前言
- 20201009
- LiteOS 2018
- 需要会通用链表
笔录草稿
源码分析
LOS_TaskDelete函数源码分析
完整源码
- 进入处理前,需要进入任务临界
- 通过任务ID来获取任务句柄
- 根据各种状态进行处理
- 处于 OS_TASK_STATUS_UNUSED (未使用) 状态
- 处于 OS_TASK_STATUS_RUNNING (运行态) 且调度被锁定了
- 处于 就绪态 或 阻塞态 或 阻塞队列态
- 处于 OS_TASK_STATUS_READY (就绪态)
- 处于 OS_TASK_STATUS_PEND(阻塞态) 或 OS_TASK_STATUS_PEND_QUEUE(阻塞队列态)
- 处于 OS_TASK_STATUS_DELAY (延时态)或 OS_TASK_STATUS_TIMEOUT(超时态)
- 被删除的任务需要做一些复位处理
- 被删除的任务s是否处于运行态
- 是
- 不能完全删除该任务,因为,调度过程中需要该任务参与
- 把当前任务插入到回收列表中,待运行创建任务函数时在进行回收处理。(其它RTOS都是在空闲任务中处理)
- 把当前任务(被删除的任务)copy到最低优先级的任务中,即是比空闲任务还低一个优先级的备用任务中,被赋给 g_stLosTask.pstRunTask,用于下main调度使用
- 解锁中断
- 调度
- 否
- 标记为未使用状态
- 直接放到空闲列表中
- 释放任务堆空间
- 初始化栈顶指针
- 解锁中断
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 uwTaskID)
{
UINTPTR uvIntSave;
LOS_TASK_CB *pstTaskCB;
UINT16 usTempStatus;
UINT32 uwErrRet = OS_ERROR;
CHECK_TASKID(uwTaskID);
uvIntSave = LOS_IntLock();
pstTaskCB = OS_TCB_FROM_TID(uwTaskID);
usTempStatus = pstTaskCB->usTaskStatus;
if (OS_TASK_STATUS_UNUSED & usTempStatus)
{
uwErrRet = LOS_ERRNO_TSK_NOT_CREATED;
OS_GOTO_ERREND();
}
if ((OS_TASK_STATUS_RUNNING & usTempStatus) && (g_usLosTaskLock != 0))
{
PRINT_INFO("In case of task lock, task deletion is not recommended\n");
g_usLosTaskLock = 0;
}
if (OS_TASK_STATUS_READY & usTempStatus)
{
osPriqueueDequeue(&pstTaskCB->stPendList);
pstTaskCB->usTaskStatus &= (~OS_TASK_STATUS_READY);
}
else if ((OS_TASK_STATUS_PEND & usTempStatus) || (OS_TASK_STATUS_PEND_QUEUE & usTempStatus))
{
LOS_ListDelete(&pstTaskCB->stPendList);
}
if ((OS_TASK_STATUS_DELAY | OS_TASK_STATUS_TIMEOUT) & usTempStatus)
{
osTimerListDelete(pstTaskCB);
}
pstTaskCB->usTaskStatus &= (~(OS_TASK_STATUS_SUSPEND));
pstTaskCB->usTaskStatus |= OS_TASK_STATUS_UNUSED;
pstTaskCB->uwEvent.uwEventID = 0xFFFFFFFF;
pstTaskCB->uwEventMask = 0;
#if (LOSCFG_BASE_CORE_CPUP == YES)
(VOID)memset((VOID *)&g_pstCpup[pstTaskCB->uwTaskID], 0, sizeof(OS_CPUP_S));
#endif
g_stLosTask.pstNewTask = LOS_DL_LIST_ENTRY(osPriqueueTop(), LOS_TASK_CB, stPendList);
if (OS_TASK_STATUS_RUNNING & pstTaskCB->usTaskStatus)
{
LOS_ListTailInsert(&g_stTskRecyleList, &pstTaskCB->stPendList);
g_stLosTask.pstRunTask = &g_pstTaskCBArray[g_uwTskMaxNum];
g_stLosTask.pstRunTask->uwTaskID = uwTaskID;
g_stLosTask.pstRunTask->usTaskStatus = pstTaskCB->usTaskStatus;
g_stLosTask.pstRunTask->uwTopOfStack = pstTaskCB->uwTopOfStack;
g_stLosTask.pstRunTask->pcTaskName = pstTaskCB->pcTaskName;
pstTaskCB->usTaskStatus = OS_TASK_STATUS_UNUSED;
(VOID)LOS_IntRestore(uvIntSave);
osSchedule();
return LOS_OK;
}
else
{
pstTaskCB->usTaskStatus = OS_TASK_STATUS_UNUSED;
LOS_ListAdd(&g_stLosFreeTask, &pstTaskCB->stPendList);
(VOID)LOS_MemFree(m_aucSysMem0, (VOID *)pstTaskCB->uwTopOfStack);
pstTaskCB->uwTopOfStack = (UINT32)NULL;
}
(VOID)LOS_IntRestore(uvIntSave);
return LOS_OK;
LOS_ERREND:
(VOID)LOS_IntRestore(uvIntSave);
return uwErrRet;
}
参考
链接
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现