Skip to main content
ATzou.1
Associate II
August 20, 2021
Question

Need to change interrupt priority for USART DMA RX Circular

  • August 20, 2021
  • 7 replies
  • 4948 views

I've got some code working from an example for USART RX DMA Circular. I'm to the point where I can receive the UART data but I need to now use a write to a protected (by a binary semaphore) circular buffer from the interrupt context HAL_UARTEx_RxEventCallback() which can be called from interrupt context DMA TC and HT events and UART IDLE line event.

Using FreeRTOS and configured is #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 in FreeRTOSConfig.h.

When using xSemaphoreTakeFromISR and xSemaphoreGiveFromISR with a binary semaphore configured I get the following assert:

configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );

Using  NVIC_SetPriority(DMA1_Channel5_IRQn, 6); so I figure that should do the trick but it's not working. When I capture the values of ucMaxSysCallPriority and ucCurrentPriority, I get values of 80 and 48 respectively. I can understand that the values are lost in translation with the NVIC groups, preemption priority and subpriority. However I did expect the NVIC_SetPriority() call above to work.

If I disable the semaphores, I can get the USART RX data into my circular buffer. I believe that I just need to get past configuration of the interrupt at a lower priority than the configMAX_SYSCALL_INTERRUPT_PRIORITY. Looking at the Groups, preemption priorities, and sub-priorities doesn't make a lot of sense to me.

Please advise.

This topic has been closed for replies.

7 replies

Pavel A.
August 21, 2021

Instead of NVIC_SetPriority use HAL_NVIC_SetPriority.

However, acquiring a semaphore from ISR does not look like a good idea.

What will you do if xSemaphoreTakeFromISR fails?

ATzou.1
ATzou.1Author
Associate II
August 21, 2021

Get the data next time around.

Its' common to receive data in an interrupt and put it into a ring buffer within the interrupt context ... and then in a task extract data from the circular buffer and process the data. The buffer resource must be protect with a mutex (binary semaphore).

How would you propose that I get data from interrupt context available for a task to process ? I'm open to another idea.

ATzou.1
ATzou.1Author
Associate II
August 21, 2021

Another point is that it already fails and asserts. The semaphore take and get from ISRs should do the trick. My protection just needs to be to the extent of writing and reading from the circular buffer with updating the state of the circular buffer. Is relatively an in and out job.

Pavel A.
August 21, 2021

Have you noticed a subtle difference between xSemaphoreTake vs xSemaphoreTakeFromISR?

The former waits until resource becomes available. The latter fails immediately if the resource is not available.

So the question is, what if you cannot acquire the semaphore? If you have the circular buffer - why do you need the semaphore?

ATzou.1
ATzou.1Author
Associate II
August 21, 2021

This thread is getting off topic. I posted here so I can get some help on properly setting the interrupt priority. As far as I'm concerned, I have already answered your question above.

Pavel A.
August 21, 2021

Your primary question is answered. Use HAL_NVIC_SetPriority.

ATzou.1
ATzou.1Author
Associate II
August 21, 2021

Let me be explicit with my questions ...

Using FreeRTOS and configured is #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 in FreeRTOSConfig.h.

My goal is to set the priority of my DMA interrupt at a lower priority than the configMAX_SYSCALL_INTERRUPT_PRIORITY.

When using HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, x, y);

How do I properly set values of x and y which are preemption priority and sub priority to accomplish my goal?

How do I know what NVIC group is set for this HAL call since the group is not set explicitly in the HAL call?

Pavel A.
August 22, 2021

HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 6, 0)

Explanation:

NVIC in STM32's implements 4 bits of priority. This info can be found in reference manuals for each STM32.

The default grouping for STM32s is 4 and there is no good reason to change it.

This gives all 4 bits (values 0-15) for preemption priority and 0 bits for sub-priority.

How do you know which NVIC grouping is set? You inspect the source of HAL_Init.

HAL_NVIC_SetPriority is a proprietary ST function (not CMSIS) but source is available.

Good luck,

--pa

ATzou.1
ATzou.1Author
Associate II
August 22, 2021

I believe that I have already tried that before I made this post. Tried it again (to make 100% sure) and got the same results as the top post with 80 and 48 decimal for cMaxSysCallPriority and ucCurrentPriority (lower number is higher priority). Doesn't make a lot of sense that the priority appears to still be higher in vPortValidateInterruptPriority() in port.c .

I'll need more than luck to resolve this issue with RX DMA. Planning on switching the implementation to interrupts from dma.

Thanks for trying to help.

ATzou.1
ATzou.1Author
Associate II
August 24, 2021

Getting there. Changed all of the dma interrupts to priority 6,0 and now not getting the assert. Changed the attempt to use the semphoreFromISR to using a queue and now I'm passing the data from the interrupt to the task and input the stream into a circular buffer. As you recommended with the 'why' question ... I now see why as the sempaphoreTake from ISR never was successful. Thanks for the help on this Pavel.

Pavel A.
August 25, 2021

You're welcome!