任务管理机制二

本文是为了续前面的任务管理机制的。

六.内部任务

在uC/OS-III 初始化的时候,它会创建至少2 个内部的任务(OS_IdleTask()和OS_TickTask()),3 个可选择的任务(OS_StatTask(),OS_TmrTaks(),OS_IntQTask())。这些可选择的任务在编译时由OS_CFG.H 中的配置决定。
1空闲任务 OS_IdleTask()
OS_IdleTask()是uC/OS-III 最先创建的任务。它的优先级通常是OS_CFG_PRIO_MAX-1。事实上,为了安全,它应该独占这个优先级。在其他任务创建的时候,OSTaskCreate()会确保他们不会跟空闲任务有相同的优先级。当CPU 中没有其它就绪任务运行时,空闲会被运行。空闲任务的重要部分代码如下
void  OS_IdleTask (void  *p_arg)
{
    CPU_SR_ALLOC();






    p_arg = p_arg;                                          /* Prevent compiler warning for not using 'p_arg'         */


    while (DEF_ON) {
        CPU_CRITICAL_ENTER();
        OSIdleTaskCtr++;
#if OS_CFG_STAT_TASK_EN > 0u
        OSStatTaskCtr++;
#endif
        CPU_CRITICAL_EXIT();


        OSIdleTaskHook();                                   /* Call user definable HOOK                               */
    }
}
这是空闲任务是一个无限循环的不会等待任何事件的任务。这是因为,在大部分的处理器中,当没有事情可做时,处理器依然会执行指令。当uC/OS-III 中没有其它更高的就绪任务待运行时,uC/OS-III就会把CPU 分配给空闲任务。
空闲任务运行时,两个计数变量会递增。OSIdleTaskCtr 是用32 位无符号整数定义的,在uC/OS-III 初始化的时候它的值被复位。它用于表示空闲任务的活动情况。换句话说,如果用调试器查看该变量,就会看到介于0x00000000 和0xffffffff 之间的数。OSIdleTaskCtr 的增长速度取决于CPU 的空闲情况。CPU 越空闲,该值增长越快。OSStatTaskCtr 是用32 位无符号整数定义的,提供给测量任务测量CPU 的利用率。
空闲任务的每次循环,都会调用OSIdleTaskHook()函数,这个函数提供给用户扩展应用。在这个函数中不要编写会让空闲任务被挂起的代码,对于uC/OS-III 移植者来说这是一个常识。OSIdleTaskHook()可以编写使CPU 处于低功耗的代码。然而,这样的话就意味着OSStatTaskCtr 不能再用于测量CPU 的使用率了。 通常情况下,当中断发生时处理器退出低功耗模式。ISR 中可能会设置某些寄存器恢复CPU 速度为全速或其想要的速度。ISR 可以唤醒了一个高优先级任务(每个任务的优先级都比空闲任务的优先级高),然后ISR 不会返回到空闲任务,而是切换到这个高优先级任务。如果这个任务完成操作或者挂起,uC/OS-III 就会切换到空闲任务并进入OSIdleTaskHook()并进入低功耗模式。然后,进入OS_IdleTask()并循环。
2时基任务 OS-TickTask()
几乎所有的实时系统都需要有一个能提供周期性时间的时间源,叫做时基周期或系统周期。uC/OS-III 的时基周期处理程序封装在OS_TICK.C 文件中。OS_TickTask()任uC/OS-III 创建,其优先级是用户可配置的。(通过配置OS_CFG_APP.H 中的OS_CFG_TICK_TASK_PRIO)。通常设置其优先级较高。事实上,它的优先级应该设置比重要任务的优先级稍低。OS_TickTask()用于追踪等待期满的任务、挂起超时的任务。OS_TickTask()是一个周期性任务,它等待来自于ISR 的信号量。




太复杂,后面再谈
3统计任务OS_StatTask()
这个任务能够统计总的CPU 使用率(0 到100%),每个任务的CPU使用率(0 到100%),每个任务的堆栈使用量。统计任务在uC/OS-III 中是可选的,当设置OS_CFG.H 中的
OS_CFG_STAT_TASK_EN 为1 时,统计任务的代码会被包含在程序中。当然,统计任务的优先级和它的任务堆栈大小在OS_CFG_APP.H中配置。最好在main()中只创建的一个任务,通常叫做AppTaskStat(),当使能了统计任务时,就必须在AppTaskStat 任务中首先调用OSStatTaskCPUUsageInit()。如下图所示。在调用OSStart()之前,用户的启动代码只能创建一个任务,而是由这个任务创建其它任务。
(1)CPU 进入main()函数中。
(2)main()函数调用OSInit()初始化uC/OS-III。假定在OS_CFG_APP.H 中设置OS_CFG_STAT_TASK_EN 为1,使能统计任务。通过uC/OS-III 返回的错误代号检测系统初始化是否成功。(详见OS.H 中的错误代号OS_ERR_???)。
(3)创建一个叫做AppTaskStart()的任务。创建这个任务的时候,给它一个相当高的优先级(不要用优先级0,因为这是为uC/OS-III保留的)。uC/OS-III 允许用户在调OSStart()之前创建任意个任务。然而,当用到统计任务统计CPU 的使用率时,调用OSStart()之前只能创建一个任务。
(4)调用OSStart(),让uC/OS-III 开始运行优先级最高的任务,根据例子,这个任务是AppTaskStart()。在这个时候,已经有五个任务被创建了:OS_IdleTask(),OS_TickTask(),OS_StatTask(),OS_TaskTmr(),AppTaskStart()。
(5)这个任务应该先设置和开启时基中断,初始化用于时基时钟的硬件定时器,设置其中断的速率。(编译时设置OS_CFG_APP.H中的OS_CFG_STAT_TASK_RATE)。另外,Micrium 提供的例子工程中包含了基本的板级支持包BSP。BSP 初始化了CPU 很多方面的也包括uC/OS-III 需要的周期时间源。如果需要,用户可以在开启任务中调用BSP_Init()初始化BSP 服务。
(6)调用OSStatTaskCPUUsageInit()。当没有其它应用任务运行时,经过1/OS_CFG_STAT_TASK_RATE 秒后OSStatTaskCtr 的计数值就是OSStatTaskCtr 的最大值,它意味着CPU 的空闲时的工作速率。
例如,如果系统中不包含应用任务,OSStatTaskCtr 从0 开始计数到10,000,000 用了1/OS_CFG_STAT_TASK_RATE 秒。添加了应用任务后,OSStatTaskCtr 每1/OS_CFG_STAT_TASK_RATE 秒检测一次。得到的值不会达到10,000,000。CPU 的利用率如下计算:
CPU 利用率%=(100-100 *OSTaskStatCtr/OSTaskStatCtr(max))如果重新测得的OSStatTaskCtr 值为7,500,000。那么CPU 的利用率为25%。
25%=(100-100*7500000/10000000)
(7)然后在AppTaskStart()创建其它的应用任务。正如先前描述的,uC/OS-III 将任务的CPU 使用率存于任务的TCB。OS_OS_StatTask()也可以计算每个任务堆栈的使用量(通过调用OSTaskStkChk())。并将计算结果存于每个任务OS_TCB 的StkFree和StkUsed 中
4 定时器任务 OS_TmrTask()
{这节所说的定时器都是软件定时器}
uC/OS-III 为用户提供了定时器任务,相应代码在OS_TMR.C 中。定时器任务是可选的,通过将OS_CFG.H 中的OS_CFG_TMR_EN设置为1 使能。当设置为1 时,它的代码才会被添加到最终代码中。
当定时器任务递减计数变量到0 时,任务中就会调用回调函数。回调函数是一个函数,它被用户定义。因此,回调函数可以用来开启或关闭LED、电机、或者其他的一些操作。用户可以创建任意个定时器(只限制于处理器的RAM)。定时器管理在12 章详细介绍。OS_TmrTask()是一个被uC/OS-III 创建的任务(假定设置OS_CFG.H 中的OS_CFG_TMR_EN 为1),它通过OS_CFG_APP.H中的OS_CFG_TMR_TASK_PRIO 设置优先级。一般情况下,它的优先级被设为中等。
OS_TmrTask()是周期函数。中断源产生时基。然而,定时器通常需要较低的率(典型为10Hz),可以通过软件将时基分频。换句话说,如果时基速率为1000Hz,但是想要的定时器速率为10Hz,定时器任务会每100 个时基被标记一次。
5 中断处理任务 OS_IntQTask()
当设置OS_CFG.H 中的OS_CFG_ISR_POST_DEFERRED_EN 为1 时,uC/OS-III 就会创建一个任务,它的作用是尽快完成ISR 中对post 函数的调用,将信号量、消息等对象先存在媒介中,退出中断后,由中断处理任务完成将这些对象提交给任务。
正如第4 章“临界段”所介绍的,uC/OS-III 通过开启/关闭中断、锁/开锁调度器管理临界段。如果选择后一种方法,ISR 调用的post函数不允许直接访问就绪列表、挂起队列等。当ISR 调用uC/OS-III 提供的post 函数时,ISR 要提交的数据会被复制,该数据的目的地会被放到一个特殊的队列—"holding"队列。当所有的嵌套中断结束时,uC/OS-III 切换到中断处理任务,它会将放置在"holding"队列中的信息重新提交到适当的任务OS_IntQTak()被uC/OS-III 创建,它的优先级通常被设为0(最高优先级)。如果OS_CFG_ISR_POST_DEFERRED_EN 被设置为1,使能了这个任务,其它的任务的优先级就不能设置为0。


7总结

任务是一段简单的程序。在单CPU 系统中,任何时间只能有一个任务被CPU 运行。uC/OS-III 支持多任务并对任务数没有限制(仅限制于CPU 的存储空间,包括代码空间和数据空间)。uC/OS-III 创建五个内部任务:空闲任务,时基任务,中断处理任务,统计任务,定时器任务。空闲任务、时基任务是必须的,统计任务、定时器任务、中断处理任务是可选择的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值