uC/OS-II中,各个任务间可以共享任务堆栈_什么是多任务系统

uC/OS-II中,各个任务间可以共享任务堆栈_什么是多任务系统想让uC/OS-Ⅱ管理用户的任务,用户必须要先建立任务。用户可以通过传递任务地址和其它参数到以下两个函数之一来建立任务:OSTaskCreate()或OSTaskCreateExt()。OSTaskCreate()与uC/OS是向下兼容的,OSTaskCreateExt()是OSTaskCreate()的扩展版本,提供了一些附加的功能。用两个函数中的任何一个都可以建立任务。  任务可以在多任…

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

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
想让uC/OS-Ⅱ管理用户的任务,用户必须要先建立任务。用户可以通过传递任务地址和其它参数到以下两个函数之一来建立任务:OSTaskCreate() 或 OSTaskCreateExt()。OSTaskCreate()与uC/OS是向下兼容的,OSTaskCreateExt()是OSTaskCreate()的扩展版本,提供了一些附加的功能。用两个函数中的任何一个都可以建立任务。

   任务可以在多任务调度开始前建立,也可以在其它任务的执行过程中被建立。在开始多任务调度(即调用OSStart())前,用户必须建立至少一个任务。任务不能由中断服务程序(ISR)来建立。

OSTaskCreate()的代码如程序清单 L4.1所述。从中可以知道,OSTaskCreate()需要四个参数:

task是任务代码的指针,

pdata是当任务开始执行时传递给任务的参数的指针,

ptos是分配给任务的堆栈的栈顶指针(参看4.02,任务堆栈),

prio是分配给任务的优先级。

OSTaskCreate函数源码

  1. //建立一个新任务    
  2. #if OS_TASK_CREATE_EN > 0                //允许生成OSTaskCreate()函数    
  3. INT8U  OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)    
  4. {    
  5. #if OS_CRITICAL_METHOD == 3                  //中断函数被设定为模式3    
  6.     OS_CPU_SR  cpu_sr;    
  7. #endif    
  8.     OS_STK    *psp;                         //初始化任务堆栈指针变量,返回新的栈顶指针    
  9.     INT8U      err;                         //定义(获得并定义初始化任务控制块)是否成功    
  10.     
  11.     
  12. #if OS_ARG_CHK_EN > 0                        //所有参数必须在指定的参数内    
  13.     if (prio > OS_LOWEST_PRIO) {            //检查任务优先级是否合法    
  14.         return (OS_PRIO_INVALID);           //参数指定的优先级大于OS_LOWEST_PRIO    
  15.     }    
  16. #endif    
  17.     OS_ENTER_CRITICAL();            //关闭中断    
  18.     if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { //确认优先级未被使用,即就绪态为0    
  19.         OSTCBPrioTbl[prio] = (OS_TCB *)1;    //保留这个优先级,将就绪态设为1    
  20.                                                 
  21.         OS_EXIT_CRITICAL();             //打开中断    
  22.         psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0);    //初始化任务堆栈    
  23.         err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);       //获得并初始化任务控制块    
  24.         if (err == OS_NO_ERR) {     //任务控制初始化成功    
  25.             OS_ENTER_CRITICAL();    //关闭中断    
  26.             OSTaskCtr++;            //任务计数器加1    
  27.             OS_EXIT_CRITICAL();     //打开中断    
  28.             if (OSRunning == TRUE) {         //检查是否有(某个)任务在运行    
  29.                 OS_Sched();                  //任务调度,最高任务优先级运行    
  30.             }    
  31.         } else {        //否则,任务初始化失败    
  32.             OS_ENTER_CRITICAL();        //关闭中断    
  33.             OSTCBPrioTbl[prio] = (OS_TCB *)0;       //放弃任务,设此任务就绪态为0    
  34.             OS_EXIT_CRITICAL();                     //打开中断    
  35.         }    
  36.         return (err);           //返回(获得并定义初始化任务控制块是否成功)    
  37.     }    
  38.     OS_EXIT_CRITICAL();         //打开中断    
  39.     return (OS_PRIO_EXIST);     //返回(具有该优先级的任务已经存在)    
  40. }    
  41. #endif    

OSTaskCreate函数源码解析

    OSTaskCreate()一开始先检测分配给任务的优先级是否有效[L4.1(1)]。任务的优先级必须在0到OS_LOWEST_PRIO之间。接着,OSTaskCreate()要确保在规定的优先级上还没有建立任务[L4.1(2)]。在使用UC/OS-Ⅱ时,每个任务都有特定的优先级。如果某个优先级是空闲的,UC/OS-Ⅱ通过放置一个非空指针在OSTCBPrioTbl[]中来保留该优先级[L4.1(3)]。这就使得OSTaskCreate()在设置任务数据结构的其他部分时能重新允许中断[L4.1(4)]。 

然后,OSTaskCreate()调用OSTaskStkInit()[L4.1(5)],它负责建立任务的堆栈。该函数是与处理器的硬件体系相关的函数,可以在OS_CPU_C.C文件中找到。有关实现OSTaskStkInit()的细节可参看第8章——移植UC/OS-Ⅱ。如果已经有人在你用的处理器上成功地移植了UC/OS-Ⅱ,而你又得到了他的代码,就不必考虑该函数的实现细节了。OSTaskStkInit()函数返回新的堆栈栈顶(psp),并被保存在任务的0S_TCB中。注意用户得将传递给OSTaskStkInit()函数的第四个参数opt置0,因为OSTaskCreate()与OSTaskCreateExt()不同,它不支持用户为任务的创建过程设置不同的选项,所以没有任何选项可以通过opt参数传递给OSTaskStkInit()。

UC/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的数据单元。

OSTaskCreateExt函数源码

  1. //建立一个新任务。与OSTaskCreate()不同的是,OSTaskCreateExt()允许用户设置更多的细节    
  2. //内容。任务的建立可以在多任务环境启动之前,也可以在正在运行的任务中建立,但中断处理    
  3. //程序中不能建立新任务。一个任务必须为无限循环结构,且不能有返回点。    
  4. #if OS_TASK_CREATE_EXT_EN > 0                //允许生成OSTaskCreateExt()函数    
  5. INT8U  OSTaskCreateExt (void   (*task)(void *pd),   //建立扩展任务(任务代码指针)    
  6.                         void    *pdata,             //传递参数指针    
  7.                         OS_STK  *ptos,              //分配任务堆栈栈顶指针    
  8.                         INT8U    prio,              //分配任务优先级    
  9.                         INT16U   id,                //(未来的)优先级标识(与优先级相同)    
  10.                         OS_STK  *pbos,              //分配任务堆栈栈底指针    
  11.                         INT32U   stk_size,          //指定堆栈的容量(检验用)    
  12.                         void    *pext,              //指向用户附加的数据域的指针    
  13.                         INT16U   opt)               //建立任务设定选项    
  14. {    
  15. #if OS_CRITICAL_METHOD == 3                  //中断函数被设定为模式3    
  16.     OS_CPU_SR  cpu_sr;    
  17. #endif    
  18.     OS_STK    *psp;                         //初始化任务堆栈指针变量,返回新的栈顶指针    
  19.     INT8U      err;                         //定义(获得定义初始化任务控制块)是否成功    
  20.     
  21.     
  22. #if OS_ARG_CHK_EN > 0        //所有参数必须在指定的参数内    
  23.     if (prio > OS_LOWEST_PRIO) {             //检查任务优先级是否合法    
  24.         return (OS_PRIO_INVALID);            //参数指定的优先级大于OS_LOWEST_PRIO    
  25.     }    
  26. #endif    
  27.     OS_ENTER_CRITICAL();        //关闭中断    
  28.     if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { //确认优先级未被使用,即就绪态为0    
  29.         OSTCBPrioTbl[prio] = (OS_TCB *)1;    //保留这个优先级,将就绪态设为0    
  30.                                                  
  31.         OS_EXIT_CRITICAL();     //打开中断    
  32.     
  33.         //以下两为1堆栈才能清0    
  34.         if (((opt & OS_TASK_OPT_STK_CHK) != 0x0000) ||   //检验任务堆栈,CHK=1    
  35.             ((opt & OS_TASK_OPT_STK_CLR) != 0x0000)) {   //任务建立时是否清0,CLR=1    
  36.             #if OS_STK_GROWTH == 1          //堆栈生长方向    
  37.             (void)memset(pbos, 0, stk_size * sizeof(OS_STK));       //从下向上递增    
  38.             #else    
  39.             (void)memset(ptos, 0, stk_size * sizeof(OS_STK));       //从下向下递减    
  40.             #endif    
  41.         }    
  42.     
  43.         psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, opt);      //初始化任务堆栈    
  44.         err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);     //获得并初始化任务控制块    
  45.         if (err == OS_NO_ERR) { //任务控制初始化成功    
  46.             OS_ENTER_CRITICAL();        //关闭中断    
  47.             OSTaskCtr++;                //任务计数器加1    
  48.             OS_EXIT_CRITICAL();         //打开中断    
  49.             if (OSRunning == TRUE) {              //检查是否有(某个)任务在运行    
  50.                 OS_Sched();                       //任务调度,最高任务优先级运行    
  51.             }    
  52.         } else {        //否则,任务初始化失败    
  53.             OS_ENTER_CRITICAL();        //关闭中断    
  54.             OSTCBPrioTbl[prio] = (OS_TCB *)0;                 //放弃任务,设此任务就绪态为0    
  55.             OS_EXIT_CRITICAL();         //打开中断    
  56.         }    
  57.         return (err);       //返回(获得并定义初始化任务控制块是否成功)    
  58.     }    
  59.     OS_EXIT_CRITICAL();     //打开中断    
  60.     return (OS_PRIO_EXIST);     //具有该优先级的任务已经存在    
  61. }    
  62. #endif    


http://blog.csdn.net/liuhui_8989/article/details/8781407

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196872.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • mysql时序性数据库_时序数据库入门[通俗易懂]

    mysql时序性数据库_时序数据库入门[通俗易懂]数据库的模型包含关系型、key-value型、Document型等很多种,那么为什么新型的时序数据库成为监控数据存储的新宠呢?下面就会从为什么需要时序数据库?时序数据库的数据结构两个方面来介绍一下时序数据库。1.为什么需要时序数据库1.1时序数据特点时序数据有如下几个特点:基本上是插入操作较多且无更新的需求数据带有时间属性,且数据量随着时间递增插入数据多,每秒钟插入需要可到达千万甚至是上…

    2022年10月5日
    1
  • python解析json文件

    python解析json文件认识json数据json有两种数据结构:对象和数组。对象:用大括号表示,由键值对组成,每个键值对用逗号隔开。其中key必须为字符串且是双引号,value可以是多种数据类型。数组:用中括号表示,每个元素之间用逗号隔开。json中的字符串都要用双括号表示。json数据可以嵌套表示出结构更加复杂的数据。json格式与python格式的对应Python JSONd…

    2022年9月25日
    0
  • 要引入java吸管工具[通俗易懂]

    要引入java吸管工具

    2022年1月17日
    42
  • Struts2运行错误:Error filterStart

    Struts2运行错误:Error filterStart困扰我近10多天的问题,让我在框架功力修炼上几乎停滞不前,今天问题被KO,小小的高兴下。 纯洁的web.xml文件struts2org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterstruts2/*

    2022年7月11日
    10
  • Python打包exe,以及解决闪退

    Python打包exe,以及解决闪退Python打包exe打开终端,中输入命令pipinstallpyinstaller后回车。安装失败尝试用管理员方式打开输入命令pyinstaller,回车显示安装成功。3.打开pycharm的底部的【Terminal】输入:pyinstaller–console–onefile······.py,或者在路径下按住shift右键单击空白打开powershel…

    2022年5月18日
    48
  • Ubuntu 18.04 浏览器安装flash[通俗易懂]

    flash官网(注意下载和系统浏览器相对应的包)PPAPI:供Opera(15以上)、Chromium(开源谷歌)浏览器使用NPAPI:适用于FireFox(火狐)、Safari(苹果)、Opera(欧朋,12.17版以下)然后解压:tar-zxvfflash_player_npapi_linux.x86_64.tar.gz复制:sudocplibflashplay…

    2022年4月12日
    64

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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