第4章第6节 任务自结束


目前更新到5.3节,请在
http://dl.dbank.com/c02ackpwp6下载5.3节的全部文档

本节源代码请在http://dl.dbank.com/c0ss54iddw下载

 

 

第6节 任务自结束

上节增加了删除任务的函数MDS_TaskDelete,任务可以调用该函数结束其它任务或自身任务的运行。在前面章节我们说过,目前任务还不具备自结束功能,需要使用类似while的结构循环运行。本节我们将增加任务自结束功能,在创建任务时不再受任何限制。

 

任务要做到自结束,需要解决2个问题,一,任务需要能脱离操作系统的调度。二、任务在结束后,操作系统需要能发生调度,切换到下个任务继续运行。

2个问题我们都可以像上节那样,调用MDS_TaskDelete函数解决,但如果使用MDS_TaskDelete函数来实现任务的自结束,那么MDS_TaskDelete函数就必须以显式的方式写在每个任务主函数的最后一行,当任务运行到结束时,任务会运行MDS_TaskDelete函数结束自身的运行。这样做有一个明显的缺点,我们需要为每个任务增加这样一行代码,不但对用户进行了约束,使用不方便,而且如果用户忘记了增加这行代码,那么操作系统运行到任务结束后就会崩溃掉。

 

前面我们介绍过,LR寄存器中保存的是本函数返回上级父函数的PC指针,返回父函数时只要跳转到该PC指针就可以了。如果我们要做到任务自删除,那么就可以借用这个功能,可以将MDS_TaskDelete函数认为是每个创建任务所使用的主函数的父函数,在任务初始化时,将MDS_TaskDelete函数的地址赋给LR寄存器,这样当任务运行完最后一条指令时,它就会取出LR寄存器中的MDS_TaskDelete函数的地址,跳转到MDS_TaskDelete函数,实现任务的自结束功能。这种方式是隐式的,不会对用户做任何限制,只需要我们修改MDS_TaskStackInit函数代码,增加对LR寄存器的初始化就可以一劳永逸了。

00011  void MDS_TaskStackInit(M_TCB* pstrTcb, VFUNC vfFuncPointer)

00012  {

00013  

……   ……

00032  

00033      pstrRegSp->uiR14 (U32)MDS_TaskSelfDelete; 

00034  

……   ……

00043  

00044  }

MDS_TaskStackInit函数的改动量非常小,只需要在33行将MDS_TaskSelfDelete函数赋给LR寄存器。MDS_TaskSelfDelete函数封装了MDS_TaskDelete函数,将存放当前指针的全局变量gpstrCurTcb传给MDS_TaskDelete函数,完成任务的自删除。

00191  void MDS_TaskSelfDelete(void)

00192  {

00193      (void)MDS_TaskDelete(gpstrCurTcb);

00194  }

 

本节的改动已经介绍完毕,本节的验证函数与上节非常相似,其中TEST_TestTask1TEST_TestTask2函数与上节完全一样,TEST_TestTask3函数修改为只循环6次,每次循环时间为1000 ticks。由于TEST_TestTask3函数具有最高优先级,并且在开始时delay2000 ticks,因此它会在8000 ticks时运行完毕,按照本节的设计,在8000 ticks时它应该会自结束运行,由任务删除钩子函数打印出任务删除的信息。

00053  void TEST_TestTask3(void)

00054  {

00055      U8 i;

00056  

00057      

00058      for(i 0; 6; i++)

00059      {

00060          DEV_PutStrToMem((U8*)"\r\nTask3 is running! Tick is: %d",

00061                          MDS_SystemTickGet());

00062  

00063          DEV_DelayMs(5000);

00064  

00065          (void)MDS_TaskDelay(500);

00066      }

00067  }

 

除此之外root任务也不需要再调用MDS_TaskDelete函数自我删除,也是由本节新增加的隐式删除方式进行自删除。

00014  void MDS_RootTask(void)

00015  {

00016      M_TASKOPT strOption;

00017  

00018      

00019      DEV_SoftwareInit();

00020  

00021      

00022      DEV_HardwareInit();

00023  

00024      

00025      (void)MDS_TaskCreate((U8*)"Test1", (VFUNC)TEST_TestTask1, gaucTask1Stack,

00026                           TASKSTACK, 2, (M_TASKOPT*)NULL);

00027  

00028      

00029      strOption.ucTaskSta TASKREADY;

00030      (void)MDS_TaskCreate((U8*)"Test2", (VFUNC)TEST_TestTask2, gaucTask2Stack,

00031                           TASKSTACK, 3, &strOption);

00032  

00033      

00034      strOption.ucTaskSta TASKDELAY;

00035      strOption.uiDelayTick 2000;

00036      (void)MDS_TaskCreate((U8*)"Test3", (VFUNC)TEST_TestTask3, gaucTask3Stack,

00037                           TASKSTACK, 1, &strOption);

00038  

00039      (void)MDS_TaskDelay(10000);

00040  

00041      

00042  

00043  }

本节运行结果截图如下:

第4章第6节 <wbr>任务自结束

图 50  任务自删除的打印信息

读者可以访问http://blog.sina.com.cn/ifreecoding网站下载视频,观看全部数据的打印过程,

 

可以看到本节实际运行打印出的结果与我们上节的实际运行打印出的结果是一致的,这也是与我们设计相符的,但这里还是有一点稍微的不同,见图51

第4章第6节 <wbr>任务自结束

图 51  任务被删除与自删除的打印信息对比

51左边是上节打印输出的数据,右边是本节打印输出的数据,这两组数据对比的结果如图51所示,只有9092行的结果不同。上节当系统运行到8000 ticks时,root任务delay时间耗尽,恢复到running状态,删除了TEST_TestTask3任务,之后又重新进入delay状态,将CPU控制权让给了TEST_TestTask2任务。而本节TEST_TestTask3任务先是delay2000ticks,然后运行了6for循环,6for循环后,系统时间为8000 ticksTEST_TestTask3任务运行结束,自己结束了运行,将CPU控制权让给了TEST_TestTask2任务,因此本节删除TEST_TestTask3任务的操作是在TEST_TestTask3任务中完成的,只有这点与上节在root任务中删除TEST_TestTask3任务是不同的。

 

51的截图是Beyond Compare工具软件的截图,Beyond Compare是一比较文件和文件夹的工具它可以比较出不同源代码文件之间的细微差别并标记出来,即使你在成千上万行代码中只修改了1个字符,它也会发现并标记出来,这对于软件的维护有着非常重要的意义。

 

使用工具软件解析本节任务切换过程的数据,结果如下图所示:

第4章第6节 <wbr>任务自结束

图 52  4.6节任务切换过程图

