Hi all,
I am using the CMSIS Driver USART driver in Keil uVision with the STM32F746 discovery board and have a weird bug in the usart callback.
I'm kind of following the example from - https://www.keil.com/pack/doc/CMSIS/Driver/html/group__usart__interface__gr.html (but updated for cmsis_os2.h)
When I do usart_driver->Receive(&cmd, 1); and hit enter in my terminal window, it then just skips through the remaining osEventFlagsWait() commands, repeatedly printing "Hello World!" to my terminal window. However if I add a loop of spinning CPU cycles to introduce a short delay before sending the osEventFlag it behaves as expected (that is it waits on the osEventFlagsWait(usart_flag, 0x01, osFlagsWaitAny, osWaitForever); line until I hit enter again). It also works as expected if I run the code line by line in the debugger (probably because stepping through the code introduces it's own delay).
The issue is (at least I think!) with the osEventFlagsWait(usart_flag, 0x01, osFlagsWaitAny, osWaitForever);. I was expecting the event flag to clear immediately after osEventFlagsWait returns, but there seems to be a delay in clearing the flag.
This means if you do:
usart_driver->Send("some message\n", 14); osEventFlagsWait(usart_flag, 0x01, osFlagsWaitAny, osWaitForever); usart_driver->Send("some other message\n", 20); osEventFlagsWait(usart_flag, 0x01, osFlagsWaitAny, osWaitForever);
where the uart callback sets the event flag when it is triggered with ARM_USART_EVENT_SEND_COMPLETE or ARM_USART_EVENT_TX_COMPLETE - e.g.
// if our usart send / transmit was a success uint32_t send_mask = ARM_USART_EVENT_SEND_COMPLETE | ARM_USART_EVENT_TX_COMPLETE ; if(event & send_mask) { osEventFlagsSet(usart_flag, 0x01); }
it just skips through the second osEventFlagsWait (as - as far as i can see - it still thinks the flag is set).
If I stick an osDelay(25); between the two calls to usart_driver->Send() it then works.
My question now is - is this the desired behaviour? Is there a bug in osEventFlagsWait() or should I just not rely on the flags being cleared immediately after osEventFlagsWait() returns? Or am I using the event flags wrong?
Regards,
Alex
p.s. This is also cross posted to https://github.com/ARM-software/CMSIS_5/issues/1027 and I have a minimal working example at https://gist.github.com/al3xsh/3de259f2bf6802d5112fd1111a6d8ec1
Hi Alex,ARM_USART_EVENT_SEND_COMPLETE event indicates that all the tx data has been processed by the driver and the user can reuse tx buffer and call USART_Send() again. This not necessary mean that all the data is already physically transferred, It might be just queued or copied in drivers local buffer.ARM_USART_EVENT_TX_COMPLETE event is optional and it can be implemented when the usart peripheral support this functionality. It indicates that all tx data was physically transferred (gone out on pin/wire). This event is useful, for example, when disabling the USART peripheral or changing the alternate function of USART_TX pin, where waiting for ARM_USART_EVENT_TX_COMPLETE event prevents unwanted interruption of the transfer.
Please take a look here for details:https://www.keil.com/pack/doc/CMSIS/Driver/html/group__usart__interface__gr.html#gad796cd023f8f6300a6caadcc39d43cbfRegards,David