新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 如何構造一個51單片機的實時操作系統

        如何構造一個51單片機的實時操作系統

        作者: 時間:2012-12-18 來源:網絡 收藏

        2 要不要占先

        由上面的分析,如果要保持一個函數可重人,就得使用靜態變量,系統的RAM資源將是一個嚴峻的考驗;如果使用臨界區來保護運行環境,系統的實時性又得不到保證,而且有將占先式任務調度轉為非占先任務調度之虞。顯然,使用靜態變量簡單,但有更多的不適用性,對將來功能的調整也是一個阻礙,一般不被采用。那么,就只能從環境保護上來下功夫了,但是果真只能以進入臨界區犧牲系統的實時性來保證任務不被占先?下面看看臨界保護這一方法的基本思路:

        ①在一個任務中,如果局部變量在其作用域內不被占先切換,則這些變量在任務被剝奪了CPU控制權后,不關心其值也不會影響任務的正確執行;

        ②使用臨界區保護,可以達到上面所提到的要求;

        ③由此導致的實時性能與占先切換的減弱可以接受。由此可知,不被占先是任務保護局部變量的關鍵。既然如此,何不舍棄占先式的任務調度?這不失為一個好的出發點。針對Keil C51,非占先式任務調度,可能是一種更好的方法,更能協調51系列單片機的既定資源。下面編寫這樣一個系統:

        ①使用非占先式任務調度;

        ②可以在小容量的芯片中使用,開發目標是,即使是8051這樣小的芯片,也可使用這個;

        ③支持優先級調度,盡可能保證其實時性。

        3 的實現

        基于以上的分析與目的,近日完成了這個操作系統。在堆棧上借用RTx的管理方法,即當前任務使用全部的堆空間

        3.1 堆棧的初始化與任務的創建

        堆棧的初始化實際是初始化0STaskStackBotton數組,并將當前任務指定為空閑任務,下一個運行任務指定為最高優先級任務,即優先級為零的任務。初始化時,將SP的值存人OSTaslkStackBotton[O],SP+2的值存入OSTaskStacKBotton[1],依此類推。而任務是調用0STa-skCreate函數建立的。實際上只是將任務(假設為n號任務)的地址填人到對應OSTaskStackBotton[n]所指向的位置,并將SP向后移動2個字節,

        為什么要以這樣一種規律而不是其他的方式呢?這是由于在任務建立后,還未進行任務調度之前,各任務的堆棧實際上是它們自身的地址,因而其堆棧深度為2,為了程序的簡便而直接填入。

        void main(void){
        OSInit(); /*初始化OSTaskStackBcBotton隊列*/
        TMOD=(TMOD0XFO)│ 0XOl;
        TL0=0xBF;
        TH0=0xFC;
        TRO=1;
        ETO=1;
        TFO=O:
        OSTaskCreate(TaskA,NULL,0);
        OSTaskCreate(TaskB.NULL,1);
        OSTaskCreate(TaskC,NULL,2);
        OSStart();

        上面這段代碼中,所有任務建立后,便調用OSStart()開始任務調度。OSStart()是一個宏定義,如下所示:
        #deflne OSStart() d0{\
        OSTaskCreate(TaskIdle,NULL,OS_MAX_TASKS);\
        EA=l:\
        return;\
        }while(O)

        首先,它創建了一個空閑任務并打開中斷,然后便返回。返回到哪里了呢?我們知道,空閑任務是優先級最低的任務,當調OSTaskCreate建立時,會將其地址填人到SP的位置,并把SP向后移動2個字節(見圖2及說明),因而此時處在堆棧頂端的,一定是空閑任務Taslddle。這就使得這里的return一定會返回到空閑任務。至此,系統進入正常運行狀態。

        3.2 任務的切換

        任務的切換分兩種情況,在當前任務優先級低于下一個取得CPU控制權的任務時,將下一個取得CPU控制權的任務的棧頂到當前任務的棧頂之間的內容向RAM空間的高端搬移,以空出全部的RAM空間作下一個任務的堆空間,同時更新對應的OSTaskStackBotton,使其指向新的正確任務的堆棧棧底。如果當前任務的優先級高于下一個任務的優先級,則作相反的搬移,

        所有任務必須主動調用,放棄CPU的控制權。任務調用后,將選擇優先級最高的就緒任務運行。

        結 語

        系統完成后,內核的代碼量在400多個字節左右,占用1個定時器中斷及小量的內存空間。系統設置容量為8個任務,用戶實際可用任務為7個,能夠滿足一般需求,也達到了在小容量芯片中應用的開發要求。由于沒有采用占先式的任務調度,除開全程相關的個別任務的一些局部變量外,其他局部變量已經不存在覆蓋關系,由于是任務主動放棄CPU控制權,對于個別需要保護的變量單獨進行處理也變得容易。在系統中,全程不需要反復地開關中斷,實時性能也很好。對個別時序要求嚴格的外設(如DSl8820)除外。


        上一頁 1 2 下一頁

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 阜平县| 三河市| 平舆县| 七台河市| 灵川县| 茌平县| 荃湾区| 饶河县| 揭东县| 阿坝| 舒城县| 韶山市| 慈利县| 德昌县| 宣汉县| 海南省| 永顺县| 来凤县| 师宗县| 榆中县| 咸阳市| 会东县| 都江堰市| 玉溪市| 上犹县| 东辽县| 平谷区| 元谋县| 无锡市| 康乐县| 焦作市| 孟连| 聊城市| 思南县| 延寿县| 岳池县| 新源县| 五常市| 平昌县| 册亨县| 南投县|