void led1_task(void *pdata)
{
while(1)
{
LED0=0;
delay_ms(80);
LED0=1;
delay_ms(920);
};
}
//LED2任务
void led2_task(void *pdata)
{
while(1)
{
LED1=0;
delay_ms(300);
LED1=1;
delay_ms(300);
};
}
操作系统中led1的优先级高于led2的优先级,高优先级的任务可以剥夺低优先级任务对cpu的控制(ucosii是可剥夺型内核),而低优先级任务不能剥夺高优先级任务对cpu的控制,因此在任务函数里面都会有延时函数delay_ms(); 仔细研究一下delay_ms()就会发现里面包括一个重要的函数OSTimdly(); 该函数里面有几句话
y = OSTCBCur->OSTCBY; /* Delay current task */
OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX;
if (OSRdyTbl[y] == 0u) {
OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;
}
OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB
这几句话实现的是在任务就续表里面置0,也就是在任务就续表里面删除本任务,并且在OSTCBCur中写入ticks的数目,表示延时的事件。
延时的同时实现了放弃cpu的控制权。
接下来还有OS_Sched()函数
该函数里面最重要的有两句话
OS_SchedNew();
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
OS_TASK_SW();
OS_SchedNew(); 函数里面最重要的功能就是
y = OSUnMapTbl[OSRdyGrp];
OSPrioHighRdy = (INT8U)((y << 3u) + OSUnMapTbl[OSRdyTbl[y]]);
这两句话的作用是通过OSUnMapTbl找出任务就续表里面优先级最高的任务优先级是多少
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];函数的作用是把
OSTCBHighRdy 指针指向优先级最高的任务
OS_TASK_SW(); 的作用是触发pendsv异常,也就是pendsv中断,pendsv中断的作用是把当前任务的r4-r11压入堆栈,并且把
OSTCBCur 指针放入栈中
因此延时函数不简单是延时函数。更重要的作用是让任务暂时放弃cpu的控制权。cpu执行led0=0可能只需要几us,因此led=0;执行以后马上另外一个任务就会获得cpu控制权从而能够执行led1=0;
|