CMSIS-RTOS 時間管理之時間延遲Time Delay
時間管理 Time Management
此RTOS除了可以把你的應用代碼作為線程運行,它還可以提供一些時間服務功能,使用這些功能你就可以訪問RTOS的一些系統調用。
時間延遲Time Delay
在所有的時間服務功能中,最基本的一個就是延時函數。它可以在你的應用中提供非常簡單易用的延時功能。也許你會覺得CMSIS-RTOS已經占用了5k字節的代碼量,但是在非RTOS的應用中,我們也常會用到一些延時循環、簡單的調度循環等,這些循環功能同樣會占用一些字節,而我們的RTOS在這方面可能會占用更少的代碼量。
void osDelay(uint32_t millisec)
上面這個調用會導致當前線程進入等待延時狀態(WAIT_DELAY),延時時間由用戶指定。與此同時調度器將會執行下一個處於準備狀態(READY)的線程。
註:在線程的生命周期中,它會進入多種狀態。這裏一個處於運行狀態(RUN)的線程被osDelay阻塞,然後它就會進入等待狀態(WAIT)。當延時時間結束時,它就會進入準備狀態(READY),調度器就會把它置於運行狀態(RUN)。如果它的時間片結束了,它就會返回準備狀態(READY)。
當定時時間結束時,線程會離開等待延時狀態,進入READY狀態。當調度器把線程移入RUNNING狀態時,它就會繼續運行。如果線程在以後的執行過程中沒有任何阻塞調用,在它的時間片結束時就會被置於READY狀態,同時另外一個同優先級的線程就會進入運行狀態。
等待事件
除了單純的時間延遲,同樣可以使用事件等待讓線程暫停並進入等待狀態,當有另外一個RTOS事件出現時,就會觸發線程繼續運行。RTOS事件可以是一個信號,消息或者郵件。如果沒有事件出現,就可以osWait()這個API,它有一個毫秒級別的超時機制,可以允許線程的喚醒和繼續執行。
osStatus osWait(uint32_t millisec)//RTX不支持此函數
當設定的時間結束,線程就會由WAIT狀態進入到READY狀態,隨後被調度器置於RUN狀態。osWait在CMSIS RTOS裏面是一個可選API。如果你打算使用這個函數,必須先確定你使用的RTOS是支持的。需要註意的是,CMSIS RTOS目前封裝的keil RTX 是不支持這個API的。
通過STM32的simulaiton,我發現他的執行順序是這樣的:首先進入main函數,一系列初始化後,完成osKernelStart (); 後,馬上進入led_Thread2,執行到osSemaphoreRelease(sem1);,轉到led_Thread1,LED_On(1); osDelay(500);還沒開始delay就又轉到led_Thread2。恰好線程2又是delay,程序中沒什麽可執行,索性線程1和線程2就delay了500ms,然後又回到線程1執行led關,等待semaphore。
/*---------------------------------------------------------------------------- Designers Guide to the Cortex-M Family Semaphore Example *----------------------------------------------------------------------------*/ #include "stm32f10x.h" #include "cmsis_os.h" #include "Board_LED.h" void led_Thread1 (void const *argument); void led_Thread2 (void const *argument); osThreadDef(led_Thread1, osPriorityAboveNormal, 1, 0); //note the raised priority for led_thread 1 osThreadDef(led_Thread2, osPriorityNormal, 1, 0); osThreadId T_ledOn; osThreadId T_ledOff; /*---------------------------------------------------------------------------- Define the semaphore *---------------------------------------------------------------------------*/ osSemaphoreId sem1; osSemaphoreDef(sem1); /*---------------------------------------------------------------------------- Wait to acquire a semaphore token from sem1 then flash LED 1 *---------------------------------------------------------------------------*/ void led_Thread1 (void const *argument) { for (;;) { osSemaphoreWait(sem1, osWaitForever); LED_On(1); osDelay(500); LED_Off(1); } } /*---------------------------------------------------------------------------- Flash LED 2 and ‘release‘ a semaphore token to sem1 *---------------------------------------------------------------------------*/ void led_Thread2 (void const *argument) { for (;;) { LED_On(2); osSemaphoreRelease(sem1); osDelay(500); LED_Off(2); osDelay(500); } } /*---------------------------------------------------------------------------- Initilise the LED‘s, Create the semaphore and start the threads *---------------------------------------------------------------------------*/ int main (void) { osKernelInitialize (); // initialize CMSIS-RTOS LED_Initialize (); sem1 = osSemaphoreCreate(osSemaphore(sem1), 0); T_ledOff = osThreadCreate(osThread(led_Thread2), NULL); T_ledOn = osThreadCreate(osThread(led_Thread1), NULL); osKernelStart (); // start thread execution }
CMSIS-RTOS 時間管理之時間延遲Time Delay