想让µC/OS-Ⅱ管理用户的任务,用户必须要先建立任务。用户可以通过传递任务地址和其它参数到以下两个函数之一来建立任务:OSTaskCreate() 或 OSTaskCreateExt()。OSTaskCreate()与µC/OS是向下兼容的,OSTaskCreateExt()是OSTaskCreate()的扩展版本,提供了一些附加的功能。用两个函数中的任何一个都可以建立任务。任务可以在多任务调度开始前建立,也可以在其它任务的执行过程中被建立。在开始多任务调度(即调用OSStart())前,用户必须建立至少一个任务。任务不能由中断服务程序(ISR)来建立。OSTaskCreate()的代码如程序清单 L4.1所述。从中可以知道,OSTaskCreate()需要四个参数:task是任务代码的指针,pdata是当任务开始执行时传递给任务的参数的指针,ptos是分配给任务的堆栈的栈顶指针(参看4.02,任务堆栈),prio是分配给任务的优先级。程序清单 L4.1   OSTaskCreate()
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
{void   *psp;INT8U   err;if (prio > OS_LOWEST_PRIO) {                                            (1)return (OS_PRIO_INVALID);}OS_ENTER_CRITICAL();if (OSTCBPrioTbl[prio] == (OS_TCB *)0) {                             (2)OSTCBPrioTbl[prio] = (OS_TCB *)1;                                  (3)OS_EXIT_CRITICAL();                                                (4)psp = (void *)OSTaskStkInit(task, pdata, ptos, 0);               (5)err = OSTCBInit(prio, psp, (void *)0, 0, 0, (void *)0, 0);          (6)if (err == OS_NO_ERR) {                                           (7)OS_ENTER_CRITICAL();OSTaskCtr++;                                                  (8)OSTaskCreateHook(OSTCBPrioTbl[prio]);                           (9)OS_EXIT_CRITICAL();if (OSRunning) {                                              (10)OSSched();                                                (11)}
        } else {OS_ENTER_CRITICAL();OSTCBPrioTbl[prio] = (OS_TCB *)0;                             (12)OS_EXIT_CRITICAL();}return (err);} else {OS_EXIT_CRITICAL();return (OS_PRIO_EXIST);}
}OSTaskCreate()一开始先检测分配给任务的优先级是否有效[L4.1(1)]。任务的优先级必须在0到OS_LOWEST_PRIO之间。接着,OSTaskCreate()要确保在规定的优先级上还没有建立任务[L4.1(2)]。在使用µC/OS-Ⅱ时,每个任务都有特定的优先级。如果某个优先级是空闲的,µC/OS-Ⅱ通过放置一个非空指针在OSTCBPrioTbl[]中来保留该优先级[L4.1(3)]。这就使得OSTaskCreate()在设置任务数据结构的其他部分时能重新允许中断[L4.1(4)]。然后,OSTaskCreate()调用OSTaskStkInit()[L4.1(5)],它负责建立任务的堆栈。该函数是与处理器的硬件体系相关的函数,可以在OS_CPU_C.C文件中找到。有关实现OSTaskStkInit()的细节可参看第8章——移植µC/OS-Ⅱ。如果已经有人在你用的处理器上成功地移植了µC/OS-Ⅱ,而你又得到了他的代码,就不必考虑该函数的实现细节了。OSTaskStkInit()函数返回新的堆栈栈顶(psp),并被保存在任务的0S_TCB中。注意用户得将传递给OSTaskStkInit()函数的第四个参数opt置0,因为OSTaskCreate()与OSTaskCreateExt()不同,它不支持用户为任务的创建过程设置不同的选项,所以没有任何选项可以通过opt参数传递给OSTaskStkInit()。µC/OS-Ⅱ支持的处理器的堆栈既可以从上(高地址)往下(低地址)递减也可以从下往上递增。用户在调用OSTaskCreate()的时候必须知道堆栈是递增的还是递减的(参看所用处理器的OS_CPU.H中的OS_STACK_GROWTH),因为用户必须得把堆栈的栈顶传递给OSTaskCreate(),而栈顶可能是堆栈的最高地址(堆栈从上往下递减),也可能是最低地址(堆栈从下往上长)。一旦OSTaskStkInit()函数完成了建立堆栈的任务,OSTaskCreate()就调用OSTCBInit()[L4.1(6)],从空闲的OS_TCB池中获得并初始化一个OS_TCB。OSTCBInit()的代码如程序清单 L4.2所示,它存在于0S_CORE.C文件中而不是OS_TASK.C文件中。OSTCBInit()函数首先从OS_TCB缓冲池中获得一个OS_TCB[L4.2(1)],如果OS_TCB池中有空闲的OS_TCB[L4.2(2)],它就被初始化[L4.2(3)]。注意一旦OS_TCB被分配,该任务的创建者就已经完全拥有它了,即使这时内核又创建了其它的任务,这些新任务也不可能对已分配的OS_TCB作任何操作,所以OSTCBInit()在这时就可以允许中断,并继续初始化OS_TCB的数据单元。
程序清单 L 4.2   OSTCBInit()
INT8U OSTCBInit (INT8U  prio,     OS_STK *ptos,   OS_STK *pbos, INT16U id,INT16U stk_size, void   *pext,   INT16U  opt)
{OS_TCB *ptcb;OS_ENTER_CRITICAL();ptcb = OSTCBFreeList;                                     (1)if (ptcb != (OS_TCB *)0) {                             (2)OSTCBFreeList        = ptcb->OSTCBNext;OS_EXIT_CRITICAL();ptcb->OSTCBStkPtr    = ptos;                         (3)ptcb->OSTCBPrio      = (INT8U)prio;ptcb->OSTCBStat      = OS_STAT_RDY;ptcb->OSTCBDly       = 0;
#if OS_TASK_CREATE_EXT_ENptcb->OSTCBExtPtr    = pext;ptcb->OSTCBStkSize   = stk_size;ptcb->OSTCBStkBottom = pbos;ptcb->OSTCBOpt       = opt;ptcb->OSTCBId        = id;
#elsepext                 = pext;stk_size             = stk_size;pbos                 = pbos;opt                  = opt;id                   = id;
#endif#if OS_TASK_DEL_ENptcb->OSTCBDelReq    = OS_NO_ERR;
#endifptcb->OSTCBY         = prio >> 3;
        ptcb->OSTCBBitY      = OSMapTbl[ptcb->OSTCBY];ptcb->OSTCBX         = prio & 0x07;ptcb->OSTCBBitX      = OSMapTbl[ptcb->OSTCBX];#if     OS_MBOX_EN || (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_SEM_ENptcb->OSTCBEventPtr  = (OS_EVENT *)0;
#endif#if     OS_MBOX_EN || (OS_Q_EN && (OS_MAX_QS >= 2))ptcb->OSTCBMsg       = (void *)0;
#endifOS_ENTER_CRITICAL();                                (4)OSTCBPrioTbl[prio]   = ptcb;                        (5)ptcb->OSTCBNext      = OSTCBList;ptcb->OSTCBPrev      = (OS_TCB *)0;if (OSTCBList != (OS_TCB *)0) {OSTCBList->OSTCBPrev = ptcb;}OSTCBList               = ptcb;OSRdyGrp               |= ptcb->OSTCBBitY;            (6)OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;OS_EXIT_CRITICAL();return (OS_NO_ERR);                                 (7)} else {OS_EXIT_CRITICAL();return (OS_NO_MORE_TCB);}
}当OSTCBInit()需要将OS_TCB插入到已建立任务的OS_TCB的双向链表中时[L4.2(5)],它就禁止中断[L4.2(4)]。该双向链表开始于OSTCBList,而一个新任务的OS_TCB常常被插入到链表的表头。最后,该任务处于就绪状态[L4.2(6)],并且OSTCBInit()向它的调用者[OSTaskCreate()]返回一个代码表明OS_TCB已经被分配和初始化了[L4.2(7)]。现在,我可以继续讨论OSTaskCreate()(程序清单 L4.1)函数了。从OSTCBInit()返回后,OSTaskCreate()要检验返回代码[L4.1(7)],如果成功,就增加OSTaskCtr[L4.1(8)],OSTaskCtr用于保存产生的任务数目。如果OSTCBInit()返回失败,就置OSTCBPrioTbl[prio]
的入口为0[L4.1(12)]以放弃该任务的优先级。然后,OSTaskCreate()调用OSTaskCreateHook()[L4.1(9)],OSTaskCreateHook()是用户自己定义的函数,用来扩展OSTaskCreate()的功能。例如,用户可以通过OSTaskCreateHook()函数来初始化和存储浮点寄存器、MMU寄存器的内容,或者其它与任务相关的内容。一般情况下,用户可以在内存中存储一些针对用户的应用程序的附加信息。OSTaskCreateHook()既可以在OS_CPU_C.C中定义(如果OS_CPU_HOOKS_EN置1),也可以在其它地方定义。注意,OSTaskCreate()在调用OSTaskCreateHook()时,中断是关掉的,所以用户应该使OSTaskCreateHook()函数中的代码尽量简化,因为这将直接影响中断的响应时间。OSTaskCreateHook()在被调用时会收到指向任务被建立时的OS_TCB的指针。这意味着该函数可以访问OS_TCB数据结构中的所有成员。如果OSTaskCreate()函数是在某个任务的执行过程中被调用(即OSRunning置为True[L4.1(10)]),则任务调度函数会被调用[L4.1(11)]来判断是否新建立的任务比原来的任务有更高的优先级。如果新任务的优先级更高,内核会进行一次从旧任务到新任务的任务切换。如果在多任务调度开始之前(即用户还没有调用OSStart()),新任务就已经建立了,则任务调度函数不会被调用。

建立任务,OSTaskCreate()相关推荐

  1. 建立任务,OSTaskCreate()源码解析

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

  2. μC/OS之OSTaskCreate()

    转自 http://blog.csdn.net/xiaocaichonga/article/details/7449409 建立任务OSTaskCreate() 1.OSTaskCreate()函数的 ...

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

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

  4. 【UCOSii源码解析】任务管理

    系列文章 UCOSii启动流程以及平台相关文件分析 优先级算法及内核源码分析 任务管理 时间管理 事件控制块 内存管理 任务间通讯与同步 文章目录 前言 (一)重提任务 (二)核心API源码分析 1. ...

  5. uCOS-II 基础入门教程(九)

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

  6. μC/OS-II学习--使用篇(一篇就足够了)

    μC/OS-II ,这个以前都读成了miu C OS two.其实应该读做"micro C O S two",μ代表"微小"之意,字母C代表"控制器& ...

  7. 从单片机到嵌入式开发——(8) μC/OS-II嵌入式实时操作系统概述

    首先是一个对目前写的这些东西的总结.后面我会花大概两篇左右的内容来简单介绍一下STM32的使用.正文部分在后面一点,可以直接往后翻. 感想什么的 截止本篇为止,单片机的基本原理部分已经介绍完毕了.这个 ...

  8. OSTaskCreate()

    //建立一个新任务.与OSTaskCreate()不同的是,OSTaskCreateExt()允许用户设置更多的细节   //内容.任务的建立可以在多任务环境启动之前,也可以在正在运行的任务中建立,但 ...

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

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

最新文章

  1. 时代变了,大人:RTX 3090时代,哪款显卡配得上我的炼丹炉?
  2. 组合框CComboBox响应函数
  3. Eclipse中的checkstyle插件
  4. Office Communication Server(OCS)2007 Communicator Web Access(CWA)的部署
  5. javascript核心_javascript核心之DOM操作
  6. 米度教育零基础三个月学会机器学习视频总结
  7. java项目经验案例_PLC与POE结合项目经验案例总结
  8. 防震计算机主机,一种防震计算机主机的制作方法
  9. 自学python考哪些证书-给零基础学习Python的小伙伴的四个建议
  10. mysql启动成功但是没有进程_zabbix_server表面启动成功,但是没有进程
  11. mac PowerPoint 导出高分辨率图片
  12. 边城工具集:绘图及标注工具
  13. mysql 身份证号码判断
  14. word打开提示无法加载此程序mathpage.wll
  15. python实现微信自动投票_Python——开发一个自动化微信投票器【附代码实例方法】...
  16. SQL FULL OUTER JOIN
  17. 感悟生活,再来聊聊拼多多
  18. 百度近年来主要算法2017
  19. SVN中tag和branch的区别
  20. 铁甲雄心机器人冠军_机器人格斗元老亮相《铁甲雄心》虽败犹荣

热门文章

  1. go——内存分配机制
  2. ①用Dev-C++搭建C语言学习环境; ②为VScode配置TMD-GCC或MinGW编译器
  3. UE4 AssetManager
  4. 《印第安纳之法柜奇兵》影评
  5. Bootstrap 旋转轮播
  6. 《新火星人-3dsmax室内效果图风暴》10CD
  7. 球王礼遇:阿根廷足协大楼命名“梅西”,激励阿根廷足球再跨越
  8. oracle rowid唯一吗,ROWID唯一性
  9. Laravel入门学习教程
  10. java8 通过18位身份证号提取用户信息(年龄,生日,姓别)