2020-02-04 10:34 PM
Hello all,
I am using NUCLEO-F446RE board.
I am looking for some way to find how many bytes of data is received over UART which we want to read using HAL_UART_Read API.
Normally, we will know what is the incoming data. So, depending on that we Read those many bytes of data.
But in a special scenario, I don't how many bytes of data is coming. Once data is received I need to validate it. For this, I need a way to find how many bytes are coming over UART?
Please help me out.
2020-02-04 10:45 PM
Receive/check bytes one by one.
JW
2020-02-04 11:01 PM
Exactly.
> Normally, we will know what is the incoming data.
No, you don't.
Characters get lost or get corrupted, you can even get false receptions.
You only know how much characters you expect.
> But in a special scenario, I don't how many bytes of data is coming. Once data is received I need to validate it.
Use a protocol with designated start or end character, or better both.
Synchronize your reception on those characters.
Always assume that start/end character can get lost or corrupted as well.
Validate once you successfully received a package.
2020-02-05 12:49 AM
Yes True.
I can read/check byte by bytes on each interrupt. And I can just save those bytes to some array. But on what condition again, I need to reset the index of array? so that I can save the next set of data/bytes starting from 0th index? Because I don't have fixed last byte?
suppose, I want to send 0x53 0x54 0x55 ==>array should be Arr[]={0x53, 0x54, 0x55} and again 0x73 0x74 0x75 ==> array should be Arr[]={0x73, 0x74, 0x75}
2020-02-05 01:02 AM
> But on what condition again, I need to reset the index of array? so that I can save the next set of data/bytes starting from 0th index? Because I don't have fixed last byte?
That would be sub-optimal conditions.
You could either use the start character of the next package to conclude the preceding one. But that would imply follow-up packets, and lag in processing/response time.
Modbus RTU uses a time-based approach. An idle time of more then 3,5 character is interpreted as packet termination.
If the inherent error susceptibility of UART transmission is a problem, and you can't ensure robustness by protocoll, I would suggest to switch to something more safe like CAN. It has automatic error repetition, arbitration, error handling, and an inherent 16-bit CRC.
2020-02-05 01:04 AM
One (imho bad) approach: When you know a message is complete (and processed) then you reset the index. This has problems - consider what happens if you start receiving a new message before you've processed the old one?
Another approach is a circular buffer. You reset the index when you've got to the end of the buffer. Reading out is harder because you need to do a "read from here", and be aware that your reading will have to wrap back to the start sooner or later. There is hardware DMA support for this.
I tend to use circular buffers with DMA. And then copy out when I want to process the data.
Hope this helps,
Danish
2020-02-05 01:12 AM
> But in a special scenario, I don't how many bytes of data is coming.
There is a UART idle time interrupt feature. The interrupt will trigger after the serial line was idle for a certain time. This interrupt is not covered by HAL UART API, but there is a nice article about it here: https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx