背景
#include "FreeRTOS.h"
#include "task.h"
TaskHandle_t s_task_handle = NULL;
void vTaskFunction(void *pvParameters) {
for (;;) {
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
}
}
void vISRHandler(void) {
BaseType_t mustYield = pdFALSE;
vTaskNotifyGiveFromISR(s_task_handle, &mustYield);
portYIELD_FROM_ISR(mustYield);
}
int main(void) {
xTaskCreate(vTaskFunction, "Task", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, &s_task_handle);
vTaskStartScheduler();
for (;;);
}
解释
- 其中,vTaskNotifyGiveFromISR 是 FreeRTOS 提供的一个函数,用于在中断服务例程(ISR)中通知一个任务。在 FreeRTOS 中,任务之间的同步和通信可以通过各种机制实现,其中包括通知(Notification)。
vTaskNotifyGiveFromISR(s_task_handle, &mustYield);
- 这个函数调用有两个参数:
1.s_task_handle: 要通知的任务的句柄。
2.&mustYield: 指向一个布尔变量的指针,用于指示被通知的任务是否高于当前的任务,如果比当前任务高,那么退出中断后就需要立即进行任务切换以保证实时性。如果当前任务比被通知的任务优先级高,则不需要进行任务切换。
- 然后:portYIELD_FROM_ISR是发起中断切换请求的。
portYIELD_FROM_ISR(mustYield);
意义
- 这里我们讲了FreeRTOS中任务通知vTaskNotifyGiveFromISR的用法。
- 由于FreeRTOS是高实时性的系统,因此我们可以看到,在中断退出时,为了保证被通知的任务及时运行,因此需要检查是否需要立即进行任务切换。如果被通知的任务没有更高的优先级,那么在退出中断后不会立即进行任务切换。FreeRTOS 设计的一个关键点就是只在有必要的时候进行任务切换,以保持系统的效率和响应性。
- portYIELD_FROM_ISR的作用是从ISR中请求一次上下文切换。具体来说,如果中断服务例程导致了一个高优先级任务变得可运行,这个宏可以确保在中断退出时,立刻切换到那个任务,而不是继续运行当前的任务。