Sterling
Sterling
DIIDevHeads IoT Integration Server
Created by Sterling on 7/9/2024 in #middleware-and-os
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
7 replies