?? 移植心得.txt
字號:
移植心得
在keil c移植UCOSII有兩個比較特殊的地方。1、局部變量的覆蓋問題。2、函數的再入性問題。
下面我就這兩方面談一下自己的體會。
1、關于局部變量的覆蓋。在PC機上的C編譯器,一般是這樣,在函數調用時臨時給局部變量在堆??臻g中分配地址,函數返回后釋放在堆棧中分配的空間。如果一個函數被遞歸調用,每次調用時局部變量分配的地址空間都不相同,因此不存在局部變量被覆蓋的問題。又由于局部變量是分配在堆??臻g因此函數自然就具有再入屬性。但在keil c中就不一樣了,由于8051系列單片機的堆棧空間小,函數的局部變量是分配在固定的地址空間,在編譯時就已經分配好了,而不是在函數被調用時才動態分配。為了提高內存的使用效率keil c默認會進行變量的覆蓋分析。也就是根據函數的相互調用關系,把不可能同時被調用的函數的局部變量分配在同一空間,這樣既能保證函數的正常執行,又能節約內存空間。
在不具有多任務內核的應用中,在主程序中被調用的函數如果在中斷服務程序中也被調用的話,也會存在局部變量覆蓋的問題。因為有可能在主程序運行此函數時產生一個中斷,在中斷服務程序中也調用了同一函數,在中斷返回時,函數的局部變量有可能已被修改,主程序接著斷點往下運行就可能產生錯誤。在有多任務內核的應用中,情況就更復雜一些,局部變量覆蓋的問題不僅涉及到任務和中斷,同時還涉及到任務和任務之間。
2、關于函數的再入性。在keil c中函數的再入性有兩個概念。一、函數固有的再入屬性。如果函數的行參和局部變量(行參也是局部變量)只使用工作寄存器,也即R0 ~ R7、ACC、 B,那么此函數就具有再入屬性。因為不管應用程序中是否具有多任務內核,R0 ~ R7、ACC、 B在中斷和任務切換時都會被保護,被中斷的函數重新運行時,會恢復被保護的寄存器,因此不會發生錯誤。二、給函數定義再入屬性。在定義函數時用reentrant關鍵字,keil c會建立一個模擬棧,函數的局部變量在模擬棧中動態的分配。8051系列單片機的功能比PC機差多了,采用這種方式效率極差。
函數如果具有再入性,就不存在局部變量被覆蓋的問題;但解決了局部變量覆蓋問題,函數不一定就具有再入性。
本人的移植方法的特點:禁止進行覆蓋分析,解決了局部變量的覆蓋問題。但沒有解決函數再入性的問題。解決函數再入性的問題有很多方法。例如:定義具有固有再入屬性的函數;使用信號量;關中斷等.
和楊屹網友移植的UCOSII的比較:
楊屹網友移植的UCOSII是采用把所有函數用reentrant關鍵字定義,因此函數具有再入屬性同時又解決了局部變量覆蓋問題。以8051的能力模擬堆棧,進行局部變量的動態分配,可想而知其效率十分低下。
在本人移植的版本中,禁止進行覆蓋分析。缺點:占用較多的xdata空間。優點:執行效率高。
和Small RTOS的比較:
Small RTOS是采用手工的方法逐項進行禁止覆蓋。在程序比較大,函數之間調用關系復雜時,要分析清任務和函數之間的調用關系是很困難的。如果漏掉了某些項,也許程序不會馬上出問題,但留下了隱患Small RTOS的功能比UCOSII也要差一些。
感謝:
特別感謝楊屹和陳明計兩位網友的無私奉獻,本人正是受到他們的啟發才會想到這種移植方法。同時也希望大家指出這個版本的不足之處,大家共同學習,共同提高。
聯系方法:LXM650@163.COM
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -