FreeRTOS源码解读task.c

1 阅读2分钟

TCB核心字段:

 `pxTopOfStack`:当前任务上下文栈顶
 `xStateListItem`:任务状态链表节点
 `xEventListItem`:事件等待链表节点
 `uxPriority` / `uxBasePriority`:优先级
 `xCoreID`:SMP 下的核心亲和性
 `pxStack``pcTaskName`

全局状态:

`pxCurrentTCBs[]`:每个核当前运行的任务
`pxReadyTasksLists[]`:按优先级分桶的就绪列表
`xDelayedTaskList1` / `xDelayedTaskList2`:延时列表双缓冲
`pxDelayedTaskList` / `pxOverflowDelayedTaskList`:当前延时表指针
`xPendingReadyList[]`:调度器挂起时先搁置的任务
`xSuspendedTaskList`:挂起任务列表
`xTickCount` / `xNextTaskUnblockTime` / `xSchedulerRunning`:调度时间基准和状态标志
`xKernelLock`(SMP 内核自旋锁)

关键函数体

prvInitialiseTaskLists 初始化 ready/delayed/suspended/pending 等所有链表。
prvInitialiseNewTask 初始化 TCB、任务名、优先级、两个 list item、初始栈帧(通过端口层)。
prvAddNewTaskToReadyList 把新任务放入 ready 队列,必要时触发调度。
vTaskStartScheduler 创建 idle/timer 任务,设置调度器状态,调用端口层启动调度。
vTaskSwitchContext 上下文切换前后的内核侧工作,选择下一任务,处理统计/TLS/errno 等。
xTaskIncrementTick tick 驱动函数,递增 tick,处理延时到期任务,决定是否请求切换。
prvAddCurrentTaskToDelayedList 当前任务从 ready 移出,按唤醒时间插入 delayed 列表。
vTaskPlaceOnEventList 把 `xEventListItem` 放到对象事件链表,同时进入 delayed 以支持超时。
xTaskRemoveFromEventList 事件到达时,把等待任务从 event/delayed 移回 ready,按优先级决定是否抢占。

注意事项:

  • 在进入app_main之前就已经运行vTaskStartScheduler创建了idle等任务。app_main本质上也是一个任务。
  • TCB中最重要的是pxTopOfStack,这是上下文切换的关键。因为任务切换时候,寄存器、PC等会进行压栈操作,栈顶指针是恢复现场的关键。
  • TCB中有两个节点——状态节点+事件节点,典型例子:带有超时等待的事件唤醒。
  • 全局变量有几个关键的,其中pxCurrentTCBs[]是每个当前核运行的任务;pxReadyTasksLists[]是按照优先级分桶的就绪链表;xDelayedTaskList1、xDelayedTaskList2是延时链表双缓冲;xPendingReadyList[]是调度器挂起时先搁置的任务;xSuspendedTaskList是挂起任务列表;
  • xTickCount是调度的事件基准,当systemtick触发中断服务函数时候,会调用xTaskIncrementTick驱动tick更新,同时处理延时链表或时间片轮转。事件链表则由事件到达触发,执行xTaskRemoveFromEventList。