ucos创建任务流程图_createthread函数的参数

ucos创建任务流程图_createthread函数的参数uC/OS-III任务创建函数OSTaskCreate()1.OSTaskCreate()函数原型voidTaskCreate(OS_TCB*p_tcb,//任务控制OS_TCB的地址CPU_CHAR*p_name,//任务的名字OS_TASK_PTRp_task,//任务代码的起始地址void*p_arg,//任务第一次运行时接收到

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

uC/OS-III任务创建函数OSTaskCreate()

欢迎进入linuxweiyh的博客

1.OSTaskCreate()函数原型

void TaskCreate(OS_TCB *p_tcb,  // 任务控制OS_TCB的地址
    CPU_CHAR *p_name,           // 任务的名字
    OS_TASK_PTR p_task,         // 任务代码的起始地址
    void *p_arg,                // 任务第一次运行时接收到的参数
    OS_PRIO prio,               // 任务优先级
    CPU_STK *p_stk_base,        // 任务栈的基地址,基地址总是栈空间的最低地址
    CPU_STK_SIZE stk_limit,     // 任务栈的深度标记
    CPU_STK_SIZE stk_size,      // 任务栈的大小
    OS_MSG_QTY q_size,          // 任务内部消息队列的大小
    OS_TICK time_quanta,        // 时间片轮转的长度
    void *p_ext,                // 用户补充的存储区
    OS_OPT opt,                 // 任务特定选项
    OS_ERR *p_err)              // 错误码

注1:这里最需要注意的参数是任务栈的基地址,这里的基地址指的是栈空间的最低地址,即???Stk[0]的地址。
注2:在uC/OS-II:的OSTaskCreate()函数中,描述有关栈的参数是栈顶地址,不是栈的基地址。
注3:深度标记stk_limit表示的是栈剩余空间,不需要管栈的增长方向,是多少就是多少,uC/OS-III内部会自己转换。当栈的剩余空间小于栈的深度标记时会报警。
2.OSTaskCreate()函数代码解析

void  OSTaskCreate (OS_TCB        *p_tcb,
CPU_CHAR      *p_name,
OS_TASK_PTR    p_task,
void          *p_arg,
OS_PRIO        prio,
CPU_STK       *p_stk_base,
CPU_STK_SIZE   stk_limit,
CPU_STK_SIZE   stk_size,
OS_MSG_QTY     q_size,
OS_TICK        time_quanta,
void          *p_ext,
OS_OPT         opt,
OS_ERR        *p_err)
{
CPU_STK_SIZE   i;
#if OS_CFG_TASK_REG_TBL_SIZE > 0u
OS_OBJ_QTY     reg_nbr;
#endif
CPU_STK       *p_sp;
CPU_STK       *p_stk_limit;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#ifdef OS_SAFETY_CRITICAL_IEC61508
if (OSSafetyCriticalStartFlag == DEF_TRUE) {
*p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;
return;
}
#endif
// 不允许在ISR中创建任务
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u 
if (OSIntNestingCtr > (OS_NESTING_CTR)0) {              
*p_err = OS_ERR_TASK_CREATE_ISR;
return;
}
#endif
// 形参检测
#if OS_CFG_ARG_CHK_EN > 0u 
if (p_tcb == (OS_TCB *)0) {              // 任务控制块
*p_err = OS_ERR_TCB_INVALID;
return;
}
if (p_task == (OS_TASK_PTR)0) {          // 任务起始地址
*p_err = OS_ERR_TASK_INVALID;
return;
}
if (p_stk_base == (CPU_STK *)0) {        // 栈的基地址 
*p_err = OS_ERR_STK_INVALID;
return;
}
if (stk_size < OSCfg_StkSizeMin) {      // 栈的大小 
*p_err = OS_ERR_STK_SIZE_INVALID;
return;
}
if (stk_limit >= stk_size) {             // 栈的深度标记 
*p_err = OS_ERR_STK_LIMIT_INVALID;
return;
}
if (prio >= OS_CFG_PRIO_MAX) {           // 任务优先级 
*p_err = OS_ERR_PRIO_INVALID;
return;
}
#endif
// 任务的优先级检测
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
if (prio == (OS_PRIO)0) {
if (p_tcb != &OSIntQTaskTCB) {
*p_err = OS_ERR_PRIO_INVALID;              // 不允许任务的优先级为0
return;
}
}
#endif
if (prio == (OS_CFG_PRIO_MAX - 1u)) {
if (p_tcb != &OSIdleTaskTCB) {                 // 不允许与空闲任务的优先级相同
*p_err = OS_ERR_PRIO_INVALID;       
return;
}
}
// 初始化任务控制块(OS_TCB)
OS_TaskInitTCB(p_tcb);
*p_err = OS_ERR_NONE;
// 清空任务栈
if ((opt & OS_OPT_TASK_STK_CHK) != (OS_OPT)0) {      // 是否使能任务栈检测
if ((opt & OS_OPT_TASK_STK_CLR) != (OS_OPT)0) {  // 任务栈是否必须清空 
p_sp = p_stk_base;
for (i = 0u; i < stk_size; i++) {            // 栈的增长方向是从高到低
*p_sp = (CPU_STK)0;                      // 从低到高清空栈
p_sp++;
}
}
}
// 初始化栈的深度标记
#if (CPU_CFG_STK_GROWTH == CPU_STK_GROWTH_HI_TO_LO)
p_stk_limit = p_stk_base + stk_limit;
#else
p_stk_limit = p_stk_base + (stk_size - 1u) - stk_limit;
#endif
// 初始化栈
p_sp = OSTaskStkInit(p_task,
p_arg,
p_stk_base,
p_stk_limit,
stk_size,
opt);
// 初始化OS_TCB
p_tcb->TaskEntryAddr = p_task;       // 保存任务入口地址
p_tcb->TaskEntryArg  = p_arg;        // 保存任务参数
p_tcb->NamePtr       = p_name;       // 保存任务名称
p_tcb->Prio          = prio;         // 保存任务优先级
p_tcb->StkPtr        = p_sp;         // 保存栈顶地址
p_tcb->StkLimitPtr   = p_stk_limit;  // 保存栈深度标记
p_tcb->TimeQuanta    = time_quanta;  // 保存任务时间片
#if OS_CFG_SCHED_ROUND_ROBIN_EN > 0u
if (time_quanta == (OS_TICK)0) {
p_tcb->TimeQuantaCtr = OSSchedRoundRobinDfltTimeQuanta;
} else {
p_tcb->TimeQuantaCtr = time_quanta;
}
#endif
p_tcb->ExtPtr        = p_ext;        // 保存额外的TCB结构
p_tcb->StkBasePtr    = p_stk_base;   // 保存栈的基地址 
p_tcb->StkSize       = stk_size;     // 保存栈的大小
p_tcb->Opt           = opt;          // 保存任务可选项
#if OS_CFG_TASK_REG_TBL_SIZE > 0u
for (reg_nbr = 0u; reg_nbr < OS_CFG_TASK_REG_TBL_SIZE; reg_nbr++) {
p_tcb->RegTbl[reg_nbr] = (OS_REG)0;
}
#endif
#if OS_CFG_TASK_Q_EN > 0u
OS_MsgQInit(&p_tcb->MsgQ,                               /* Initialize the task's message queue */
q_size);
#endif
OSTaskCreateHook(p_tcb);              // 调用用户定义的介入函数
// 把任务添加到任务就绪表中
OS_CRITICAL_ENTER();                  // 进入临界区
OS_PrioInsert(p_tcb->Prio);           // 向任务表中添加任务优先级
OS_RdyListInsertTail(p_tcb);
#if OS_CFG_DBG_EN > 0u
OS_TaskDbgListAdd(p_tcb);
#endif
OSTaskQty++;  // Increment the #tasks counter
if (OSRunning != OS_STATE_OS_RUNNING) {  // Return if multitasking has not started
OS_CRITICAL_EXIT();               // 退出临界区
return;
}
OS_CRITICAL_EXIT_NO_SCHED();          // 退出临界区
OSSched();                            // 调度
}

总结:OSTaskCreate()函数主要的工作是初始化任务控制块、初始化栈、添加任务到任务任务就绪表。
注:由于目前对uC/OS-III的理解不是很透彻,所以只能做部分注释,以后会逐步增加。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/196895.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 【Redis】集群

    【Redis】集群【Redis】集群

  • 优先级队列默认最小值优先吗_低优先级队列要等几局

    优先级队列默认最小值优先吗_低优先级队列要等几局1.优先级队列是什么??首先,优先级队列是一个队列,队列所有的性质,它也有。其次,优先级队列每次取出的是优先级最高的元素。优先级队列的内部是用堆来维护的。将优先级最高的排在前面。2.什么时候用这个队列呢??看完优先级队列的定义,好像看懂了,又好像没看懂。这队列,什么用它呢?1)排序的对象和排序时比较的对象常见的排序方法(插入、快排等),排序的对象和比较的对象是一样的,根据数本身的大小进行排序。优先级队列可以对排序对象和比较对象相同的进行排序,也可以对排序的对象和排序时比较的对象不同的

  • 大数据数据分析架构探究

    大数据数据分析架构探究

  • 成功的草根网站_草根网 真看不懂

    成功的草根网站_草根网 真看不懂 如果你是菜鸟站长,如果你可以耐心的看完这篇文章,那么你的网站建设道路会少一些磕拌,多一些平坦.以上两个如果若不满足可以直接回主版面了.  首先声明一下,我也是菜鸟,虽然接触网站制作很久了,从2000年开始的,但中途做做停停,耽误了太多的时间,所以到现在我也只是个菜鸟,充其量只是个老菜鸟吧.但正因为我也是菜鸟,所以我说的东西都是些浅显易懂的,应该会对各位新手有些帮助吧,至少是少走很多弯路!

    2022年10月18日
  • malloc函数的用法(超级白话版)[通俗易懂]

    malloc函数的用法(超级白话版)[通俗易懂]malloc函数的用法在这里,我不讲什么原理性的东西,我就单纯讲讲怎么用。首先malloc()函数返回的是void*类型,所以用的时候要进行强制类型转换malloc函数用完后,记得使用free()函数来释放空间,不然只分配不释放会出问题例L=(int*)malloc(sizeof(int));我们看到了先用int*进行了强制类型转换,说明L的类型为int*,⚠️如果你不进行强制类型转换,分配空间会报错sizeof(int)的意思是分配的字节数,分配和int类型一样的字节数,当然,

  • 微信电脑版打不开怎么办?电脑版微信打不开的解决方案_wechatwin.dll文件缺失怎么解决

    微信电脑版打不开怎么办?电脑版微信打不开的解决方案_wechatwin.dll文件缺失怎么解决微信现在除了是日常的交流工具,基本上办公也离不开它,微信也注意到大家的意愿,所以也开发了电脑端的微信,不过有时候电脑版的微信也不好用,遇到紧急情况需要通知同事的时候又发现打不开了,通常遇上这种情况,我们要采取这些措施。解决办法如下:电脑版微信打不开是怎么一回事?第一步要做的就是,排查网络或是电脑系统的问题,可以重启试试。排除电脑或者网络问题以后,那可能是微信客户端不稳定。也许是文件损坏了或者是系统…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号