Using an STM32F767ZI microcontroller with FreeRTOS

I'm using an STM32F767ZI microcontroller with FreeRTOS. I have two tasks: one receives TCP data triggered by an interrupt every 100ms, and the other handles user requests. When task-2 calls NVIC_SystemReset, the system hangs, typically in vPortRaiseBASEPRI after vTaskNotifyFromISR used by task-1. The error message indicates a hang in vPortRaiseBASEPRI, causing the system to become unresponsive. Replacing the task notification with a flag in the interrupt allows the reset but is inefficient. Disabling interrupts with portDISABLE_INTERRUPTS, suspending tasks with vTaskSuspendAll, and entering a critical section with taskENTER_CRITICAL didn't help. A workaround of disabling interrupts before reset works but is unsafe. How can I reliably perform a software reset without these issues? Here's my code guys:
// Task 1: Receives data via TCP every 100ms
void Task1(void *pvParameters) {
for (;;) {
// Wait for notification from ISR
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
// Process TCP data
}
}

// Task 2: Handles user requests and may request a system reset
void Task2(void *pvParameters) {
for (;;) {
// Handle user requests
if (userRequestsReset) {
// Attempt system reset
NVIC_SystemReset();
}
}
}

// ISR: Sends task notification every 100ms
void ISR_Handler(void) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(Task1Handle, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

void main(void) {
// Create tasks
xTaskCreate(Task1, "Task 1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, &Task1Handle);
xTaskCreate(Task2, "Task 2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);

// Start scheduler
vTaskStartScheduler();

// Should never reach here
for (;;) {}
}
// Task 1: Receives data via TCP every 100ms
void Task1(void *pvParameters) {
for (;;) {
// Wait for notification from ISR
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
// Process TCP data
}
}

// Task 2: Handles user requests and may request a system reset
void Task2(void *pvParameters) {
for (;;) {
// Handle user requests
if (userRequestsReset) {
// Attempt system reset
NVIC_SystemReset();
}
}
}

// ISR: Sends task notification every 100ms
void ISR_Handler(void) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(Task1Handle, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

void main(void) {
// Create tasks
xTaskCreate(Task1, "Task 1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, &Task1Handle);
xTaskCreate(Task2, "Task 2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);

// Start scheduler
vTaskStartScheduler();

// Should never reach here
for (;;) {}
}
How can I modify this to ensure a reliable software reset? @Middleware & OS
Solution:
Well, I believe you can start by modifying the system reset procedure in task-2 to ensure a safe and reliable reset. Before calling NVIC_SystemReset, disable all interrupts to prevent any pending ISR from causing the system to hang. ```c...
Jump to solution
5 Replies
ZacckOsiemo
ZacckOsiemo4mo ago
Do you have to use NVICSystemReset? I am asking because the stm32 has inbuilt reset functionality in SCB-AIRCR register. And maybe that can avoid the pitfalls you are encountering.
Sterling
Sterling4mo ago
I would look into that 🙏
Solution
UC GEE
UC GEE4mo ago
Well, I believe you can start by modifying the system reset procedure in task-2 to ensure a safe and reliable reset. Before calling NVIC_SystemReset, disable all interrupts to prevent any pending ISR from causing the system to hang.
// Task 2: Handles user requests and may request a system reset
void Task2(void *pvParameters) {
for (;;) {
// Handle user requests
if (userRequestsReset) {
// Disable interrupts to ensure no ISRs are pending
taskENTER_CRITICAL();
// Attempt system reset
NVIC_SystemReset();
// Enable interrupts again (though this will not be reached if the system resets)
taskEXIT_CRITICAL();
}
}
}
// Task 2: Handles user requests and may request a system reset
void Task2(void *pvParameters) {
for (;;) {
// Handle user requests
if (userRequestsReset) {
// Disable interrupts to ensure no ISRs are pending
taskENTER_CRITICAL();
// Attempt system reset
NVIC_SystemReset();
// Enable interrupts again (though this will not be reached if the system resets)
taskEXIT_CRITICAL();
}
}
}
Check out this @Sterling it will help you to achieve a reliable software reset.
Sterling
Sterling4mo ago
Okayy @UC GEE , will do
Dtynin
Dtynin4mo ago
@Sterling Actually, when you ensure that interrupts are disabled before the system resets, you prevent any ongoing or pending ISRs from interfering with the reset process. This approach helps avoid the issue of the system hanging in
vPortRaiseBASEPRI
vPortRaiseBASEPRI
.
Want results from more Discord servers?
Add your server