请选择 进入手机版 | 继续访问电脑版
快捷导航
0 89

μcos 任务管理+时间管理 学习笔记

晏慧茹 于 2017-12-19 17:00 发表在 [技术分享] [复制链接]
本帖最后由 晏慧茹 于 2017-12-20 07:55 编辑

引言:μcos中最多可以支持64 个任务,分别对应优先级0~63,其中0 为最高优先级。63为最低级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所有用户可以使用的任务数有56个。
     μcos提供了任务管理的各种函数调用,包括创建任务,删除任务,改变任务的优先级,任务挂起和恢复等。
    系统初始化时会自动产生两个任务:一个是空闲任务,它的优先级最低,改任务仅给一个整形变量做累加运算;另一个是系统任务,它的优先级为次低,改任务负责统计当前cpu的利用率。


一、任务管理
1.建立任务的函数
   OSTaskCreate() 和 OSTaskCreateExt()   (提供了附加功能)
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
参数:task:任务函数指针,pdata:任务开始执行时传递给任务的参数的指针,ptos:分配给任务的堆栈的栈顶指针,prio:分配给任务的优先级


2.任务堆栈
a.静态分配堆栈
   static OS_STK  TaskStack[stack_size]; 或  OS_STK  TaskStack[stack_size];
b.动态分配堆栈
   OS_STK  *pstk;
   pstk = (OS_STK *)malloc(stack_size);
   if (pstk != (OS_STK *)0)    /* 确认malloc()能得到足够地内存空间 */
   {               
       Create the task;
   }

注:堆栈必须声明为OS_STK类型,并且由连续的内存空间组成。

3.任务删除
   OSTaskDel(INT8U prio)不安全,可能会导致任务占用的资源没有释放。
   OSTaskDelReq(INT8U prio)该函数通过任务控制块中的OSTCBDelReq作为请求删除方和被删除方的联络信号。


4.改变任务优先级
   OSTaskChangePrio()

5.挂起任务
  OSTaskSuspend(),有时候将任务挂起是很有用的。挂起任务可通过调用 OSTaskSuspend()函数来完成。被挂起的任务只能通过调用 OSTaskResume()函数来恢复。

6.恢复任务  
   OSTaskResume()是通过清除 OSTCBStat 域中的OS_STAT_SUSPEND 位来取消挂起的。要使任务处于就绪状态,OS_TCBDly 域必须为 0,这是因为在 OSTCBStat 中没有任何标志表明任务正在等待延时的期满。只有当以上两个条件都满足的时候,任务才处于就绪状态。最后,任务调度程序会检查被恢复的任务拥有的优先级是否比调用本函数的任务的优先级高。

7.获得有关任务的信息  
   OSTaskQuery()获得的是对应任务的 OS_TCB 中内容的拷贝。


二、延时函数                 
1.时延函数   
   OSTimeDly()  延时时间用时钟节拍的数目来确定的;

  1. void OSTimeDly (INT16U ticks)
  2. {
  3.     if (ticks > 0) {
  4.         OS_ENTER_CRITICAL();
  5.         if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) {
  6.             OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
  7.         }   

  8.         OSTCBCur->OSTCBDly = ticks;
  9.         OS_EXIT_CRITICAL();
  10.         OSSched();
  11.     }
  12. }
复制代码
   

                        (此为系统延时函数OSTimeDly()调用图解)

OSTimeDlyHMSM()  延时时间由具体定义的时间确定的;


  1. INT8U OSTimeDlyHMSM (INT8U hours, INT8U minutes, INT8U seconds, INT16U
  2. milli)
  3. {
  4.     INT32U ticks;
  5.     INT16U loops;
  6.     if (hours > 0 || minutes > 0 || seconds > 0 || milli > 0) {

  7.         if (minutes > 59) {
  8.             return (OS_TIME_INVALID_MINUTES);
  9.         }
  10.         if (seconds > 59) {
  11.             return (OS_TIME_INVALID_SECONDS);
  12.         }
  13.         If (milli > 999) {
  14.             return (OS_TIME_INVALID_MILLI);
  15.         }

  16.         ticks = (INT32U)hours
  17.         * 3600L * OS_TICKS_PER_SEC
  18.         + (INT32U)minutes * 60L * OS_TICKS_PER_SEC
  19.         + (INT32U)seconds * OS_TICKS_PER_SEC
  20.         + OS_TICKS_PER_SEC * ((INT32U)milli
  21.         + 500L/(OS_TICKS_PER_SEC) / 1000L;

  22.         loops = ticks / 65536L;
  23.         ticks = ticks % 65536L;
  24.         OSTimeDly(ticks);

  25.         while (loops > 0) {
  26.             OSTimeDly(32768);
  27.             OSTimeDly(32768);
  28.             loops--;
  29.         }

  30.         return (OS_NO_ERR);
  31.     } else {
  32.         return (OS_TIME_ZERO_DLY);
  33.     }
  34. }
复制代码
    注:任务调用OSTimeDly()后,一旦规定的时间期满或者有其它的任务通过OSTimeDlyResume()取消了延迟,它就会马上进入就绪态,而不是执行状态,也就是说延时结束后本任务一定不会被立刻执行。


2.系统时间
  每次发生时钟节拍时,UCOS都会将一个32位的计数器加1。OSTimeGet()和 OSTimeSet()用来获取或者设置这个计数器的值。


  上图说明了如何通过OSTimeGet()函数得到当前的系统时钟节拍:ticks = OSTimeGet();来实现。




总结:主要就是了解任务管理和时间管理常用的函数及其函数的功能。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
Connecting & Messaging from Any.

共 0 个关于本帖的回复 最后回复于 2017-12-19 17:00

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

推荐板块

精彩推荐

热门排行

明星用户

手机版|小黑屋|AnyMSG ( ©AnyMSG 2009 - 2017 · ICP备16009991号 )

GMT+8, 2019-4-25 22:42