cfreertos

FreeRTOS Context switching after ISR unblocks a tasks


I have read the official FreeRTOS Reference manual but could not find a specific answer to my question.

Will context switch happen if ISR unblocks a FreeRTOS task that is the same priority as the task that was paused due to ISR?

The keyword here is same priority. I know that the context switch will happen if the priority of unblocked task is higher.

Imagine a following scenario where all 3 tasks are the same priority.

#define configUSE_TIME_SLICING 0

void vTaskA(void *pv) {
    for (;;) {
        SEGGER_RTT_WriteString(0, "A running\n");
        vTaskDelay(pdMS_TO_TICKS(5));
    }
}

void vTaskB(void *pv) {
    for (;;) {
        SEGGER_RTT_WriteString(0, "B running\n");
        vTaskDelay(pdMS_TO_TICKS(5));
    }
}
void vTaskC(void *pv) {
    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
    SEGGER_RTT_WriteString(0, "B woke up\n");
    for (;;) vTaskDelay(1000);
}



void EXTI_IRQHandler(void) {
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    vTaskNotifyGiveFromISR(TaskCHandle, &xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

As you can see above, I have 3 FreeRTOS tasks running (A,B) are constantly being triggered one after another without interrupting each other (time slicing is turned off).

Question

Lets say in the middle of task A, ISR happens and it puts the TaskC into ready state due to vTaskNotifyGiveFromISR. Will the scheduler resume the taskA as it was not completed fully due to ISR, or context switch will happen after ISR unblocks the taskC and the taskC will automatically start without taskA completing?


Solution

  • In your code it will return execution to the interrupted task.

    You can force different behaviour if you change BaseType_t xHigherPriorityTaskWoken = pdTRUE; which will enforce task switch