You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'd expect the bug would be reproducible any target that supports the serial async API with DMA, however.
Expected behavior
It should be possible to write out a serial port asynchronously without DMA.
Actual behavior
The write goes out the serial port, but we never receive a TX completion event (SERIAL_EVENT_TX_COMPLETE or anything else matching SERIAL_EVENT_TX_ALL)
If no DMA channels are available or if the DMA usage hint DMA_USAGE_NEVER is provided, the serial driver is supposed to fall back to using interrupts. However, it looks like that fallback behavior isn't working. After a quick inspection of the code, I couldn't see where the UART's interrupt is enabled: EnableIRQ is called, but K64F's UART_EnableInterrupts or the HAL's serial_irq_set appears not to be called, so the UART appears to never trigger the IRQ and we never get a TX completion event at the application level.
Steps to reproduce
I was able to reproduce the issue on K64F with the following steps. However, one should be able to reproduce the issue on any other target with DEVICE_SERIAL_ASYNCH
/* main.cpp */
#include<stdint.h>
#include<mbed.h>
#include<rtos.h>
#if !DEVICE_SERIAL_ASYNCH
#error "This test suite requires the async serial API to be supported on this target"
#endif/* This semaphore keeps track of whether or not the serial callback has * finished. This semaphore allows the main thread to wait for the serial * callback to finish. */
Semaphore serial_semaphore(0);
Timeout watchdog;
staticvoidserial_write_callback(int events)
{
serial_semaphore.release();
}
staticvoidfail() {
puts("\r\n\tSorry, we failed something.\r\n");
for(;;);
}
staticvoiddma_serial_write_async(const DMAUsage usage)
{
int result;
Serial serial(USBTX, USBRX);
event_callback_t event;
constuint8_t buffer[] = "Howdy\r\n";
event.attach(serial_write_callback);
/* Configure DMA */
result = serial.set_dma_usage_tx(usage);
if (result) {
fail();
}
result = serial.set_dma_usage_rx(usage);
if (result) {
fail();
}
serial.write(buffer, sizeof(buffer) - 1, event, SERIAL_EVENT_TX_ALL);
/* Wait for the write to finish by waiting for the serial callback to * finish. *//* NOTE: Completion event (callback) never happens, even though we expect * such an event, but the serial data does still go out the serial port. */
serial_semaphore.wait();
}
staticvoiddma_serial_write_async_without_dma(void)
{
printf("-------- %s --------", __func__);
fflush(stdout);
dma_serial_write_async(DMA_USAGE_NEVER);
puts("\r\n");
fflush(stdout);
}
staticvoidtimed_out() {
/* We've timed out. */puts("\r\n\tSorry, looks like we hung.\r\n");
}
staticvoidsetup_watchdog(void)
{
/* Set up a watchdog timer to kill things that hang. This will call our * callback in ISR mode after 2 seconds. */
watchdog.attach(timed_out, 2.0);
}
intmain(void)
{
puts("\r\nHello and welcome to serial DMA fun!\r\n");
setup_watchdog();
/* This will hang. */dma_serial_write_async_without_dma();
puts("Congratulations! You've made it through the gauntlet!\r\n");
}
The output of running the program is as follows. The "Howdy" text is what we attempted to write out the serial port with asynchronously with the DMA hint DMA_USAGE_NEVER.
Hello and welcome to serial DMA fun!
-------- dma_serial_write_async_without_dma -------Howdy
Sorry, looks like we hung.
The text was updated successfully, but these errors were encountered:
Description
Bug
Target
Observed on K64F
Should be reproducible on any other target supporting async serial and DMA
Toolchain:
GCC_ARM
Toolchain version:
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496]
mbed-cli version:
0.9.10
meed-os sha:
e7361eb with additional patch applied from NXP, "K64F: Add support for SERIAL ASYNCH API"
Use PR #3438
or use my branch at https://github.com/Patater/mbed-os/tree/k64f-serial-dma-fun)
I'd expect the bug would be reproducible any target that supports the serial async API with DMA, however.
Expected behavior
It should be possible to write out a serial port asynchronously without DMA.
Actual behavior
The write goes out the serial port, but we never receive a TX completion event (
SERIAL_EVENT_TX_COMPLETE
or anything else matchingSERIAL_EVENT_TX_ALL
)If no DMA channels are available or if the DMA usage hint
DMA_USAGE_NEVER
is provided, the serial driver is supposed to fall back to using interrupts. However, it looks like that fallback behavior isn't working. After a quick inspection of the code, I couldn't see where the UART's interrupt is enabled: EnableIRQ is called, but K64F'sUART_EnableInterrupts
or the HAL'sserial_irq_set
appears not to be called, so the UART appears to never trigger the IRQ and we never get a TX completion event at the application level.Steps to reproduce
I was able to reproduce the issue on K64F with the following steps. However, one should be able to reproduce the issue on any other target with
DEVICE_SERIAL_ASYNCH
mbed new serial_dma_fun
)mbed compile -m K64F -t GCC_ARM
)The output of running the program is as follows. The "Howdy" text is what we attempted to write out the serial port with asynchronously with the DMA hint DMA_USAGE_NEVER.
The text was updated successfully, but these errors were encountered: