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 > 0uOS_OBJ_QTY     reg_nbr;
#endifCPU_STK       *p_sp;CPU_STK       *p_stk_limit;CPU_SR_ALLOC();#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return;}
#endif#ifdef OS_SAFETY_CRITICAL_IEC61508if (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 > 0uif (prio == (OS_PRIO)0) {if (p_tcb != &OSIntQTaskTCB) {*p_err = OS_ERR_PRIO_INVALID;              // 不允许任务的优先级为0return;}}
#endifif (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;
#elsep_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_TCBp_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 > 0uif (time_quanta == (OS_TICK)0) {p_tcb->TimeQuantaCtr = OSSchedRoundRobinDfltTimeQuanta;} else {p_tcb->TimeQuantaCtr = time_quanta;}
#endifp_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 > 0ufor (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 > 0uOS_MsgQInit(&p_tcb->MsgQ,                               /* Initialize the task's message queue                    */q_size);
#endifOSTaskCreateHook(p_tcb);              // 调用用户定义的介入函数// 把任务添加到任务就绪表中OS_CRITICAL_ENTER();                  // 进入临界区OS_PrioInsert(p_tcb->Prio);           // 向任务表中添加任务优先级OS_RdyListInsertTail(p_tcb);#if OS_CFG_DBG_EN > 0uOS_TaskDbgListAdd(p_tcb);
#endifOSTaskQty++;  // Increment the #tasks counterif (OSRunning != OS_STATE_OS_RUNNING) {  // Return if multitasking has not startedOS_CRITICAL_EXIT();               // 退出临界区return;}OS_CRITICAL_EXIT_NO_SCHED();          // 退出临界区OSSched();                            // 调度
}

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

uC/OS-III任务创建函数OSTaskCreate()相关推荐

  1. 任务创建函数OSTaskCreate解析

    任务是操作系统处理的首要对象,在多任务运行的环境中,任务的管理需要考虑多方面的因素,最基本的任务管理是任务的创建.任务创建函数有两种,一种是基本的创建函数OSTaskCreate,另一种是扩展的任务创 ...

  2. uC/OS任务创建函数OSTaskCreate ()参数详解

    要使用 uC/OS 的任务必须先声明任务控制块和创建任务,调用 OSTaskCreate () 函数可以创建一个任务.OSTaskCreate () 函数的信息如下表所示.

  3. UC/OS III操作系统学习笔记

    UCOS操作系统学习笔记 1.UCOSIII任务 1.1任务管理 1.2 任务创建和删除.挂起和恢复 1.3 系统内部任务 2.UCOSIII中断和时间管理 2.1 中断管理 2.2 时间管理 3.U ...

  4. 整理uc/os的46个函数

    Void OSInit(void); 所属文件 OS_CORE.C     调用者 启动代码    开关量 无 OSinit()初始化μC/OS-Ⅱ,对这个函数的调用必须在调用OSStart()函数之 ...

  5. uC/OS iii(三)任务管理之任务状态

    博客已转移至https://www.cnblogs.com/heart-flying/p/10148254.html

  6. UC/OS II 任务管理(4)之任务创建

    任务的创建函数 ucosii之前的版本都只支持64个任务,但是V2.90版本支持的任务数量达到了256. 用法和原理都差不多.我这里就只介绍任务数不大于64的情况.当任务大于64的时候,只需要配置相关 ...

  7. 嵌入式系统开发16——嵌入式实时操作系统uC/OS的简介及简单应用

    本文主要介绍嵌入式实时操作系统(RTOS),并且以uc/OS为例,将其移植到stm32F103C8T6上,构建3个任务:其中两个task分别以1s和3s周期对LED灯进行点亮-熄灭的控制:另外一个ta ...

  8. uC/OS II 函数说明 之–OSTaskCreate()与OSTaskCreateExt()

    1. OSTaskCreate()     OSTaskCreate()建立一个新任务,能够在多任务环境启动之前,或者执行任务中建立任务.注意,ISR中禁止建立任务,一个任务必须为无限循环结构.    ...

  9. 笔记之uC/OS 多任务机制OSTaskCreate()

    想让uC/OS-Ⅱ管理用户的任务,用户必须要先建立任务.用户可以通过传递任务地址和其它参数到以下两个函数之一来建立任务:OSTaskCreate() 或 OSTaskCreateExt().OSTas ...

最新文章

  1. 【小松教你手游开发】【unity实用技能】unity游戏移植到WindowsPhone8平台上的一些...
  2. python手机号码正确编程_python 小练习之生成手机号码
  3. Android studio 运行即打包keystore之build.gradle设置
  4. Autowire异常
  5. Linux下打印调试管理
  6. windows下cuda10.0+cudnn的配置
  7. signature=27524ebaa2473e38aa641bf251dcf3cf,[Without Title]
  8. 测试员:你知道未来移动测试的方向是什么样的吗?
  9. 【音乐拼接】mp3格式
  10. 漫画C语言 做个聊天软件你不懂也得懂
  11. OpenCV: 读取图片中某个点的像素值
  12. 文献阅读-深度学习跨模态图文检索研究综述
  13. html不能打开图片,HTML无法打开图片
  14. 查询mysql索引信息_数据查询优化之mysql索引
  15. linux su无效_linux系统 su切换用户失败情况
  16. C++ string assign和append的常用方法
  17. NOIP2015提高组 信息传递(图论)
  18. C++中mutable的用法和存在意义
  19. 什么样的工作轻松又赚钱?真的有这样的工作吗?
  20. 基于Springboot+Mybatis+mysql+vue技术交流博客论坛系统

热门文章

  1. VS2010中文旗舰版下载 Visual Studio 2010 Ultimate
  2. 2021-11-18 WinFrom面试题 Winform中,怎么实现Form2中点击打开按钮,打开Form1,输入文本,再点击Form1中的“确定”按钮,把输入的值显示到Form2的文本框中?
  3. 事业合伙人制度研究报告
  4. EOS区块链上EOSJS和scatter开发dApp
  5. 在C#中以编程方式将 MS Project MPP 转换为 Word 文档
  6. 如何让人觉得你情商高
  7. Zynq UltraScale+ MPSoC-模拟U盘
  8. js获取用户的操作系统和浏览器版本的方法
  9. 打扑克直播软件app开发:直播如何和游戏结合?
  10. VS2013下MFC通过ADO连接Access数据库