Modifying FreeRTOS Interrupt Priorities After Scheduler Initialization
Hey everyone @Middleware & OS , I'm neck-deep in an RTOS project using FreeRTOS. I need to read and potentially modify interrupt priorities after the FreeRTOS scheduler has been kicked off with
vTaskStartScheduler()
. The issue is, NVIC_GetPriority(DMA1_Channel4_IRQn)
seems to behave differently depending on when I call it.
- Before calling vTaskStartScheduler()
, NVIC_GetPriority(DMA1_Channel4_IRQn)
works as expected and reflects the configured priority (11).
- However, after the scheduler starts, the function consistently returns 11, regardless of any changes I try to make within the vTest_NVIC
task.
I've tried using taskENTER_CRITICAL()
and taskEXIT_CRITICAL()
to ensure thread safety, but it doesn't seem to resolve the issue.
What am I missing here? Why does the behavior differ before and after the scheduler starts?3 Replies
@Marvee Amasi It seems like you might be encountering a couple of potential issues with how the NVIC priorities are being handled after the FreeRTOS scheduler starts. Here are a few things to consider:
Priority Grouping - Ensure that the priority grouping configuration is consistent throughout your application. FreeRTOS typically sets its own priority grouping based on
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
defined in FreeRTOSConfig.h
. Verify that your NVIC priority grouping set by HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)
aligns with this configuration.
Interrupt Priorities and FreeRTOS - FreeRTOS uses interrupt priorities to manage its critical sections and task switching. Interrupts used within FreeRTOS (or any interrupts calling FreeRTOS APIs) should have priorities lower (numerically higher) than configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
. Ensure that the priority (11 in your case) falls within the acceptable range set by FreeRTOS.
Task and Interrupt Context - When you call NVIC_GetPriority(DMA1_Channel4_IRQn)
within the task, ensure that the DMA1_Channel4 interrupt is enabled and configured properly. Additionally, check if there are any other parts of your code or other tasks that might be modifying the NVIC priorities or reconfiguring the interrupt.
Critical Sections - While using taskENTER_CRITICAL()
and taskEXIT_CRITICAL()
ensures thread safety, it doesn't necessarily guarantee that the priority of an interrupt won't be modified outside these critical sections by other parts of your application or by the hardware.To debug this issue further, you can add more logging before and after setting the priority within your task to confirm if the priority is being changed as expected. Here’s an updated version of your code snippet with additional logging:
#include <FreeRTOS.h>
#include <queue.h>
#include <task.h>
#include "stm32f4xx_hal.h"
static void vTest_NVIC(void *pvParameters) {
tprintf("\r\nTask Started...");
while (1) {
taskENTER_CRITICAL();
uint32_t priority = NVIC_GetPriority(DMA1_Channel4_IRQn);
tprintf("\r\nCurrent priority: %d", (int)priority);
// Modify the priority to test if changes take effect
NVIC_SetPriority(DMA1_Channel4_IRQn, 5);
priority = NVIC_GetPriority(DMA1_Channel4_IRQn);
tprintf("\r\nModified priority: %d", (int)priority);
taskEXIT_CRITICAL();
vTaskDelay(pdMS_TO_TICKS(3000));
}
}
int main(void) {
HAL_Init(); // Ensure the HAL is initialized
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 11, 0);
tprintf("\r\nInitial priority: %d", (int)NVIC_GetPriority(DMA1_Channel4_IRQn));
// Create a task
xTaskCreate(vTest_NVIC, "Test_NVIC", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
// Start the scheduler
vTaskStartScheduler();
// Infinite loop while (1) { } } This code ensures the initial priority is logged, then the priority is modified within the task, and the modified priority is logged again. This should help you identify if the priority changes are being applied correctly after the scheduler starts.
// Infinite loop while (1) { } } This code ensures the initial priority is logged, then the priority is modified within the task, and the modified priority is logged again. This should help you identify if the priority changes are being applied correctly after the scheduler starts.
The DMA1_Channel4 interrupt priority (11) is indeed lower than the configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY (5), so it seems to be within the acceptable range for FreeRTOS interaction.