今天在某QQ群里看到有人討論這個問題,正巧我也仔細想了一下。以下是我對這個問題的看法
1.RTOS的RT這詞就是實時的意思,網上很多歸納總結都說RTOS要用在實時性很高的項目,怎么才算是實時性高呢?
假設我們裸機有下面這個段程序
int main() { sys_init(); while(1) { 遠程數據處理_proc(); //通訊模塊接收的數據 10ms 485數據處理_proc(); // 10ms lcd_proc(); 5ms key_proc(); 5ms clock_proc(); 1ms 遠程模塊管理_proc(); //通訊模塊連接服務器等 10ms 采集數據_proc(); //可以是采集電能或其它數據 20ms 處理采集數據_proc(); 30ms 喂狗_proc(); 1ms } }
假設每個函數的處理時間,不考慮中斷,執行一輪循環的總共時間為92ms,我們知道裸機執行程序永遠都是按順序來的,不可能剛結束遠程數據處理_proc(),就會去執行喂狗_proc();,想要執行到喂狗就必須乖乖地把其它任務按照順序執行完,再去執行喂狗。
那么,裸機的問題就出來了,如果cpu當前執行到lcd_proc();,這時候遠程數據來了,先觸發接收中斷,中斷程序把數據給保存,但是有一個問題,就是cpu這時候沒有辦法去處理這段數據(如果有同學為什么不在中斷程序處理,有這個疑問的可以去百度百度為什么不能在中斷處理數據),為什么?因為你是裸機,cpu就得乖乖地把下面的程序都執行完后,才輪到遠程數據處理_proc();。也就是說cpu從lcd_proc()到遠程數據處理_proc(),需要至少72ms,72ms只是根據我們每個任務假設的時間得到的,在實際項目中,根據復雜程度或延時函數等等,說它是10秒也不過分,一切皆有可能。到這里,RTOS的實時到底是什么意思,我想大家應該能從這個例子看出一點頭緒來。
我們把上面這段裸機程序移植到RTOS中,以FreeRTOS為例:
int main() { sys_init(); xTaskCreate(遠程數據處理_task); 10ms 優先級最高,阻塞等待數據 xTaskCreate(485數據處理_task); 10ms xTaskCreate(lcd_task); 5ms xTaskCreate(key_task); 5ms xTaskCreate(clock_task); 1ms xTaskCreate(遠程模塊處理_task) 10ms xTaskCreate(采集數據_task); 20ms xTaskCreate(處理采集數據_task); 30ms xTaskCreate(喂狗_task); 1ms vTaskStartScheduler(); //調度開始 }
遠程數據處理_task的優先級最高,而且是阻塞等待,為什么要阻塞,如果不阻塞,那么cpu會一直運行這個高優先級的任務,其它任務就執行不了。這里使用隊列阻塞,即隊列沒有數據,該任務就會阻塞。其它任務的優先級是一樣的,我們把按照裸機出現的問題放在FreeRTOS中,程序執行到lcd_task(相同優先級的任務采用時間片調度,cpu並不一定是連續5ms都在執行它,時間片大小根據configCPU_CLOCK_HZ,configTICK_RATE_HZ這兩個值決定,這里我們假設1ms,即每個相同優先級的任務,執行1ms就會切換到下一個優先級相同的任務),這時候接收中斷觸發,接收到遠程數據,注意,中斷程序會往隊列中發送數據。這時候,高優先級任務遠程數據處理_task就從阻塞態變成了就緒態,由於它是高優先級的,該任務就會馬上執行,不會像裸機一樣等待72ms。
RTOS的實時性就是體現在這里的。