当前位置:网站首页>【Ucos-III源码分析】——任务创建
【Ucos-III源码分析】——任务创建
2022-07-16 14:05:00 【你的先生_1016】
任务创建时都干了些什么事儿
(1)、创建一些临时的变量。
(2)、判断:
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* ---------- CANNOT CREATE A TASK FROM AN ISR ---------- */
*p_err = OS_ERR_TASK_CREATE_ISR;
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u /* ---------------- VALIDATE ARGUMENTS ------------------ */
if (p_tcb == (OS_TCB *)0) { /* User must supply a valid OS_TCB */
*p_err = OS_ERR_TCB_INVALID;
return;
}
if (p_task == (OS_TASK_PTR)0) { /* User must supply a valid task */
*p_err = OS_ERR_TASK_INVALID;
return;
}
if (p_stk_base == (CPU_STK *)0) { /* User must supply a valid stack base address */
*p_err = OS_ERR_STK_INVALID;
return;
}
if (stk_size < OSCfg_StkSizeMin) { /* User must supply a valid minimum stack size */
*p_err = OS_ERR_STK_SIZE_INVALID;
return;
}
if (stk_limit >= stk_size) { /* User must supply a valid stack limit */
*p_err = OS_ERR_STK_LIMIT_INVALID;
return;
}
if (prio >= OS_CFG_PRIO_MAX) { /* Priority must be within 0 and OS_CFG_PRIO_MAX-1 */
*p_err = OS_ERR_PRIO_INVALID;
return;
}
#endif
if (prio == (OS_CFG_PRIO_MAX - 1u)) {
if (p_tcb != &OSIdleTaskTCB) {
*p_err = OS_ERR_PRIO_INVALID; /* Not allowed to use same priority as idle task */
return;
}
}这些的意思就是判断你创建的任务是否合理,包括不允许在中断程序中去创建任务、任务控制块不能为0、栈空间不能为0,栈不能小于系统确定的最小值空间 、优先级要合理这些。
(3)、初始化任务控制块的部分—调用 OS_TaskInitTCB(p_tcb);
void OS_TaskInitTCB (OS_TCB *p_tcb)
{
#if OS_CFG_TASK_REG_TBL_SIZE > 0u
OS_REG_ID id;
#endif
#if OS_CFG_TASK_PROFILE_EN > 0u
CPU_TS ts;
#endif
p_tcb->StkPtr = (CPU_STK *)0;
p_tcb->StkLimitPtr = (CPU_STK *)0;
p_tcb->ExtPtr = (void *)0;
p_tcb->NextPtr = (OS_TCB *)0;
p_tcb->PrevPtr = (OS_TCB *)0;
p_tcb->TickNextPtr = (OS_TCB *)0;
p_tcb->TickPrevPtr = (OS_TCB *)0;
p_tcb->TickSpokePtr = (OS_TICK_SPOKE *)0;
p_tcb->NamePtr = (CPU_CHAR *)((void *)"?Task");
p_tcb->StkBasePtr = (CPU_STK *)0;
p_tcb->TaskEntryAddr = (OS_TASK_PTR )0;
p_tcb->TaskEntryArg = (void *)0;
#if (OS_CFG_PEND_MULTI_EN > 0u)
p_tcb->PendDataTblPtr = (OS_PEND_DATA *)0;
p_tcb->PendDataTblEntries = (OS_OBJ_QTY )0u;
#endif
p_tcb->TS = (CPU_TS )0u;
#if (OS_MSG_EN > 0u)
p_tcb->MsgPtr = (void *)0;
p_tcb->MsgSize = (OS_MSG_SIZE )0u;
#endif
#if OS_CFG_TASK_Q_EN > 0u
OS_MsgQInit(&p_tcb->MsgQ,
(OS_MSG_QTY)0u);
#if OS_CFG_TASK_PROFILE_EN > 0u
p_tcb->MsgQPendTime = (CPU_TS )0u;
p_tcb->MsgQPendTimeMax = (CPU_TS )0u;
#endif
#endif
#if OS_CFG_FLAG_EN > 0u
p_tcb->FlagsPend = (OS_FLAGS )0u;
p_tcb->FlagsOpt = (OS_OPT )0u;
p_tcb->FlagsRdy = (OS_FLAGS )0u;
#endif
#if OS_CFG_TASK_REG_TBL_SIZE > 0u
for (id = 0u; id < OS_CFG_TASK_REG_TBL_SIZE; id++) {
p_tcb->RegTbl[id] = (OS_REG)0u;
}
#endif
p_tcb->SemCtr = (OS_SEM_CTR )0u;
#if OS_CFG_TASK_PROFILE_EN > 0u
p_tcb->SemPendTime = (CPU_TS )0u;
p_tcb->SemPendTimeMax = (CPU_TS )0u;
#endif
p_tcb->StkSize = (CPU_STK_SIZE )0u;
#if OS_CFG_TASK_SUSPEND_EN > 0u
p_tcb->SuspendCtr = (OS_NESTING_CTR )0u;
#endif
#if OS_CFG_STAT_TASK_STK_CHK_EN > 0u
p_tcb->StkFree = (CPU_STK_SIZE )0u;
p_tcb->StkUsed = (CPU_STK_SIZE )0u;
#endif
p_tcb->Opt = (OS_OPT )0u;
p_tcb->TickCtrPrev = (OS_TICK )OS_TICK_TH_INIT;
p_tcb->TickCtrMatch = (OS_TICK )0u;
p_tcb->TickRemain = (OS_TICK )0u;
p_tcb->TimeQuanta = (OS_TICK )0u;
p_tcb->TimeQuantaCtr = (OS_TICK )0u;
#if OS_CFG_TASK_PROFILE_EN > 0u
p_tcb->CPUUsage = (OS_CPU_USAGE )0u;
p_tcb->CtxSwCtr = (OS_CTX_SW_CTR )0u;
p_tcb->CyclesDelta = (CPU_TS )0u;
ts = OS_TS_GET(); /* Read the current timestamp and save */
p_tcb->CyclesStart = ts;
p_tcb->CyclesTotal = (OS_CYCLES )0u;
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
p_tcb->IntDisTimeMax = (CPU_TS )0u;
#endif
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
p_tcb->SchedLockTimeMax = (CPU_TS )0u;
#endif
p_tcb->PendOn = (OS_STATE )OS_TASK_PEND_ON_NOTHING;
p_tcb->PendStatus = (OS_STATUS )OS_STATUS_PEND_OK;
p_tcb->TaskState = (OS_STATE )OS_TASK_STATE_RDY;
p_tcb->Prio = (OS_PRIO )OS_PRIO_INIT;
#if OS_CFG_DBG_EN > 0u
p_tcb->DbgPrevPtr = (OS_TCB *)0;
p_tcb->DbgNextPtr = (OS_TCB *)0;
p_tcb->DbgNamePtr = (CPU_CHAR *)((void *)" ");
#endif
}这里面可以简单理解为任务控制块tcb里面有保存任务信息的结构体,这里面都是将结构体设置程默认值。
(4)、初始化栈空间
if ((opt & OS_OPT_TASK_STK_CHK) != (OS_OPT)0) { /* See if stack checking has been enabled */
if ((opt & OS_OPT_TASK_STK_CLR) != (OS_OPT)0) { /* See if stack needs to be cleared */
p_sp = p_stk_base;
for (i = 0u; i < stk_size; i++) { /* Stack grows from HIGH to LOW memory */
*p_sp = (CPU_STK)0; /* Clear from bottom of stack and up! */
p_sp++;
}
}
}这里面主要就是利用循环的办法来清空栈空间,一般是需要设置OS_OPT_TASK_STK_CHK和OS_OPT_TASK_STK_CLR
(5)、获取栈顶指针
p_sp = OSTaskStkInit(p_task,
p_arg,
p_stk_base,
p_stk_limit,
stk_size,
opt);
//* Returns : Always returns the location of the new top-of-stack' once the processor //registers have
//* been placed on the stack in the proper order.
//一旦成功的设置了tcb里面的内容,将会返回栈顶的指针这一步和我们的arm也有关系,arm总是从栈顶向下慢慢使用资源的。
(6)、开始正式的tcb赋你传进来的参数值
/* -------------- INITIALIZE THE TCB FIELDS ------------- */
p_tcb->TaskEntryAddr = p_task; /* Save task entry point address */
p_tcb->TaskEntryArg = p_arg; /* Save task entry argument */
p_tcb->NamePtr = p_name; /* Save task name */
p_tcb->Prio = prio; /* Save the task's priority */
p_tcb->StkPtr = p_sp; /* Save the new top-of-stack pointer */
p_tcb->StkLimitPtr = p_stk_limit; /* Save the stack limit pointer */
p_tcb->TimeQuanta = time_quanta; /* Save the #ticks for time slice (0 means not sliced) */
p_tcb->ExtPtr = p_ext; /* Save pointer to TCB extension */
p_tcb->StkBasePtr = p_stk_base; /* Save pointer to the base address of the stack */
p_tcb->StkSize = stk_size; /* Save the stack size (in number of CPU_STK elements) */
p_tcb->Opt = opt; /* Save task options */
这些就是一些赋值操作,没什么可说的
(7)、插入优先级
void OS_PrioInsert (OS_PRIO prio)
{
CPU_DATA bit;
CPU_DATA bit_nbr;
OS_PRIO ix;
ix = prio / DEF_INT_CPU_NBR_BITS;
bit_nbr = (CPU_DATA)prio & (DEF_INT_CPU_NBR_BITS - 1u);
bit = 1u;
bit <<= (DEF_INT_CPU_NBR_BITS - 1u) - bit_nbr;
OSPrioTbl[ix] |= bit;
}这里的原理前面的我也没太看清楚算的什么东西,但是大概意思就是把你传递进来的优先级进行运算后插入到一个优先级表中去,这个所谓的优先级表就是一个数组。算的优先级就是一个数组下标
(8)、添加任务到ready任务队列当中
void OS_RdyListInsertTail (OS_TCB *p_tcb)
{
OS_RDY_LIST *p_rdy_list;
OS_TCB *p_tcb2;
p_rdy_list = &OSRdyList[p_tcb->Prio];
if (p_rdy_list->NbrEntries == (OS_OBJ_QTY)0) { /* CASE 0: Insert when there are no entries */
p_rdy_list->NbrEntries = (OS_OBJ_QTY)1; /* This is the first entry */
p_tcb->NextPtr = (OS_TCB *)0; /* No other OS_TCBs in the list */
p_tcb->PrevPtr = (OS_TCB *)0;
p_rdy_list->HeadPtr = p_tcb; /* Both list pointers point to this OS_TCB */
p_rdy_list->TailPtr = p_tcb;
} else { /* CASE 1: Insert AFTER the current tail of list */
p_rdy_list->NbrEntries++; /* One more OS_TCB in the list */
p_tcb->NextPtr = (OS_TCB *)0; /* Adjust new OS_TCBs links */
p_tcb2 = p_rdy_list->TailPtr;
p_tcb->PrevPtr = p_tcb2;
p_tcb2->NextPtr = p_tcb; /* Adjust old tail of list's links */
p_rdy_list->TailPtr = p_tcb;
}
}这里的大概意思就是,所有的创建好的任务都处于一个就绪态,所有就绪态的任务根据优先级都会分配到一个数组当中数组内存储的都是每一个任务的任务控制块的结构体指针,如果这个刚创建的任务的优先级没有其他任务和他在一起就把他放在这,如果有就把两个任务连接起来。
(9)、任务创建的计数变量++
OSTaskQty++;
/* Increment the #tasks counter */
边栏推荐
- 《遥远的救世主》遵守客观规律(七)——文化属性
- Huawei image xmage: seek all the images in the world, and finally see the Bodhi Heart
- 【產品人衛朋】2022年產品人必備的13個設計類網站(1.0版)
- It's decided. There are 93 open source tasks in 6 fields. Alibaba open source tutor will take you to participate in the open source summer 2022 of the Chinese Academy of Sciences
- nn. BCEWithLogisticLoss() & nn. The difference between bceloss(), nn CrossEntropyLoss() & nn. Nllloss() differences
- zabbix 监控服务 (四)配置触发器
- 数据可视化之matplotlib绘制饼状图
- [day 33] or the use of operation | continuous low 0 to 1
- C#网络应用编程,实验4:线程管理练习
- 《遥远的救世主》遵守客观规律(六)——文化属性
猜你喜欢

