uc/os中OSTimeDly与OSTimeDlyHMSM的区别
这个主要是为了说明OSTimeDlyHMSM(0,0,0,timemin)中的timemin最小延时问题。
这个函数在两个延时函数都有应用,就是用来任务切换的。
在uc/os-II的系统中,规定,除了空闲任务之外的所有任务必须在任务中合适的位置调用系统提供的函数OSTimeDly();使当前任务的运行延时(暂停)一段时间并进行一次任务调度,以让出CPU的使用权。(嵌入式实时操作系统uc/os-II原理及应用(任哲))
OSTimeDly()源码:
void OSTimeDly(INT16U ticks) //以时钟节拍数为单位的延时函数{#if OS_CRITICAL_METHOD == 3 //控制中断选择 OS_CPU_SR cpu_sr;#endif if(ticks > 0) { OS_ENTER_CRITICAL(); if((OSRdyTbl[OSTCBCur -> OSTCBY] &= ~OSTCBCur -> OSTCBBitX) == 0) { OSRdyGrp &= ~OSTCBCur -> OSTCBBitY; } OSTCBCur -> OSTCBDly = ticks; OS_EXIT_CRITICAL(); OS_Sched(); }}OSTimeDlyHMSM()主要源码:
ticks = (hours * 3600L + minutes * 60L + seconds) * OS_TICKS_PER_SEC+ OS_TICKS_PER_SEC * (milli + 500L / OS_TICKS_PER_SEC) / 1000L;loops = ticks / 65536L; //计算得商得倍数(多少个65536 时钟节拍)ticks = ticks % 65536L; //计算得余数OSTimeDly(ticks); //先作余数清除 ——Awhile (loops > 0) //如果节拍数超过65536 个时钟节拍{OSTimeDly(32768); //执行两次延时,实现共65536 个时钟节拍 ——BOSTimeDly(32768); ——Cloops--; //继续减1,直到为0}return (OS_NO_ERR); //返回(函数调用成功)}后面看到一个人对这个延时准确度的一个证明,感觉挺好,代码如下: #include "main.h"uint32 num0=0,num1=0;uint8 err=99; //err==0时,OSTimeDlyHMSM(),调用成功。#define STACK_SIZE 64 OS_STK TASK0_STACK[STACK_SIZE]; OS_STK TASK1_STACK[STACK_SIZE]; void TASK0(void *pdata); void TASK1(void *pdata); int main (void){ OSInit(); OSTaskCreate(TASK0,(void *)0,&TASK0_STACK[STACK_SIZE-1],2); OSTaskCreate(TASK1,(void*)0,&TASK1_STACK[STACK_SIZE-1],4); OSStart(); return 0; }void TASK0 (void *pdata){ pdata = pdata; TargetInit(); while(1) { num0++; err=OSTimeDlyHMSM(0,0,0,49); }}void TASK1 (void *pdata){ pdata = pdata; while(1) { num1++; OSTimeDlyHMSM(0,0,0,50); }}这个主要是为了说明OSTimeDlyHMSM(0,0,0,timemin)中的timemin最小延时问题。
另外,使用这两个函数的主要目的一个是使任务的运行停止并等待一段时间,另外就是调用调度器进行任务调度,为了让低优先级的任务有机会上场。
下面给大家看下中断级任务切换过程:
void OS_Sched (void){#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr;#endif INT8U y; OS_ENTER_CRITICAL(); if ((OSIntNesting == 0) && (OSLockNesting == 0)) { y = OSUnMapTbl[OSRdyGrp]; OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); if (OSPrioHighRdy != OSPrioCur) { OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; OSCtxSwCtr++; OS_TASK_SW(); } } OS_EXIT_CRITICAL();}这个函数在两个延时函数都有应用,就是用来任务切换的。
以上代码一部分自己写的,一部分借鉴别处:
http://www.jxust3jia1.com/bbs/viewthread.php?tid=10625
http://hi.baidu.com/fukai5/blog/item/6a199b3c0aeabdf73c6d9718.html