μC/OS-II在總線式數據采集系統中的應用
2.2 內核的移植
內核的移植也就是使實時內核能夠在某個微處理器或微控制器上正常運行。移植工作包括以下幾個內容:
(1)在OS_CPU.H中用#define定義三個宏,聲明C96中能夠識別的數據類型和堆棧的增長方向。
(2)在OS_CPU.C中用C語言重新編寫以下幾個函數:OSTaskStkInit、OSStartHighRdy、OSTaskCreateHook、OSTaskSwHook、OSTaskDelHook、OSTaskStatHook、OSTimeTickHook。
(3)在OS_CPU.ASM中編寫幾個匯編語言函數LoadCtx()、OSCtxSw()、OSIntCtxSw()、OSTickISR()。
2.3 實時內核在應用中應注意的問題
一個實時系統的軟件由實時操作系統加上應用程序構成。應用程序與操作系統的接口通過系統調用來實現。用80C196KB作為系統的MCU,只能用內部RAM作為TCB和所有系統存儲器(含各種控制表)以及各個任務的工作和數據單元。因此一定要注意以下幾點:
(1)為各個任務分配各自的堆棧區,該堆棧區既作為任務的工作單元,也作為任務控制塊的保護單元。
(2)系統的任務控制塊只存放各任務的堆棧指針,而任務的狀態均存放于任務堆棧中。在一個任務退出運行時,通過中斷把它的狀態進棧,然后把它的堆棧指針保存于系統的TCB中;再根據優先級取出優先級最高的已就緒任務的堆棧指針SP映象值送入SP中;最后執行中斷返回指令轉去執行新任務。
(3)各任務的數據和工作單元盡量用堆棧實現,這樣可以允許各任務使用同一個子程序。使用堆棧實現參數傳遞并作為工作單元,而不使用絕對地址的RAM,可實現可重入子程序。該子程序既可為各個任務所調用,也可以實現遞歸調用。
2.4 應用μC/OS-II實時內核的主要部分
(1)任務的分配
實時系統中的任務有別于前后臺系統中的子程序模塊,任務是處理機按程序處理數據的過程,是個動態的概念。一般一個任務對應于一段獨立的主程序,它可能調用各種子程序,并使用各種系統資源如中斷、外設等,以完成某種選定的功能,且允許多個任務并行。根據該系統的性能指標和技術要求,可對系統進行如下的任務劃分:按鍵中斷、LCD顯示、串行通信、打印與報警、信道巡檢A/D采樣與數據處理、系統信息顯示、系統工作參數測量、電源切換與充電管理共八個任務。
(2)任務的調度
μC/OS-II的任務調度是按優先級進行的,根據各任務的實時性要求及重要程度,分別置它們的優先級為4、9、8、7、6、11、10、5。其中0、1、2、3、OS_LOWEST_PRIO-3、OS_LOWEST_PRIO-2、OS_LOWEST_PRIO-1、OS_LOWEST_PRIO這幾個優先級保留以被系統使用。優先級號越低,任務的優先級越高。這樣程序之間的通信可以通過按鍵中斷置標志來實現,其中按鍵中斷的優先級最高。當其它任務運行時,按鍵中斷將使得系統服務轉向運行按鍵中斷處理子程序ISR。當中斷處理子程序運行完后,轉向判斷就緒狀態任務的優先級別。如果發現有比中斷前任務優先級更高的任務,則轉向執行該任務。先判斷其運行標志,如果是‘非’,則又等待。再重復上述過程。如果在執行完ISR后發現沒有比中斷前任務優先級更高的,則轉向中斷前的子程序繼續運行。該系統的軟件處理沒有采用優先級轉換的方法,而是采用狀態置位判斷的方法,這樣可以減少程序的復雜性。
(3)任務間的通信
任務間通信最簡便的方法是使用共享數據結構。雖然共享數據區法簡化了任務間的信息交換,但是必須保證每個任務在處理共享數據時的排它性,以避免競爭和數據的破壞。通常與共享資源打交道時,使之滿足互斥條件最一般的方法有以下幾種:
?關中斷;
?使用測試并置位;
?禁止任務切換;
?利用信號量。
在本系統中采用了前兩種。關中斷是一種最簡單快捷的方式,也是在中斷服務子程序中處理共享數據結構的唯一方法。要注意的是:關中斷的時間要盡量短,以免影響操作系統的中斷處理。其應用模式如下:
void Function(void)
{
OS_ENTER_CRITICAL();
…… /*在此處理共享數據*/
OS_EXIT_CRITICAL();
}
測試并置位方式需要有一個全局變量,約定好先測試該變量;如果是約定的數值,則執行該任務,否則不執行該任務。這種方法稱測試并置位(TEST-AND-SET),或TAS。其應用程序如下:
Disable interrupts /*關中斷*/
If ('Access Variable' is 0){ /*若資源不可用,標志為0*/
Set variable to 1; /*置資源不可用,標志為1*/
Reenable interrupts; /*重開中斷*/
Access the resource; /*處理該資源*/
Disable interrupts; /*關中斷*/
Set the 'Access Variable' back to 0;/*清資源不可使用,標志為0*/
Reenable interrupts; /*重新開中斷*/
}else { /*否則*/
Reenable interrupts; /*開中斷*/
/*資源不可使用,以后再試*/
}
(4)時鐘節拍
評論