uCOS的軟體定時器、uCOS時鐘節拍和滴答定時器的關係
uCOS2.81後的版本中有軟體定時器的概念,如果要開啟定時器任務,需要在OS_CFG.H檔案中 #define OS_TMR_EN 1
軟體定時器其實跟硬體中斷是相似的,定時時間到了,就執行一次回撥函式,雖然好用,但是也會降低系統的實時性。
軟體定時器也需要一個時鐘節拍驅動,這個驅動也是由硬體實現的,一般使用uCOS中的任務延時節拍驅動來驅動軟體定時器,每個時鐘節拍OSTmrCtr(全域性變數,初始值為0)加1,當OSTmrCtr的值等於OS_TICKS_PER_SEC /OS_TMR_CFG_TICKS_PER_SEC(前者是ucos節拍頻率,後者是軟體定時器的節拍頻率,相當於分頻)時,呼叫函式OSTmrSignl()函式,傳送訊號量OSTmrSemSignal(初始值0,決定軟體定時器掃描任務OSTmr_Task的執行),也就是說,對軟體定製器的處理不在時鐘節拍中斷函式中執行,而是以發生訊號量的方式啟用任務OSTmr_Task,任務OSTmr_Task對定時器進行檢測,包括定時器定時完成的判斷,回撥函式的執行。
舉例來講,ucos中的OS_TICKS_PER_SEC設定值為1000(最大),OS_TMR_CFG_TICKS_PER_SEC為100,則可知uCOS的節拍時間為1ms,軟體定時器的節拍時間為1000/100*1=10ms
在軟體定時器的生成函式中:
OS_TMR *OSTmrCreate (INT32U dly,
INT32U period,
INT8U opt,
OS_TMR_CALLBACK callback,
void *callback_arg,
INT8U *pname,
INT8U *perr)
其中dly表示第一次延時時間節拍數(軟體定時器節拍,不是ucos的節拍)
period表示重複節拍數,如果設定dly為10,period為20,opt設定OS_TMR_OPT_PERIODIC,則表示這是1個重複執行軟體定時器,第一次執行定時時間為10x10=100ms,以後每隔20x10=200ms的間隔時間執行回撥函式。
uCOS2.81後的版本中有軟體定時器的概念,軟體定時器其實跟硬體中斷是相似的,定時時間到了,就執行一次回撥函式,雖然好用,但是也會降低系統的實時性。
軟體定時器也需要一個時鐘節拍驅動,這個驅動也是由硬體實現的,一般使用uCOS中的任務延時節拍驅動來驅動軟體定時器,每個時鐘節拍OSTmrCtr(全域性變數,初始值為0)加1,當OSTmrCtr的值等於OS_TICKS_PER_SEC /OS_TMR_CFG_TICKS_PER_SEC(前者是ucos節拍頻率,後者是軟體定時器的節拍頻率,相當於分頻)時,呼叫函式OSTmrSignl()函式,傳送訊號量OSTmrSemSignal(初始值0,決定軟體定時器掃描任務OSTmr_Task的執行),也就是說,對軟體定製器的處理不在時鐘節拍中斷函式中執行,而是以發生訊號量的方式啟用任務OSTmr_Task,任務OSTmr_Task對定時器進行檢測,包括定時器定時完成的判斷,回撥函式的執行。
舉例來講,ucos中的OS_TICKS_PER_SEC設定值為1000(最大),OS_TMR_CFG_TICKS_PER_SEC為100,則可知uCOS的節拍時間為1ms,軟體定時器的節拍時間為1000/100*1=10ms
在軟體定時器的生成函式中:
OS_TMR *OSTmrCreate (INT32U dly,
INT32U period,
INT8U opt,
OS_TMR_CALLBACK callback,
void *callback_arg,
INT8U *pname,
INT8U *perr)
其中dly表示第一次延時時間節拍數(軟體定時器節拍,不是ucos的節拍)
period表示重複節拍數,如果設定dly為10,period為20,opt設定OS_TMR_OPT_PERIODIC,則表示這是1個重複執行軟體定時器,第一次執行定時時間為10x10=100ms,以後每隔20x10=200ms的間隔時間執行回撥函式。
===========================================
uCOS時鐘節拍和滴答定時器的關係
在使用uCOS時,有一個非常重要,非常關鍵的概念就是作業系統的時鐘節拍,uCOS的時鐘節拍來源於滴答定時器,滴答定時器按照設定的時間不停的計時和產生中斷,在uCOS-III中滴答定時器的中斷服務函式如下:
void OS_CPU_SysTickHandler (void)
{
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
OSIntNestingCtr++; /* Tell uC/OS-III that we are starting an ISR */
CPU_CRITICAL_EXIT();
OSTimeTick(); /* Call uC/OS-III's OSTimeTick() */
OSIntExit(); /* Tell uC/OS-III that we are leaving the ISR */
}
其中OSTimeTick();的作用是檢查每個任務的任務控制塊中OSTCBDly減1後是否為0(翻譯過來就是檢查任務延時函式OSTimeDly中的節拍數是否減為0了),如果是,則表明這個任務剛才是掛起狀態,此時應變為就緒態,接著在任務中OSTimeDly函式進行一次任務排程。
所以可以得出一個重要關係:
滴答定時器的中斷時間 = uCOS的1個節拍時間
這個節拍就是OSTimeDly (OS_TICK dly, OS_OPT opt,OS_ERR *p_err)函式中的dly。
在uCOS-III中針對節拍的時間有如下定義:
/* ------------------------ TICKS ----------------------- */
#define OS_CFG_TICK_RATE_HZ 1000u /* Tick rate in Hertz (10 to 1000 Hz) */
這個OS_CFG_TICK_RATE_HZ表示節拍的頻率,如果設定為1000,則表示頻率為1000Hz,則1個節拍為1ms。
那麼問題來了,如果想要uCOS-III的節拍時間為1ms,如何設定滴答定時器的reload數值呢?
通過上面的分析可知,我們只需要設定滴答定時器的中斷時間為1ms即可,以STM32為例,典型的系統時鐘頻率為72MHz(外部晶振選擇為8MHz),滴答定時器時鐘源也選擇為HCLK(不是除以8),
則滴答定時器計數1次的時間為:1/72000000 s
要想中斷時間為1ms = 1/1000 s,則reload = (1/10000)/(1/72000000) = 72000
而72000 = 72000000(系統時鐘)/1000(OS_CFG_TICK_RATE_HZ)
所以在設定滴答定時器初始化函式時,只需設定:
SysTick_Config(SystemCoreClock/OS_CFG_TICK_RATE_HZ);
就能滿足uCOS-III想要的節拍時間了。
摘自:https://blog.csdn.net/u012351051/article/details/51262503