cancel
Showing results for 
Search instead for 
Did you mean: 

Need to change interrupt priority for USART DMA RX Circular

ATzou.1
Associate II

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.

11 REPLIES 11
Pavel A.
Evangelist III

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
Associate II

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
Associate II

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.

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
Associate II

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.

Your primary question is answered. Use HAL_NVIC_SetPriority.

ATzou.1
Associate II

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?

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
Associate II

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.