1.空闲任务OS_IdleTaskInit(p_err); os_core.c中
系统在初始化过程中,会先创建一个空闲任务,在创建空闲任务时先初始化任务控制块和链表,然后进行优先级和就绪链表插入操作(OS_PrioInsert和OS_RdyListInsertTail),同时将任务计数加一(OSTaskQty++; ),最后调用OSSched()函数。
这个任务几乎不做什么事情,只是把OSIdleTaskCtr
和OSStatTaskCtr
进行自加操作,这两个变量都是用来调试和统计任务统计的,以保证CPU始终处于运行状态。
创建任务的标准流程:初始化任务控制块——插入优先级链表——插入就绪链表——任务计数加1——调用OSSched()。
2.时钟节拍任务OS_TickTaskInit(p_err); os_tick.c中,优先级为2u
流程同上。
节拍任务的具体函数如下:
可以看到,函数处于for的死循环中,并且调用
(void)OSTaskSemPend(0u,
OS_OPT_PEND_BLOCKING,
DEF_NULL,
&err); 函数,其作用为:
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函数中操作: