1 任务的挂起与唤醒
1.1 概述
现有的任务状态切换图:

任务的挂起就是暂时禁止任务占用CPU运行,简单来说,就是无条件暂停任务运行。

新的任务状态切换图:

1.2 设计实现
添加挂起计数器:

挂起函数:

恢复函数:

实现代码如下:
/**********************************************************************************************************
** Function name : tTaskSuspend
** Descriptions : 挂起指定的任务
** parameters : task 待挂起的任务
** Returned value : 无
***********************************************************************************************************/
void tTaskSuspend (tTask * task)
{
// 进入临界区
uint32_t status = tTaskEnterCritical();
// 不允许对已经进入延时状态的任务挂起
if (!(task->state & TINYOS_TASK_STATE_DELAYED))
{
// 增加挂起计数,仅当该任务被执行第一次挂起操作时,才考虑是否
// 要执行任务切换操作
if (++task->suspendCount <= 1)
{
// 设置挂起标志
task->state |= TINYOS_TASK_STATE_SUSPEND;
// 挂起方式很简单,就是将其从就绪队列中移除,这样调度器就不会发现他
// 也就没法切换到该任务运行
tTaskSchedUnRdy(task);
// 当然,这个任务可能是自己,那么就切换到其它任务
if (task == currentTask)
{
tTaskSched();
}
}
}
// 退出临界区
tTaskExitCritical(status);
}
/**********************************************************************************************************
** Function name : tTaskWakeUp
** Descriptions : 唤醒被挂起的任务
** parameters : task 待唤醒的任务
** Returned value : 无
***********************************************************************************************************/
void tTaskWakeUp (tTask * task)
{
// 进入临界区
uint32_t status = tTaskEnterCritical();
// 检查任务是否处于挂起状态
if (task->state & TINYOS_TASK_STATE_SUSPEND)
{
// 递减挂起计数,如果为0了,则清除挂起标志,同时设置进入就绪状态
if (--task->suspendCount == 0)
{
// 清除挂起标志
task->state &= ~TINYOS_TASK_STATE_SUSPEND;
// 同时将任务放回就绪队列中
tTaskSchedRdy(task);
// 唤醒过程中,可能有更高优先级的任务就绪,执行一次任务调度
tTaskSched();
}
}
// 退出临界区
tTaskExitCritical(status);
}
参考资料:
2779

被折叠的 条评论
为什么被折叠?



