cancel
Showing results for 
Search instead for 
Did you mean: 

STM32N6 with ThreadX. What is the most efficient way to process UART Rx?

Roshko
Associate II

Hello,
I hope someone with more experience with the STM32N6 and ThreadX can help me get an efficient solution.
I'm using STM32N6 to communicate with multiple peripheral devices via UART. The protocol they are using to send data however, does not allow me to know what the message is in advance, or how many bytes the received packet would be. I only know the packet ends with 0x0D 0x0A. 
Other MCUs I've used in the past have some built in Pattern matching in the DMA so the DMA interrupts when a combination of symbols is received (0x0D 0x0A). However I don't see something like that in the STM32N6 HAL. I did a driver using the simple HAL_UART_Receive_IT(huart, &UART2_rxByte, 1); and interrupt on every byte to check if a packet is received, but It is really painful to know CPU time is wasted on entering interrupts when I need it for processing data. Maybe ThreadX can be more efficient with some polling thread? Or I missed some configuration option? What would you suggest?

4 REPLIES 4
Andrew Neil
Super User

@Roshko wrote:

 interrupt on every byte to check if a packet is received, but It is really painful to know CPU time is wasted on entering interrupts 


So don't do the checking in the ISR.

Just have the ISR write to a circular buffer.

Parse the buffer elsewhere ...

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

That doesn't solve my issue of processing time wasted for entering the ISR on every byte. Can I have the DMA do it? Is there a HAL function to get the new buffer entries? Or at least a pointer to the last entry? 

The amount of time to simply get the received character and put it into the ring buffer is minimal.

Doesn't the N6 have FIFOs in its UARTs?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Hi Andrew,
Unless I'm getting something really wrong about how the HAL works (Which is completely possible - I'm a noob with STM32):
My guess is that 60-80 instructions are executed to enter an ISR and call HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart). - Processing Time wasted
1 instruction is executed to copy the received character and put it into the ring buffer - you are right that is minimal
60-80 instructions are wasted again to return from HAL_UART_RxCpltCallback and exit the ISR - Processing time wasted.

I don't see any way to utilize the Rx FIFO without knowing the message length in advance or writing my own HAL

I checked stm32n6xx_hal_uart_ex.c and I think I might be able to use:
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
And 
HAL_UARTEx_RxEventCallback
to check for HAL_UART_RXEVENT_IDLE and process the data there as in:
https://stackoverflow.com/questions/79684056/how-to-use-hal-uartex-receivetoidle-dma-stm32

I would be happy to know if you have some other recommendations in the mean time.