新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 移植μC/OS-Ⅱ

        移植μC/OS-Ⅱ

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

        ************************************************************************

        本文引用地址:http://www.104case.com/article/201610/305739.htm

        */

        typedefunsignedcharBOOLEAN;

        typedefunsignedcharINT8U;/* 無符號8位整數 */(1)

        typedefsignedcharINT8S;/* 有符號8位整數 */

        typedefunsignedinTINT16U;/* 無符號16位整數 */

        typedefsignedintINT16S;/* 有符號16位整數 */

        typedefunsignedlONgINT32U;/* 無符號32位整數 */

        typedefsignedlongINT32S;/* 有符號32位整數 */

        typedeffloatFP32;/* 單精度浮點數 */(2)

        typedefdoubleFP64;/* 雙精度浮點數 */

        typedefunsignedintOS_STK;/* 堆棧入口寬度為16位 */

        /*

        *************************************************************************

        * 與處理器相關的代碼

        *************************************************************************

        */

        #defineOS_ENTER_CRITICAL()???/* 禁止中斷 */(3)

        #defineOS_EXIT_CRITICAL()???/* 允許中斷 */

        #defineOS_STK_GROWTH1/* 定義堆棧的增長方向: 1=向下,0=向上 */(4)

        #defineOS_TASK_SW()???(5)

        8.03.01與編譯器相關的數據類型

        因為不同的微處理器有不同的字長,所以μC/OS-Ⅱ的移植包括了一系列的類型定義以確保其可移植性。尤其是,μC/OS-Ⅱ代碼從不使用C的short,int和long等數據類型,因為它們是與編譯器相關的,不可移植。相反的,我定義的整型數據結構既是可移植的又是直觀的[L8.1(2)]。為了方便,雖然μC/OS-Ⅱ不使用浮點數據,但我還是定義了浮點數據類型[L8.1(2)]。

        例如,INT16U數據類型總是代表16位的無符號整數?,F在,μC/OS-Ⅱ和用戶的應用程序就可以估計出聲明為該數據類型的變量的數值范圍是0-65535。 將μC/OS-Ⅱ移植到32位的處理器上也就意味著INT16U實際被聲明為無符號短整型數據結構而不是無符號整型數據結構。但是,μC/OS-Ⅱ所處理的仍然是INT16U。

        用戶必須將任務堆棧的數據類型告訴給μC/OS-Ⅱ。這個過程是通過為OS_STK聲明正確的C數據類型來完成的。如果用戶的處理器上的堆棧成員是32位的,并且用戶的編譯文件指定整型為32位數,那么就應該將OS_STK聲明位無符號整型數據類型。所有的任務堆棧都必須用OS_STK來聲明數據類型。用戶所必須要做的就是查看編譯器手冊,并找到對應于μC/OS-Ⅱ的標準C數據類型。

        8.03.02OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()

        與所有的實時內核一樣,μC/OS-Ⅱ需要先禁止中斷再訪問代碼的臨界段,并且在訪問完畢后重新允許中斷。這就使得μC/OS-Ⅱ能夠保護臨界段代碼免受多任務或中斷服務例程(ISRs)的破壞。中斷禁止時間是商業實時內核公司提供的重要指標之一,因為它將影響到用戶的系統對實時事件的響應能力。 雖然μC/OS-Ⅱ盡量使中斷禁止時間達到最短, 但是μC/OS-Ⅱ的中斷禁止時間還主要依賴于處理器結構和編譯器產生的代碼的質量。 通常每個處理器都會提供一定的指令來禁止/允許中斷,因此用戶的C編譯器必須要有一定的機制來直接從C中執行這些操作。有些編譯器能夠允許用戶在C源代碼中插入匯編語言聲明。這樣就使得插入處理器指令來允許和禁止中斷變得很容易了。其它一些編譯器實際上包括了語言擴展功能,可以直接從C中允許和禁止中斷。為了隱藏編譯器廠商提供的具體實現方法,μC/OS-Ⅱ定義了兩個宏來禁止和允許中斷:

        OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()[L8.1(3)]。

        {

        OS_ENTER_CRITICAL();

        /* ? μC/OS-II 臨界代碼段 */

        OS_EXIT_CRITICAL();

        }

        方法1

        執行這兩個宏的第一個也是最簡單的方法是在OS_ENTER_CRITICAL()中調用處理器指令來禁止中斷,以及在OS_EXIT_CRITICAL()中調用允許中斷指令。但是,在這個過程中還存在著小小的問題。如果用戶在禁止中斷的情況下調用μC/OS-Ⅱ函數,在從μC/OS-Ⅱ返回的時候,中斷可能會變成是允許的了!如果用戶禁止中斷就表明用戶想在從μC/OS-Ⅱ函數返回的時候中斷還是禁止的。在這種情況下,光靠這種執行方法可能是不夠的。

        方法2

        執行OS_ENTER_CRITICAL()的第二個方法是先將中斷禁止狀態保存到堆棧中,然后禁止中斷。而執行OS_EXIT_CRITICAL()的時候只是從堆棧中恢復中斷狀態。如果用這個方法的話,不管用戶是在中斷禁止還是允許的情況下調用μC/OS-Ⅱ服務,在整個調用過程中都不會改變中斷狀態。如果用戶在中斷禁止的時候調用μC/OS-Ⅱ服務,其實用戶是在延長應用程序的中斷響應時間。用戶的應用程序還可以用OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()來保護代碼的臨界段。 但是, 用戶在使用這種方法的時候還得十分小心,因為如果用戶在調用象OSTimeDly()之類的服務之前就禁止中斷,很有可能用戶的應用程序會崩潰。發生這種情況的原因是任務被掛起直到時間期滿,而中斷是禁止的,因而用戶不可能獲得節拍中斷!很明顯,所有的PEND調用都會涉及到這個問題,用戶得十分小心。一個通用的辦法是用戶應該在中斷允許的情況下調用μC/OS-Ⅱ的系統服務!

        問題是:哪種方法更好一點?這就得看用戶想犧牲些什么。如果用戶并不關心在調用μC/OS-Ⅱ服務后用戶的應用程序中中斷是否是允許的,那么用戶應該選擇第一種方法執行。

        如果用戶想在調用μC/OS-Ⅱ服務過程中保持中斷禁止狀態,那么很明顯用戶應該選擇第二種方法。

        給用戶舉個例子吧,通過執行STI命令在Intel80186上禁止中斷,并用CLI命令來允許中斷。用戶可以用下面的方法來執行這兩個宏:

        #defineOS_ENTER_CRITICAL()asmCLI

        #defineOS_EXIT_CRITICAL()asmSTI

        CLI和SCI指令都會在兩個時鐘周期內被馬上執行(總共為四個周期)。為了保持中斷狀態,用戶需要用下面的方法來執行宏:

        #defineOS_ENTER_CRITICAL()asmPUSHF;CLI

        #defineOS_EXIT_CRITICAL()asmPOPF

        在這種情況下,OS_ENTER_CRITICAL()需要12個時鐘周期,而OS_EXIT_CRITICAL()需要另外的8個時鐘周期(總共有20個周期)。這樣,保持中斷禁止狀態要比簡單的禁止/允許中斷多花16個時鐘周期的時間(至少在80186上是這樣的)。當然,如果用戶有一個速度比較快的處理器(如IntelPentiumⅡ),那么這兩種方法的時間差別會很小。



        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 南开区| 新巴尔虎左旗| 庐江县| 巴青县| 彭阳县| 上饶市| 宜良县| 遂溪县| 仁寿县| 开江县| 资讯 | 五家渠市| 大同市| 霍州市| 保康县| 微山县| 奉化市| 阿尔山市| 法库县| 班玛县| 柳江县| 定远县| 台东市| 惠东县| 鹤岗市| 同心县| 三明市| 宁强县| 长宁区| 得荣县| 平乡县| 潮州市| 鲜城| 龙游县| 兰州市| 隆化县| 盐山县| 高淳县| 芜湖市| 如皋市| 鞍山市|