【golang】cannot unmarshal xxx “ into Go struct field xxx of type xxx

Nature microbiology | Bacillus subtilis biofilm promotes melon growth and disease resistance

C#网络应用编程,实验七: 异步编程练习

華為影像XMAGE:求盡世間像,終見菩提心

C#网络应用编程,实验2:IP地址转换和域名解析练习

C#网络应用编程,实验4:线程管理练习
![[dynamic programming]dp20 calculation string editing distance - medium](/img/89/9c56bc84e07f0c253a66b837f14232.png)
[dynamic programming]dp20 calculation string editing distance - medium

2022 G3 boiler water treatment examination question bank and simulation examination

S7-200SMART案例分析——运动控制编程(二)

2022年最新天津建筑安全员模拟题库及答案
随机推荐
2022.7.14-----leetcode.745
[autosar-dem] - 2.4-app SWC how to read mil lamp status and configure mil lamp
Package C language files into exe executable programs
阿里妈妈展示广告引擎新探索:迈向全局最优算力分配
uCOS-III学习笔记——软件定时器
对象序列化流与反序列化流
Concept correlation and pattern matching of strings
TCP拥塞控制详解 | 6. 主动队列管理
1.创建Prism项目
[dynamic programming]dp20 calculation string editing distance - medium
2022.7.15-----leetcode.558
JD finance, are you bad, or are you cutting too much??
2022 latest Tianjin Construction Safety Officer simulation question bank and answers
自己第一次正畸情况(持续更新中)
module ‘sklearn. datasets‘ has no attribute ‘fetch_ mldata‘
Pytorch构建网络细节总结
The art of code annotation. Does excellent code really need no annotation?
使用plt.savefig()方法保存绘图时出现图片全白或全黑的问题
S7-200SMART案例分析——运动控制编程(二)
C#求完全数,输出水仙花以及类的使用