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 (;;) {}
}


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.



// 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.
Was this page helpful?