ucosiii学习(2)——系统初始化时所创建的任务

1.空闲任务OS_IdleTaskInit(p_err);      os_core.c中

系统在初始化过程中,会先创建一个空闲任务,在创建空闲任务时先初始化任务控制块和链表,然后进行优先级和就绪链表插入操作(OS_PrioInsert和OS_RdyListInsertTail),同时将任务计数加一(OSTaskQty++;  ),最后调用OSSched()函数。

这个任务几乎不做什么事情,只是把OSIdleTaskCtrOSStatTaskCtr进行自加操作,这两个变量都是用来调试和统计任务统计的,以保证CPU始终处于运行状态。

创建任务的标准流程:初始化任务控制块——插入优先级链表——插入就绪链表——任务计数加1——调用OSSched()。

2.时钟节拍任务OS_TickTaskInit(p_err);     os_tick.c中,优先级为2u

流程同上。

节拍任务的具体函数如下:

可以看到,函数处于for的死循环中,并且调用 

(void)OSTaskSemPend(0u,
                            OS_OPT_PEND_BLOCKING,
                            DEF_NULL,
                            &err);  函数,其作用为:

扫描二维码关注公众号,回复: 3641148 查看本文章

 Description: This function is called to block the current task until a signal is sent by another task or ISR.

循环最初,要等待任务自身的计数信号量,而且其选项是OS_OPT_PEND_BLOCKING,等不到信号量时会阻塞住并释放CPU发生一次调度,调度到其他任务。而这个任务的技术信号量的Post操作是发生在SysTick的中断处理函数中的。在SysTick中断处理函数void SysTick_Handler(void)中有调用OSTimeTick:

void  OS_CPU_SysTickHandler  (void)
{
    CPU_SR_ALLOC();
    CPU_CRITICAL_ENTER();
    OSIntEnter();               /* Tell uC/OS-III that we are starting an ISR   */
    CPU_CRITICAL_EXIT();
    OSTimeTick();               /* Call uC/OS-III's OSTimeTick()   */
    OSIntExit();                /* Tell uC/OS-III that we are leaving the ISR   */
}

在OSTimeTick()中有

  (void)OSTaskSemPost(&OSTickTaskTCB,                          /* Signal tick task                                     */
                        OS_OPT_POST_NONE,
                       &err);

因此,OSTimeTick函数会往OSTickTaskTCB任务中做一次Post操作,OS_TickTask在其for循环中循环一次。

(void)OS_TickListUpdateDly(tick_step):更新时基任务列表OSTickListTimeDly。OS_TickListUpdateDly函数会先把OSTickListTimeDly中的每一个任务的TickRemain进行检查,如果发现这些任务延时已经到期,那么就把这些任务从OSTickListTimeDly移除,并调用OS_RdyListInsert放入到就绪队列里。

(* Description: This function updates the delta list which contains tasks that have been delayed.)

(void)OS_TickListUpdateTimeout(tick_step):更新时基任务列表OSTickListTimeout。OS_TickListUpdateTimeout函数也会先把OSTickListTimeout中的每一个任务的TickRemain进行检查,如果发现这些任务的Time Out已经到期,那么就先把这些任务从OSTickListTimeout移除,又因为这些任务都是通过Pend和设置timeout值被放入OSTickListTimeout队列的,所以这些任务一定也存在于一个Pend List中。同样的,OS_TickListUpdateTimeout也会调用OS_PendListRemove把这些任务从其相应的Pend List中移除,并调用OS_RdyListInsert放入到就绪队列里。

(* Description: This function updates the delta list which contains tasks that are pending with a timeout.)

这两个任务是系统初始化时必须创建的。

3.统计任务 OS_StatTaskInit(p_err);

Description: This task is internal to uC/OS-III and is used to compute some statistics about the multitasking environment.  Specifically, OS_StatTask() computes the CPU usage.  CPU usage is determined by:

a.统计总的CPU使用率(0 到 100%),每个任务的CPU使用率(0 到 100%)。μC/OS III 允许用户在调用 OSStart()之前创建任意个任务。然而 ,当用到统计任务统计 CPU 的使用率时,调用 OSStart()之前只能创建一个任务,优先级比空闲任务高。
b. 每个任务的堆栈使用量。并将计算结果存于每个任务OS_TCB的StkFree和StkUsed中。


如果想使用统计任务,最好在 main()中只创建一个任务,通常叫做AppTaskStat(),当使能了统计任务时,就必须在AppTaskStat任务中首先调用OSStatTaskCPUUsageInit()。在调用OSStart()之前 ,用户的启动代码只能创建一个任务,由这个任务创建其它任务。 调用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。

4.定时器任务OS_TmrInit(p_err);

Description: This function is called by OSInit() to initialize the timer manager module.

优先级为最大优先级-3,高于空闲任务, 主要用于阻塞(OSTaskSemPend)或者延时(OSTimeDly),取决于宏开关OS_CFG_DYN_TICK_EN。以OSTaskSemPend为例,定时器任务会一直等到其他任务或者中断对OSTmrTaskTCB进行的Post操作。而这个操作和时基任务的Post操作一样,在OS_CPU_SysTickHandler的OSTimeTick函数中操作:

猜你喜欢

转载自blog.csdn.net/weixin_42480952/article/details/83015764
今日推荐