初始化idletask的代码如下
- /*
- *********************************************************************************************************
- * INITIALIZATION
- * CREATING THE IDLE TASK
- *
- * Description: This function creates the Idle Task.
- *
- * Arguments : none
- *
- * Returns : none
- *********************************************************************************************************
- */
- static void OS_InitTaskIdle (void)
- {
- #if OS_TASK_NAME_SIZE > 7
- INT8U err;
- #endif
- #if OS_TASK_CREATE_EXT_EN > 0
- #if OS_STK_GROWTH == 1
- (void)OSTaskCreateExt(OS_TaskIdle,
- (void *)0, /* No arguments passed to OS_TaskIdle() */
- &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Top-Of-Stack */
- OS_TASK_IDLE_PRIO, /* Lowest priority level */
- OS_TASK_IDLE_ID,
- &OSTaskIdleStk[0], /* Set Bottom-Of-Stack */
- OS_TASK_IDLE_STK_SIZE,
- (void *)0, /* No TCB extension */
- OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */
- #else
- (void)OSTaskCreateExt(OS_TaskIdle,
- (void *)0, /* No arguments passed to OS_TaskIdle() */
- &OSTaskIdleStk[0], /* Set Top-Of-Stack */
- OS_TASK_IDLE_PRIO, /* Lowest priority level */
- OS_TASK_IDLE_ID,
- &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Bottom-Of-Stack */
- OS_TASK_IDLE_STK_SIZE,
- (void *)0, /* No TCB extension */
- OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */
- #endif
- #else
- #if OS_STK_GROWTH == 1
- (void)OSTaskCreate(OS_TaskIdle,
- (void *)0,
- &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1],
- OS_TASK_IDLE_PRIO);
- #else
- (void)OSTaskCreate(OS_TaskIdle,
- (void *)0,
- &OSTaskIdleStk[0],
- OS_TASK_IDLE_PRIO);
- #endif
- #endif
- #if OS_TASK_NAME_SIZE > 14
- OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)"uC/OS-II Idle", &err);
- #else
- #if OS_TASK_NAME_SIZE > 7
- OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)"OS-Idle", &err);
- #endif
- #endif
- }
设置一个字节大小的变量err
当系统可以创建OSTaskCreateExt()即用户可以额外的附加数据域的任务创建
并且OS_STK_GROWTH == 1即栈的地址是从高地址到低地址的
使用OSTaskCreateExt(OS_TaskIdle,
(void *)0, /* No arguments passed to OS_TaskIdle() */
&OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Top-Of-Stack */
OS_TASK_IDLE_PRIO, /* Lowest priority level */
OS_TASK_IDLE_ID,
&OSTaskIdleStk[0], /* Set Bottom-Of-Stack */
OS_TASK_IDLE_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */
创建idle任务,函数的9个参数分别为,任务代码的指针(任务函数名),pdata传递给任务的参数指针,
分配给任务的堆栈的栈顶指针,分配给任务的优先级数据,(之后是Ext后缀的任务创建函数才有的)
特殊id(目前版本未使用),栈底指针(用于堆栈的检验),
size用于指定堆栈的容量(如果栈的单位容量为4个字节,size为1000,那么栈的大小为4×1000个字节)
指向用户附加数据域的指针(附加的哦),最后,有三个选项,分别表示堆栈检验,堆栈清零和浮点操作的使能。
当使能HIGH-LOW栈的时候,堆栈的top指针指向数组最后一位,当LOW-HIGH时,堆栈的top指向数组头
数组的内存分配一定是从低地址向高地址,跟大端小端系统木有联系
如果Ext的使能没有打开,就是用(void)OSTaskCreate(OS_TaskIdle,
(void *)0,
&OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1],
OS_TASK_IDLE_PRIO);
创建任务,其参数与前面的ext函数的前四个参数含义相同,
创建完成后,如果OS_TASK_NAME_SIZE足够大,使用OSTaskNameSet函数设置taskname
- /*
- *********************************************************************************************************
- * ASSIGN A NAME TO A TASK
- *
- * Description: This function is used to set the name of a task.
- *
- * Arguments : prio is the priority of the task that you want the assign a name to.
- *
- * pname is a pointer to an ASCII string that contains the name of the task. The ASCII
- * string must be NUL terminated.
- *
- * err is a pointer to an error code that can contain one of the following values:
- *
- * OS_NO_ERR if the requested task is resumed
- * OS_TASK_NOT_EXIST if the task has not been created or is assigned to a Mutex
- * OS_ERR_TASK_NAME_TOO_LONG if the name you are giving to the task exceeds the
- * storage capacity of a task name as specified by
- * OS_TASK_NAME_SIZE.
- * OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname'
- * OS_PRIO_INVALID if you specified an invalid priority:
- * A higher value than the idle task or not OS_PRIO_SELF.
- *
- * Returns : None
- *********************************************************************************************************
- */
- #if OS_TASK_NAME_SIZE > 1
- void OSTaskNameSet (INT8U prio, INT8U *pname, INT8U *err)
- {
- INT8U len;
- OS_TCB *ptcb;
- #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 (err == (INT8U *)0) { /* Validate 'err' */
- return;
- }
- if (prio > OS_LOWEST_PRIO) { /* Task priority valid ? */
- if (prio != OS_PRIO_SELF) {
- *err = OS_PRIO_INVALID; /* No */
- return;
- }
- }
- if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */
- *err = OS_ERR_PNAME_NULL; /* Yes */
- return;
- }
- #endif
- OS_ENTER_CRITICAL();
- if (prio == OS_PRIO_SELF) { /* See if caller desires to set it's own name */
- prio = OSTCBCur->OSTCBPrio;
- }
- ptcb = OSTCBPrioTbl[prio];
- if (ptcb == (OS_TCB *)0) { /* Does task exist? */
- OS_EXIT_CRITICAL(); /* No */
- *err = OS_TASK_NOT_EXIST;
- return;
- }
- if (ptcb == (OS_TCB *)1) { /* Task assigned to a Mutex? */
- OS_EXIT_CRITICAL(); /* Yes */
- *err = OS_TASK_NOT_EXIST;
- return;
- }
- len = OS_StrLen(pname); /* Yes, Can we fit the string in the TCB? */
- if (len > (OS_TASK_NAME_SIZE - 1)) { /* No */
- OS_EXIT_CRITICAL();
- *err = OS_ERR_TASK_NAME_TOO_LONG;
- return;
- }
- (void)OS_StrCopy(ptcb->OSTCBTaskName, pname); /* Yes, copy to TCB */
- OS_EXIT_CRITICAL();
- *err = OS_NO_ERR;
- }
- #endif
设置必要的局部变量,设置参数
如果OS_ARG_CHK_EN > 0即使能变量检查位
idle的优先级一般被定义为OS_LOWEST_PRIO
那么检查指针参数是否指向空指针,检查优先级是否大于OS_LOWEST_PRIO
关中断
得到优先级,然后使用OSTCBPrioTbl[prio]函数返回prio优先级对应的任务TCB指针
如果为空,返回错误
求出strlen如果过长返回超出长度错误
一切ok使用OS_StrCopy(ptcb->OSTCBTaskName, pname);将字符串pname拷贝到TCB的taskname中去
开中断
err返回NO_ERR
- /*
- *********************************************************************************************************
- * IDLE TASK
- *
- * Description: This task is internal to uC/OS-II and executes whenever no other higher priority tasks
- * executes because they are ALL waiting for event(s) to occur.
- *
- * Arguments : none
- *
- * Returns : none
- *
- * Note(s) : 1) OSTaskIdleHook() is called after the critical section to ensure that interrupts will be
- * enabled for at least a few instructions. On some processors (ex. Philips XA), enabling
- * and then disabling interrupts didn't allow the processor enough time to have interrupts
- * enabled before they were disabled again. uC/OS-II would thus never recognize
- * interrupts.
- * 2) This hook has been added to allow you to do such things as STOP the CPU to conserve
- * power.
- *********************************************************************************************************
- */
- void OS_TaskIdle (void *p_arg)
- {
- #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
- OS_CPU_SR cpu_sr = 0;
- #endif
- (void)p_arg; /* Prevent compiler warning for not using 'parg' */
- for (;;) {
- OS_ENTER_CRITICAL();
- OSIdleCtr++;
- OS_EXIT_CRITICAL();
- OSTaskIdleHook(); /* Call user definable HOOK */
- }
- }
TaskIdle的函数实现:
死循环:
关中断,idle计数器自加,开中断,用户自定义程序TaskIdleHook
阅读(2998) | 评论(0) | 转发(0) |