对比上节中任务切换过程的图49,可以明显的看出在8000 ticks时,本节是切换到了TEST_TestTask3任务,而上节是切换到了root任务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
将《底层工作者手册之C语言基础及项目开发》改名为《底层开发者手册之C语言基础及项目开发》,并做了一些修改,更新到2.4.5。不过其中有一些还没有写完。先凑合看吧   《C》这本手册是《底层开发者手册》系列的第二本,但它却是我第一个开始写的,早在2008年年底时我就开始着手写这本手册,但写了没多久就因为发生了一个意外而终止了。在2010年年初的时候我开始了第四本手册的写作——嵌入式操作系统内核,目前已接近完工状态(我的博客可以下载,blog.sina.com.cn/ifreecoding),现在我又回过头来重新写《C》这本手册,将会采用与《嵌》一样的方式,写一部分就在网上发布一部分,在这同时我又在收集第一本和第三本手册的材料,准备将这4本手册同时写完,使读者可以按照顺序阅读这4本手册,层层深入底层开发者的工作。   一个良好的C语言基础是编写嵌入式设备底层代码的必要条件,如今介绍C语言的书不少,介绍嵌入式C的书也不少,但几乎没有结合实际项目来介绍C语言的,看完这样的书,C语言会用了,但做出来的产品只能称之为中国校园式产品,为求实现功能不择手段,根本不适合在项目中使用。另有一些自称C语言精华的书或网上的面试宝典,尽是讲一些偏题怪题,这可能满足了作者的虚荣心,但却在将新手引向一个错误的方向。当然,仁者见仁智者见智,这仅是我个人的观点,也一定会被他人所反驳的,正是出现百家争鸣的局面社会才能进步。   本手册分为2部分,第一部分介绍C语言基础,在介绍C基础时会结合嵌入式中的应用加以介绍,将重点介绍在项目开发中有用的内容,对于过分追求技术但又没有什么实际用处的内容不做过多的介绍,对于这些内容最多会提一下,让读者知道有这种情况存在。第二部分介绍项目开发,从项目需求、分析、设计、编码、测试、维护的角度来介绍编写代码。记住,编码只是项目中的一个部分,在中国校园式产品中这可能几乎就是全部了,但在一个可以称之为产品的项目中,它只是一部分,并且项目越大它所占的比重越小。   我在看书学习新知识时,希望看到的是那些写的多一些详细一些,也就是废话多一些的书,可以傻瓜式的一步步跟下来,不希望看到那些对关键之处一笔带过还故作高深的书,所以本手册就以废话多为原则,可能会写的罗嗦一些,只求能看的明白一些。当然,本人知识水平有限,有些知识会有理解上的错误,或者有未触及的地方,错误一定是有的,就像做产品一样,不可能没有错误。我写本手册的目的在于分享我的知识,注重实际应用,这对某一论坛上的某些只会空谈经验、分析汉字语法的理想C语言文艺专家们来说可能会不屑一顾。如有问题,请登录我的博客blog.sina.com.cn/ifreecoding反馈,我虚心接受,但我拒绝那些假大空的为了批评而批评的建议。我们做项目不是写论文,是实实在在的东西!   为新手写一本介绍C语言的书很难,因为它牵涉到非常多的知识作为基础,其中的一些知识很可能需要使用另外几本书的篇幅来介绍,而且知识是耦合在一起的,在介绍前面的时候会涉及到后面的知识,对于新手来说,没有对C形成一个全貌,无法理解。因此给新手的建议是只能多看几遍,第一遍大致看看,掌握全貌,不要细读,然后再多读几遍,仔细分析各种问题,并结合例子,自己动手编程,调试,这个过程非常重要,一定要自己动手编程,光看是没有用的,只有自己动手解决了问题,才能从根本上理解问题。 C语言入门可能会比较容易,但不要指望几个月时间就能熟练掌握C语言,如果做底层编码的话则需要以年为单位来衡量。
Mindows操作系统更新5.1~5.3,将wanlix从ARM7内核移植到cortex内核,更多资料请登陆www.ifreecoding.com下载。 前面基础知识介绍完毕,本开始真刀真枪的移植代码了。本将Wanlix3.3的代码从ARM7内核移植到TI和ST的cortex内核的芯片上,移植完成后通过串口打印可以看到移植的效果。 如果你有STM32的板子,现在就可以跑! /***************************************************************************/ Wanlix是一个内核非常小的嵌入式操作系统,只有几百个字,但功能少,只提供任务切换功能,非常适合资源特别少但又需要任务切换的小项目。 Mindows可提供多种操作系统功能,是实时抢占式操作系统,任务支持多种优先级抢占调度,将实时性高的任务设置为高优先级就可以保证软件系统的实时性,用户也可根据自身需求选取需要的部分,也可在此基础上编写代码增加自己需要的功能,具有可裁剪性。 我将Wanlix和Mindows的开发过程记录下来,就形成了这本“底层工作者手册之嵌入式操作系统内核”一书,本手册不仅仅是从应用的角度介绍操作系统如何使用,更重要的是从原理的角度对操作系统的功能做了分析、设计,从无到有循序渐进一点点的增加操作系统的功能,并且每增加一个功能便配以一个例子加以演示,让读者能立刻看到代码运行的结果。 本手册记录了我从对操作系统内核不了解到写出操作系统内核的过程,这样的一个过程对你来说应该也是一个最好的学习过程。 如果你有一定的C语言基础,并且对硬件也有稍微的了解,那么我相信你一定会看明白本手册!也一定可以随心所欲的修改、扩展你需要的操作系统功能! 请登陆www.ifreecoding.com获取更多资料 /***************************************************************************/
Mindows操作系统更新到4.4看,增加任务任务切换钩子功能,更多资料请登陆www.ifreecoding.com下载。 Wanlix是一个内核非常小的嵌入式操作系统,只有几百个字,但功能少,只提供任务切换功能,非常适合资源特别少但又需要任务切换的小项目。 Mindows可提供多种操作系统功能,是实时抢占式操作系统,任务支持多种优先级抢占调度,将实时性高的任务设置为高优先级就可以保证软件系统的实时性,用户也可根据自身需求选取需要的部分,也可在此基础上编写代码增加自己需要的功能,具有可裁剪性。 我将Wanlix和Mindows的开发过程记录下来,就形成了这本“底层工作者手册之嵌入式操作系统内核”一书,本手册不仅仅是从应用的角度介绍操作系统如何使用,更重要的是从原理的角度对操作系统的功能做了分析、设计,从无到有循序渐进一点点的增加操作系统的功能,并且每增加一个功能便配以一个例子加以演示,让读者能立刻看到代码运行的结果。 本手册记录了我从对操作系统内核不了解到写出操作系统内核的过程,这样的一个过程对你来说应该也是一个最好的学习过程。 如果你有一定的C语言基础,并且对硬件也有稍微的了解,那么我相信你一定会看明白本手册!也一定可以随心所欲的修改、扩展你需要的操作系统功能! 请登陆www.ifreecoding.com获取更多资料
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值