μC/OS-II中,任务是基本的执行单元,所以任务如何管理对于基于μC/OS-II系统的驱动的编写是很关键的,下面就来浅析几个主要的任务管理函数的源码。其任务管理函数主要就在源码目录的Os_task.c中。
首先先来看一下任务是如何创建的,μC/OS-II中最基本的任务创建函数是OSTaskCreate ()函数,它的源码如下:
- #if OS_TASK_CREATE_EN > 0
- INT8U OSTaskCreate (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT8U prio)
- {
- OS_STK *psp;
- INT8U err;
- #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
- OS_CPU_SR cpu_sr = 0;
- #endif
- #if OS_ARG_CHK_EN > 0
- if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */
- return (OS_PRIO_INVALID);
- }
- #endif
- OS_ENTER_CRITICAL();
- if (OSIntNesting > 0) { /* Make sure we don't create the task from within an ISR */
- OS_EXIT_CRITICAL();
- return (OS_ERR_TASK_CREATE_ISR);
- }
- if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */
- OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the priority to prevent others from doing ... */
- /* ... the same thing until task is created. */
- OS_EXIT_CRITICAL();
- psp = OSTaskStkInit(task, p_arg, ptos, 0); /* Initialize the task's stack */
- err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);
- if (err == OS_NO_ERR) {
- if (OSRunning == TRUE) { /* Find highest priority task if multitasking has started */
- OS_Sched();
- }
- } else {
- OS_ENTER_CRITICAL();
- OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */
- OS_EXIT_CRITICAL();
- }
- return (err);
- }
- OS_EXIT_CRITICAL();
- return (OS_PRIO_EXIST);
- }
- #endif
- #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
- OS_CPU_SR cpu_sr = 0;
- #endif
这个事进入临界状态方法的一个选择,一般在ARM中选择的都是第三种,其是把寄存器的值保存到临界变量cpu_sr中。
- #define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();}
- #define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);}
上面就是进入临界状态和退出临界状态的方法,首先通过函数将寄存器中的值保存在cpu_sr中,然后在退出临界状态时再将寄存器的值恢复。
- #if OS_ARG_CHK_EN > 0
- if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */
- return (OS_PRIO_INVALID);
- }
- #endif
- OS_ENTER_CRITICAL();
- if (OSIntNesting > 0) { /* Make sure we don't create the task from within an ISR OSIntNesting为中断嵌套次数,没有中断则为0*/
- OS_EXIT_CRITICAL();
- return (OS_ERR_TASK_CREATE_ISR);
- }
- if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */
- OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the priority to prevent others from doing ... */
- /* ... the same thing until task is created. */
- OS_EXIT_CRITICAL();
- psp = OSTaskStkInit(task, p_arg, ptos, 0); /* Initialize the task's stack */
- err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);
- if (err == OS_NO_ERR) {
- if (OSRunning == TRUE) { /* Find highest priority task if multitasking has started */
- OS_Sched();
- }
- } else {
- OS_ENTER_CRITICAL();
- OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */
- OS_EXIT_CRITICAL();
- }
- return (err);
- }
- OS_EXIT_CRITICAL();
- return (OS_PRIO_EXIST);
- }
下面我们再来看OSTaskCreate()的升级版OSTaskCreateExt()函数:
- #if OS_TASK_CREATE_EXT_EN > 0
- INT8U OSTaskCreateExt (void (*task)(void *p_arg), //指向任务代码的指针
- void *p_arg, //指向传递给任务的参数的指针
- OS_STK *ptos, //指向栈顶指针
- INT8U prio, //任务优先级
- INT16U id, //任务ID值
- OS_STK *pbos, //任务栈底指针
- INT32U stk_size, //任务栈单元个数
- void *pext, //任务控制块中扩展部分数据的位置
- INT16U opt) //任务栈初始化选项
- {
- OS_STK *psp;
- INT8U err;
- #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
- OS_CPU_SR cpu_sr = 0;
- #endif
- #if OS_ARG_CHK_EN > 0
- if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */
- return (OS_PRIO_INVALID);
- }
- #endif
- OS_ENTER_CRITICAL();
- if (OSIntNesting > 0) { /* Make sure we don't create the task from within an ISR */
- OS_EXIT_CRITICAL();
- return (OS_ERR_TASK_CREATE_ISR);
- }