uC/OS-III之系统内部任务

1.uC/OS-III系统内部有提供了5个任务:空闲任务、时钟节拍任务、统计任务、中断服务管理任务和定时器任务。其中空闲任务和时钟节拍任务是必须创建的,而统计任务、定时器任务和中断服务管理任务是可选的。

2.空闲任务(OS_IdleTask()、os_core.c)
空闲任务是系统必须创建的。当其他所有的任务都未就绪时,就需要运行它。
(1)优先级–它的优先级比较特殊,总是设置为OS_CFG_PRIO_MAX-1,所以其他的任务就不能设置为该优先级
(2)栈大小–在os_cfg_app.h文件中定义,如果有需要的话可以更改它的大小

#define  OS_CFG_IDLE_TASK_STK_SIZE        64u

(3)空闲任务的源代码位于os_core.c文件的748行,如下所示:

void  OS_IdleTask (void *p_arg)
{
    CPU_SR_ALLOC();            // 声明变量cpu_sr,临时存储CPU的状态寄存器的值

    p_arg = p_arg;
    while (DEF_ON) {
        CPU_CRITICAL_ENTER();  // 进入临界区
        OSIdleTaskCtr++;       // 表示空闲任务的活跃度,它的递增的速度表示CPU执行应用代码的繁忙程度。递增越快,表示执行与应用相关的任务所花费的时间越少
#if OS_CFG_STAT_TASK_EN > 0u
        OSStatTaskCtr++;       // 在统计任务中用来统计程序运行时CPU的利用率
#endif
        CPU_CRITICAL_EXIT();   // 退出临界区

        OSIdleTaskHook();      // 调用用户定义的介入函数,可以在uC/OS-III空闲的时候做一些额外的工作
    }
}

注:在空闲任务中不能调用任何会使其进入等待态的服务函数(包括用户自定义的介入函数)

3.时钟节拍任务(OS_TickTask()、os_tick.c)
每个操作系统都需要一个周期性的时钟源,称为时钟节拍(Clock Tick)或者系统节拍(System Tick)。在uC/OS-III中时钟节拍相关部分的处理放在时钟节拍任务OS_TickTask()中,它的功能是跟踪正在延时的任务,以及在指定时间内等待某个内核对象的任务。
(1)配置的部分放在os_cfg_app.h的文件中

#define  OS_CFG_TICK_RATE_HZ             100u  // 时钟频率,一般在10Hz-1000Hz之间               
#define  OS_CFG_TICK_TASK_PRIO            10u  // 时钟节拍任务的优先级,在实际使用中应当只比最重要的任务的优先级低一点
#define  OS_CFG_TICK_TASK_STK_SIZE       128u  // 时钟节拍任务的栈的大小             
#define  OS_CFG_TICK_WHEEL_SIZE           17u  // 时钟节拍轮的大小,建议它的大小不要与时钟节拍的频率成倍数关系,最好是素数

(2)时钟节拍任务OS_TickTask()的代码位于os_tick.c文件中,60行 - 79行

void  OS_TickTask (void *p_arg)
{
    OS_ERR  err;
    CPU_TS  ts;

    p_arg = p_arg;
    while (DEF_ON) {
        (void)OSTaskSemPend((OS_TICK  )0,
                            (OS_OPT   )OS_OPT_PEND_BLOCKING,
                            (CPU_TS  *)&ts,
                            (OS_ERR  *)&err);  // 等待来自时钟节拍中断的信号
        if (err == OS_ERR_NONE) {
            if (OSRunning == OS_STATE_OS_RUNNING) {
                OS_TickListUpdate();           // 更新时钟节拍列表中所有任务的等待时间
            }
        }
    }
}

(4)时钟节拍轮OSCfg_TickWheel[]
个人感觉uC/OS-III关于时钟节拍轮的设计非常巧妙,很好玩。由于现在还没有了解到相关的代码,所以这里不再做过多说明。

4.统计任务(OS_StatTask()、os_stat.c)
统计任务,顾名思义就是在系统运行时做一些统计工作,比如总的CPU利用率、各任务的CPU利用率以及各任务的堆栈使用量等。
(1)统计任务的允许与禁止通过os_cfg.h文件中的宏定义OS_CFG_STAT_TASK_EN来控制

#define OS_CFG_STAT_TASK_EN             1u

(2)配置信息位于os_cfg_app.h文件中

#define  OS_CFG_STAT_TASK_PRIO            11u  // 统计任务的优先级
#define  OS_CFG_STAT_TASK_RATE_HZ         10u  // 统计任务的时钟频率,其值在1Hz - 10Hz之间
#define  OS_CFG_STAT_TASK_STK_SIZE       128u  // 统计任务的栈大小

(2)使用注意
如果要使用统计任务,必须在main()函数中创建的第一个也是唯一一个应用任务中调用OSStatTaskCPUUsageInit()函数,并且只能在该函数之后再创建其他的任务。
OSStatTaskCPUUsageInit()函数的作用是确定当系统中没有其他的任务运行时OSStatTaskCtr在(1/OS_CFG_STAT_TASK_RATE_HZ)秒的时间内能够到达的最大值。

5.定时任务(OS_TmrTask()、os_tmr.c)
uC/OS-III可以通过定时任务向用户提供定时服务。到目前为止,暂未使用到定时器任务,所以这里不再说具体实例。
(1)定时任务OS_TmrTask()的使能通过宏定义OS_CFG_TMR_EN(位于os_cfg.h中)来实现。
(2)定时任务的配置主要有任务优先级、任务频率、任务栈大小、定时器轮大小这几项,它们位于文件os_cfg_app.h中。

#define  OS_CFG_TMR_TASK_PRIO             11u               // 定时任务的优先级,一般设置为中等优先级
#define  OS_CFG_TMR_TASK_RATE_HZ          10u               // 任务的频率,一般设置成10Hz
#define  OS_CFG_TMR_TASK_STK_SIZE        128u               // 任务栈大小,这里需要注意一点的是回调函数是从定时器任务的环境中调用的,因此栈的大小还要考虑回调函数所占空间的大小
#define  OS_CFG_TMR_WHEEL_SIZE            17u               // 定时器轮大小

(3)任务函数的解析放在《uC/OS-III之定时器管理》中。

6.中断服务管理任务(OS_IntQTask()、on_int.c)
个人觉得这里不应该叫做中断服务管理任务,应该叫做中断队列处理任务(以后等深入了解直接发布模式和延时发布模式后,就会这样想了)。
(1)通过将os_cfg.h文件中的配置常量OS_CFG_ISR_POST_DEFERRED_EN设置成1,来允许创建OS_IntQTask()的任务。
(2)该任务的源代码放在os_int.c文件中,270行 - 305行

#if OS_CFG_ISR_POST_DEFERRED_EN > 0u                       // 延迟发布模式
void  OS_IntQTask (void *p_arg)
{
    CPU_BOOLEAN  done;
    CPU_TS       ts_start;
    CPU_TS       ts_end;
    CPU_SR_ALLOC();                                        // 宏定义,声明变量cpu_sr,用来临时存储CPU的状态寄存器的值

    p_arg = p_arg;  //Not using 'p_arg', prevent compiler warning
    while (DEF_ON) {
        done = DEF_FALSE;
        while (done == DEF_FALSE) {
            if (OSIntQNbrEntries == (OS_OBJ_QTY)0u) {
                CPU_CRITICAL_ENTER();                      // 进入临界区
                OSRdyList[0].NbrEntries = (OS_OBJ_QTY)0u;  // 清空就绪表中优先级为0的表项:中断队列处理任务的优先级为0
                OSRdyList[0].HeadPtr    = (OS_TCB   *)0;
                OSRdyList[0].TailPtr    = (OS_TCB   *)0;
                OS_PrioRemove(0u);                         // 从优先级位映射表中删除0
                CPU_CRITICAL_EXIT();                       // 退出临界区
                OSSched();                                 // 任务调度
                done = DEF_TRUE;                           // 中断队列为空,循环要结束
            } else {
                ts_start = OS_TS_GET();                    // 获取时间戳
                OS_IntQRePost();
                ts_end   = OS_TS_GET() - ts_start;         // 计算发送的时间
                if (ts_end > OSIntQTaskTimeMax) {          // 统计最大时间
                    OSIntQTaskTimeMax = ts_end;
                }
                CPU_CRITICAL_ENTER();                      // 进入临界区
                OSIntQNbrEntries--;
                CPU_CRITICAL_EXIT();                       // 退出临界区
            }
        }
    }
}
#endif

注:该任务的优先级为0。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值