1 任务的删除
1.1 任务删除问题
删除任务需要做如下两项工作:
- 将任务从所在队列中删除。

- 释放关闭占用的资源。
1.2 安全删除原理
安全删除方式一:设置清理回调函数,在强制删除时调用。

安全删除方式之二:设置删除请求标志,由任务自己决定何时删除。

两种删除方式的比较:

1.3 设计实现
添加删除清理和请求删除标志位函数:

请求删除函数:

检查是否请求删除函数:

删除自己函数:

强制删除函数:

关键代码实现如下:
/**********************************************************************************************************
** Function name : tTaskSetCleanCallFunc
** Descriptions : 设置任务被删除时调用的清理函数
** parameters : task 待设置的任务
** parameters : clean 清理函数入口地址
** parameters : param 传递给清理函数的参数
** Returned value : 无
***********************************************************************************************************/
void tTaskSetCleanCallFunc (tTask * task, void (*clean)(void * param), void * param)
{
task->clean = clean;
task->cleanParam = param;
}
/**********************************************************************************************************
** Function name : tTaskForceDelete
** Descriptions : 强制删除指定的任务
** parameters : task 需要删除的任务
** Returned value : 无
***********************************************************************************************************/
void tTaskForceDelete (tTask * task)
{
// 进入临界区
uint32_t status = tTaskEnterCritical();
// 如果任务处于延时状态,则从延时队列中删除
if (task->state & TINYOS_TASK_STATE_DELAYED)
{
tTimeTaskRemove(task);
}
// 如果任务不处于挂起状态,那么就是就绪态,从就绪表中删除
else if (!(task->state & TINYOS_TASK_STATE_SUSPEND))
{
tTaskSchedRemove(task);
}
// 删除时,如果有设置清理函数,则调用清理函数
if (task->clean)
{
task->clean(task->cleanParam);
}
// 如果删除的是自己,那么需要切换至另一个任务,所以执行一次任务调度
if (currentTask == task)
{
tTaskSched();
}
// 退出临界区
tTaskExitCritical(status);
}
/**********************************************************************************************************
** Function name : tTaskRequestDelete
** Descriptions : 请求删除某个任务,由任务自己决定是否删除自己
** parameters : task 需要删除的任务
** Returned value : 无
***********************************************************************************************************/
void tTaskRequestDelete (tTask * task)
{
// 进入临界区
uint32_t status = tTaskEnterCritical();
// 设置清除删除标记
task->requestDeleteFlag = 1;
// 退出临界区
tTaskExitCritical(status);
}
/**********************************************************************************************************
** Function name : tTaskIsRequestedDelete
** Descriptions : 是否已经被请求删除自己
** parameters : 无
** Returned value : 非0表示请求删除,0表示无请求
***********************************************************************************************************/
uint8_t tTaskIsRequestedDelete (void)
{
uint8_t delete;
// 进入临界区
uint32_t status = tTaskEnterCritical();
// 获取请求删除标记
delete = currentTask->requestDeleteFlag;
// 退出临界区
tTaskExitCritical(status);
return delete;
}
/**********************************************************************************************************
** Function name : tTaskDeleteSelf
** Descriptions : 删除自己
** parameters : 无
** Returned value : 无
***********************************************************************************************************/
void tTaskDeleteSelf (void)
{
// 进入临界区
uint32_t status = tTaskEnterCritical();
// 任务在调用该函数时,必须是处于就绪状态,不可能处于延时或挂起等其它状态
// 所以,只需要从就绪队列中移除即可
tTaskSchedRemove(currentTask);
// 删除时,如果有设置清理函数,则调用清理函数
if (currentTask->clean)
{
currentTask->clean(currentTask->cleanParam);
}
// 接下来,肯定是切换到其它任务去运行
tTaskSched();
// 退出临界区
tTaskExitCritical(status);
}
参考资料:
817

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



