freertos-task-调度器的启用和关闭-示例
task.c 中,关于调度器的 启用和关闭
1 uxSchedulerSuspended
定义:
PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t ) pdFALSE;
/* Context switches are held pending while the scheduler is suspended. Also,
interrupts must not manipulate the xStateListItem of a TCB, or any of the
lists the xStateListItem can be referenced from, if the scheduler is suspended.
If an interrupt needs to unblock a task while the scheduler is suspended then it
moves the task's event list item into the xPendingReadyList, ready for the
kernel to move the task from the pending ready list into the real ready list
when the scheduler is unsuspended. The pending ready list itself can only be
accessed from a critical section. */
作用:
标识、调度器是否处在 挂起状态。
进程 切换 挂起 调度器挂起的时候。
调度器挂起的时候,中断不能操作 TCB 中的 xStateListItem 和任何引用 xStateListItem 的 链表。
那么,当调度器suspend的时候,中断例程中 需要unblock 一个task,它怎么做呢?它move task的event list item 到xPendingReadyList 中,准备好让kernel在调度器 unsuspend时。把task 从pending ready list 移动到 real ready list。
pending ready list 只能在 critical section 中访问
2 vTaskSuspendAll - 挂起调度器(关闭调度器)
挂起调度器
void vTaskSuspendAll( void )
++uxSchedulerSuspended;
3 xTaskResumeAll-恢复调度器(启用调度器)
BaseType_t xTaskResumeAll( void )
/* If uxSchedulerSuspended is zero then this function does not match a
previous call to vTaskSuspendAll(). */
configASSERT( uxSchedulerSuspended );
taskENTER_CRITICAL();
{
--uxSchedulerSuspended;
}
taskEXIT_CRITICAL();
4 使用示例
https://www.wenjiangs.com/doc/d7cgu5an
void vTaskSuspendAll( void );
挂起所有活动的实时内核,同时允许中断(包括内核滴答)。
任务在调用vTaskSuspendAll ()后,这个任务将继续执行,不会有任何被切换的危险,直到调用xTaskResumeAll ()函数。
API中有可能影响影响上下文切换的函数(例如,vTaskDelayUntil(), xQueueSend()等等),一定不能再调度器挂起时被调用。
使用范例:
void vTask1( void * pvParameters ) { for( ;; ) { // 任务执行到这里
// 有时 任务想执行长时间的操作,这期间,不想被切换 // 不能使用taskENTER_CRITICAL ()/taskEXIT_CRITI // 因为操作的执行时间的长度,可能将错过中断——包括系统滴答
// 关闭 内核切换任务
vTaskSuspendAll ();
// 这里执行一些操作。不需要使用循环 // 因为,已经占有了整个微处理器的执行时间 // 在这期间,中断仍将起作用 // 同时,内核滴答计数仍将维持
// ...
// 重启内核调度器 xTaskResumeAll (); } }