I have a custom STM32F4 MCU board. I need to receive different types of sequences from Master board in a RS485 n/w. Lengths of data to be received is variable say 10 bytes, 25 bytes and so on. I have to handle every sequence and respond accordingly.
How to properly make use of HAL functions HAL_UART_Receive_IT and HAL_UART_RxCpltCallback to receive variable data properly?
I see that 3rd argument of HAL_UART_Receive_IT is looking for number of bytes to be fixed like shown:
HAL_UART_Receive_IT(&huart1, &uart1_rx_byte, no_of_bytes);
Please suggest a good implementation...
Receiving frame format:
| Start byte | Slave Addr | Byte count | Func. ID | Data1 | Data2 |...|Data n| Checksum byte 1 | Checksum byte 2 |
Where Byte count = no. of bytes from Func. ID to Checksum byte 2
If your communications speed is slow relative to the MCU clock speeds AND your MCU has nothing better to do, you could do 2-part reception as suggested by @codo in comments (first 3 bytes to get packet length, then receive n bytes from packet header). This will fall apart pretty quickly, if you are looking for higher speeds on a busy system. Another caveat could be bitflips in packet length byte corrupting your message.
Your insistence on sticking to IT and avoiding DMA seems a bit strange, since it literally makes your MCU twitch between the UART peripheral and whatever else it's doing (don't be fooled by the "receive n bytes" - it still generates IRQ on each byte, since peripheral has single data register, just that IRQ processing and memory pointer advancement is hidden by HAL). Receiving with DMA triggers IRQ only once the whole packet has arrived. Setting up DMA with maximum packet size limit and UART_IDLE or timer-based idle detection (if your command source does not provide nicely timed bytes) allows you to process the whole packet once it has arrived.
I'm using UART_IDLE IRQ with DMA at 8Mbaud on 180MHz with FreeRTOS and bunch of other timing-sensitive things happening. At 8Mbaud you only have some 200 cycles per byte to process the message, so IT-driven approach doesn't work that well (context-switching, HAL overhead, etc). I also have packeted structure, similar to yours. Each packet gets verified against length and CRC. Sadly, UART_IDLE IRQ handling is one of the things not implemented in ST HAL, so you have to implement it yourself.