新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > μC/OS-II的時間管理

        μC/OS-II的時間管理

        作者: 時間:2016-10-08 來源:網絡 收藏

        程序清單 L5.2 OSTimeDlyHMSM().

        INT8UOSTimeDlyHMSM(INT8Uhours,INT8Uminutes,INT8Useconds,INT16U

        milli)

        {

        INT32Uticks;

        INT16Uloops;

        if(hours>0|| minutes>0|| seconds>0|| milli>0){(1)

        if(minutes>59){

        return(OS_TIME_INVALID_MINUTES);

        }

        if(seconds>59){

        return(OS_TIME_INVALID_SECONDS);

        }

        If(milli>999){

        return(OS_TIME_INVALID_MILLI);

        }

        ticks=(INT32U)hours*3600L*OS_TICKS_PER_SEC(2)

        +(INT32U)minutes*60L*OS_TICKS_PER_SEC

        +(INT32U)seconds*OS_TICKS_PER_SEC

        +OS_TICKS_PER_SEC*((INT32U)milli

        +500L/OS_TICKS_PER_SEC)/1000L;(3)

        loops=ticks/65536L;(4)

        ticks=ticks%65536L;(5)

        OSTimeDly(ticks);(6)

        while(loops>0){(7)

        OSTimeDly(32768);(8)

        OSTimeDly(32768);

        loops--;

        }

        return(OS_NO_ERR);

        }else{

        return(OS_TIME_ZERO_DLY);(9)

        }

        }

        由于OSTimeDlyHMSM()的具體實現方法,用戶不能結束延時調用OSTimeDlyHMSM()要求延時超過65535個節拍的任務。換句話說,如果時鐘節拍的頻率是100Hz,用戶不能讓調用OSTimeDlyHMSM(0,10,55,350)或更長延遲時間的任務結束延時。

        5.2讓處在延時期的任務結束延時,OSTimeDlyResume()

        μC/OS-Ⅱ允許用戶結束延時正處于延時期的任務。延時的任務可以不等待延時期滿,而是通過其它任務取消延時來使自己處于就緒態。這可以通過調用OSTimeDlyResume()和指定要恢復的任務的優先級來完成。實際上,OSTimeDlyResume()也可以喚醒正在等待事件(參看第六章——任務間的通訊和同步)的任務,雖然這一點并沒有提到過。在這種情況下,等待事件發生的任務會考慮是否終止等待事件。

        OSTimeDlyResume()的代碼如程序清單L5.3所示,它首先要確保指定的任務優先級有效[L5.3(1)]。 接著, OSTimeDlyResume()要確認要結束延時的任務是確實存在的[L5.3(2)]。

        如果任務存在, OSTimeDlyResume()會檢驗任務是否在等待延時期滿[L5.3(3)]。 只要OS_TCB

        域中的OSTCBDly包含非0值就表明任務正在等待延時期滿,因為任務調用了OSTimeDly(),OSTimeDlyHMSM()或其它在第六章中所描述的PEND函數。然后延時就可以通過強制命令OSTCBDly為0來取消[L5.3(4)]。延時的任務有可能已被掛起了,這樣的話,任務只有在沒有被掛起的情況下才能處于就緒狀態[L5.3(5)]。當上面的條件都滿足后,任務就會被放在就緒表中[L5.3(6)]。這時,OSTimeDlyResume()會調用任務調度程序來看被恢復的任務是否擁有比當前任務更高的優先級[L5.3(7)]。這會導致任務的切換。

        程序清單 L5.3 恢復正在延時的任務

        INT8UOSTimeDlyResume(INT8Uprio)

        {

        OS_TCB*ptcb;

        if(prio>=OS_LOWEST_PRIO){(1)

        return(OS_PRIO_INVALID);

        }

        OS_ENTER_CRITICAL();

        ptcb=(OS_TCB*)OSTCBPrioTbl[prio];

        if(ptcb!=(OS_TCB*)0){(2)

        if(ptcb->OSTCBDly!=0){(3)

        ptcb->OSTCBDly=0;(4)

        if(!(ptcb->OSTCBStatOS_STAT_SUSPEND)){(5)

        OSRdyGrp|=ptcb->OSTCBBitY;(6)

        OSRdyTbl[ptcb->OSTCBY]|=ptcb->OSTCBBitX;

        OS_EXIT_CRITICAL();

        OSSched();(7)

        }else{

        OS_EXIT_CRITICAL();

        }

        return(OS_NO_ERR);

        }else{

        OS_EXIT_CRITICAL();

        return(OS_TIME_NOT_DLY);

        }

        }else{

        OS_EXIT_CRITICAL();

        return(OS_TASK_NOT_EXIST);

        }

        }

        注意,用戶的任務有可能是通過暫時等待信號量、郵箱或消息隊列來延時自己的(參看第六章)。可以簡單地通過控制信號量、郵箱或消息隊列來恢復這樣的任務。這種情況存在的唯一問題是它要求用戶分配事件控制塊(參看6.00),因此用戶的應用程序會多占用一些RAM。

        5.3系統時間,OSTimeGet()和 OSTimeSet()

        無論時鐘節拍何時發生,μC/OS-Ⅱ都會將一個32位的計數器加1。這個計數器在用戶調用OSStart()初始化多任務和4,294,967,295個節拍執行完一遍的時候從0開始計數。在時鐘節拍的頻率等于100Hz的時候,這個32位的計數器每隔497天就重新開始計數。用戶可以通過調用OSTimeGet()來獲得該計數器的當前值。也可以通過調用OSTimeSet()來改變該計數器的值。OSTimeGet()和OSTimeSet()兩個函數的代碼如程序清單L5.4所示。注意,

        在訪問OSTime的時候中斷是關掉的。這是因為在大多數8位處理器上增加和拷貝一個32位的數都需要數條指令,這些指令一般都需要一次執行完畢,而不能被中斷等因素打斷。

        程序清單 L5.4 得到和改變系統時間

        INT32UOSTimeGet(void)

        {

        INT32Uticks;

        OS_ENTER_CRITICAL();

        ticks=OSTime;

        OS_EXIT_CRITICAL();

        return(ticks);

        }

        voidOSTimeSet(INT32Uticks)

        {

        OS_ENTER_CRITICAL();

        OSTime=ticks;

        OS_EXIT_CRITICAL();

        }


        上一頁 1 2 下一頁

        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 建阳市| 武胜县| 广昌县| 固阳县| 绍兴县| 嘉义县| 浦江县| 鄢陵县| 增城市| 石嘴山市| 故城县| 抚远县| 垫江县| 堆龙德庆县| 休宁县| 通州市| 孟连| 毕节市| 广水市| 长子县| 安顺市| 济阳县| 赞皇县| 昆明市| 黑龙江省| 明星| 崇义县| 九寨沟县| 台安县| 县级市| 梅州市| 沧源| 公主岭市| 邵东县| 扶绥县| 西林县| 左贡县| 高台县| 彰化市| 大荔县| 富宁县|