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.
#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_GetPendingIRQ(DMA1_Channel4_IRQn) ?
NVIC_GetPriority(DMA1_Channel4_IRQn) : portMAX_DELAY;
tprintf("\r\nCurrent priority (if pending): %d", (int)priority);
taskEXIT_CRITICAL();
vTaskDelay(pdMS_TO_ICKS(3000));
}
}

int main(void) {
portBASE_TYPE xReturn;
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 11, 0);
tprintf("\r\nInitial priority: %d", (int)NVIC_GetPendingIRQ(DMA1_Channel4_IRQn) ?
NVIC_GetPriority(DMA1_Channel4_IRQn) : portMAX_DELAY);
vTaskStartScheduler();
}
#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_GetPendingIRQ(DMA1_Channel4_IRQn) ?
NVIC_GetPriority(DMA1_Channel4_IRQn) : portMAX_DELAY;
tprintf("\r\nCurrent priority (if pending): %d", (int)priority);
taskEXIT_CRITICAL();
vTaskDelay(pdMS_TO_ICKS(3000));
}
}

int main(void) {
portBASE_TYPE xReturn;
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 11, 0);
tprintf("\r\nInitial priority: %d", (int)NVIC_GetPendingIRQ(DMA1_Channel4_IRQn) ?
NVIC_GetPriority(DMA1_Channel4_IRQn) : portMAX_DELAY);
vTaskStartScheduler();
}
- 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
Dtynin
Dtynin5mo ago
@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.
Enthernet Code
Enthernet Code5mo ago
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.
Marvee Amasi
Marvee Amasi5mo ago
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.
Want results from more Discord servers?
Add your server