UART async UART_RX_RDY timeout

Hello,

I'm currently working on a project where I use the UART in async mode.

I'm giving a timeout parameter to the uart_rx_enable() function in order to treat the UART_RX_RDY event as an End Of Frame event.

The problem is that when the buffer is full the UART_RX_RDY event is also generated before switching to the next buffer without taking into account the timeout value.

Is there a way to know if the event UART_RX_RDY has been generated specifically because of a timeout and not because of a buffer full/switch event ?

Regards

Parents Reply Children
  • Hi and thanks for your answer,

    I am sorry I did not have the time to test it (I will test asap) but it looks really close to what I tested on my side so I do not think it will help me with my problem.

    I will try to explain my problem using your example :

    The problem I encounter is when I receive a message on the UART that does not fit in the curent buffer.

    For instance, if he buffer size is 16, the offset is 14 and I receive a 4 bytes message, the data will be split between the current and the next buffer.
    The problem is that is will lead to multiple events :

    - an UART_RX_RDY event for the first 2 bytes when the buffer is full
    - a UART_RX_BUF_REQUEST and a UART_RX_BUF_RELEASED events
    - an other UART_RX_RDY for the last 2 bytes

    Because I interpret an UART_RX_RDY event like an End Of Frame, this is a problem because this will result into 2 messages being sent to the message queue, leading to two incomplete messages.


    I hope my explanation is clear enough.

    Regards
    Alexandre

  • Hi Alexandre

    Sigurd is currently on vacation and I will help you out in the mean time. 

    I would strongly recommend against trying to use the UART_RX_RDY event to signal EOF. The behavior of this event is not reliable enough to serve this purpose. 

    Instead I would recommend using some kind of packetization protocol to add SOF/EOF markers to your UART messages so that you can detect EOF whether or not the callbacks are split, and independent of buffer size, RX timeout and other implementation specifics. 

    Best regards
    Torbjørn

  • Hi

    Out of curiosity, what makes the behavior of this event not reliable ?

    I still think that this is sad to not be able to access the timeout status via a timeout flag in the uart_event_rx structure. (maybe I should open an issue on the Zephyr repo ?).

    I would have preferred to use the timeout event to avoid having to parse the buffer searching for a valid frame but I think i do not have the choice Disappointed

    Thanks for your answers.

    Best regards
    Alexandre

  • Hi Alexandre

    Zoptune said:
    Out of curiosity, what makes the behavior of this event not reliable ?

    Maybe my wording was a bit imprecise. The event will reliably signal that data is received, but because of the asynchronous nature of UART communication, and the way the UARTE peripherals handle the RX buffers, I don't think it can be used to reliably detect EOF. 

    Possibly you can make it work if you handle the issue of your package being split into two updates: Whenever you receive an update with a length shorter than the expected length you can assume that a new update will come later, and wait for the second interrupt before you process the packet. 

    Zoptune said:
    I still think that this is sad to not be able to access the timeout status via a timeout flag in the uart_event_rx structure.

    If I understand you correctly you would want to be able to verify whether or not the RX_RDY event in question was caused by a full buffer or a timeout? 

    Best regards
    Torbjørn

  • Hi  

    Ok thanks for your clarification, I understand now.

    Whenever you receive an update with a length shorter than the expected length you can assume that a new update will come later, and wait for the second interrupt before you process the packet. 

    It is not possible in my case because the frames can have variable length (SoF marker + TLV format + CRC).

    If I understand you correctly you would want to be able to verify whether or not the RX_RDY event in question was caused by a full buffer or a timeout?

    Yes, I think it would be interesting to have access to a flag that specify the source of the RX_RDY event.

    I implemented a piece of code that search for a valid frame on every RX_RDY event.
    Thanks.

    Best regards
    Alexandre

Related