We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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