在u cos ii中任务延时函数是非常重要的的功能函数,它可以使任务在超级循环中不至于独占CPU,因为在任务中调用一次这个函数系统会进行一次任务调度,从而执行下一个优先级更高的任务,一旦调用OSTimeDly()所规定的时间满或者有其他任务通过调用OSTimeDlyResume()取消了延时,该任务又重新回到就绪状态。
下面简单介绍一下该函数的源码:
void OSTimeDly (INT16U ticks)
{
if (ticks > 0) //若为0,表示不延时
{
OS_ENTER_CRITICAL(); //关系统中断
if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0)
{
OSRdyGrp &= ~OSTCBCur->OSTCBBitY; //从任务控制块的就绪表中移除当前任务
}
OSTCBCur->OSTCBDly = ticks; //延时节怕数保存到任务控制块
OS_EXIT_CRITICAL(); //开启系统中断
OSSched(); //进行任务调度,执行下一次优先级最高的任务
}
}
下面举一个简单的例子
int main()
{
my_systeminit();//系统初始化
GPIO_led(); //GPIO口初始化
Timerx_Init();//时钟初始化
OSInit(); //系统初始化
OSTaskCreate((void (*) (void *)) App_TaskStart,
/* Create the start task. */
(void *) 0,
(OS_STK *) &App_TaskStartStk[APP_TASK_START_STK_SIZE - 1],
(INT8U) APP_TASK_START_PRIO); //创建任务1,优先级为2
OSTaskCreate((void (*) (void *)) task1,
(void *) 0,
(OS_STK *) &app_task1[APP_TASK_TASK1_STK_SIZE-1],
(INT8U) APP_TASK_TASK1_PRIO);//创建任务2,优先级为3
OSTimeSet(0); //开启os‘心跳’
OSStart(); //启动系统 /* Start multitasking (i.e. give control to uC/OS-II). */
return (0);
}
static void App_TaskStart(void* p_arg)
{
INT8U error;
(void) p_arg;
OS_CPU_SysTickInit(); /* Initialize the SysTick. */
for(;;)
{
LED_LED2_ON(); //开启LED2
LED_LED1_ON();//开启LED1
OSTimeDly(1000);
LED_LED3_ON(); //开启LED3
}
}
static void task1(void* p_arg)
{
INT8U error;
(void) p_arg;
for(;;)
{
LED_LED2_OFF();//关闭LED2
LED_LED1_OFF();//关闭LED1
OSTimeDly(100);
}
}
现象是首先LED1 LED2亮,随后LED1 LED2灭,随后LED3亮,最后LED1 LED2 LED3一起亮如此循环。
现象分析:
首先执行任务1,LED1 LED2亮,执行到延时函数,执行任务调度,任务1挂起,执行任务2,之后LED1 LED2灭,又执行任务2 的延时函数,任务2挂起(此时任务1也是挂起的),CPU执行空闲任务,当任务2延时期满,回来重新执行任务2,一直循环到任务1的延时期满,回来执行LED_LED3_ON(); ,LED3亮,又回到 LED_LED2_ON(); LED_LED1_ON();//LED1 LED2 LED3一起亮。
总结:OSTimeDly()函数类似有VC中的sleep函数,执行的时候本线程休眠执行下一个线程,当延时时间满,又重新执行本线程。