This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

CMSIS Driver - USART issue

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 

Parents
  • Hi David,

    Many thanks for your reply! That did indeed solve it!

    Am I correct in thinking that the difference between ARM_USART_EVENT_TX_COMPLETE and ARM_USART_EVENT_SEND_COMPLETE is that ARM_USART_EVENT_SEND_COMPLETE returns even when there might be data in the USART buffer still to send, whereas ARM_USART_EVENT_TX_COMPLETE is when the transmission is completely done (i.e. no data in the transmit buffers)?

    Thanks for your help!

    Regards,

    Alex

Reply
  • Hi David,

    Many thanks for your reply! That did indeed solve it!

    Am I correct in thinking that the difference between ARM_USART_EVENT_TX_COMPLETE and ARM_USART_EVENT_SEND_COMPLETE is that ARM_USART_EVENT_SEND_COMPLETE returns even when there might be data in the USART buffer still to send, whereas ARM_USART_EVENT_TX_COMPLETE is when the transmission is completely done (i.e. no data in the transmit buffers)?

    Thanks for your help!

    Regards,

    Alex

Children
  • 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#gad796cd023f8f6300a6caadcc39d43cbf

    Regards,
    David