新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 時間觸發 合作式調度器 編程模式

        時間觸發 合作式調度器 編程模式

        作者: 時間:2013-10-11 來源:網絡 收藏
        引言

        目前,RTOS特別是搶先式RTOS在嵌入式系統中的應用越來越廣泛,但是還有很大一部分產品使用是小型單片機。這些系統由于成本的限制,通常資源非常有限,比如ROM往往小丁32 KB,RAM小于2 KB,由于RTOS對每個任務都要開辟單獨內存區域,存放任務的上下文和各任務獨立的堆棧,所以在這種系統中使用RTOS非常勉強。對于這些低成本資源受限系統通常采用“前后臺”(或者叫“超級循環”)結構進行編程,這實際上是一種事件觸發的,當中斷數目較多且系統完成的功能相對復雜時,就會使系統的程序編寫變得非常復雜并使系統運行的可預測性迅速下降。

        針對這個問題,Michael J.Pont提出了一種“基于”,這種方法有助于降低CPU的負荷并減少存儲器的使用量,提高系統行為的可預測性,并使程序的結構變得簡潔。但是在實際使用中,當系統中不同的任務對時間要求差異較大時,“基于”難以給出簡單有效的解決方案。為此,對“基于的編程模式”進行了改進,使之適應性更強,可以為成本和資源受限的小型嵌入式系統提供統一且有效的編程模式。

        1 傳統編程結構的局限性

        當不使用RTOS時,嵌入式軟件通常采用兩種傳統的編程結構進行編程,一種叫“前后臺廳式”或者叫“超級循環結構”,本質上是事件觸發的編程方式;另一種叫時間觸發編程模式,Michael J.Pont的“基于時間觸發的編程模式”即屬于此。

        在實際工作中,當系統稍微復雜時,會發現這兩種方式都有一定局限性,下面以一個實際產品設計中遇到的問題為例來說明。在設計一個用于配電柜的壁裝式智能配電儀表時,CPU的程序設計需完成以下任務:

        ①每半秒對前顯示屏的顯示數據進行一次刷新。
        ②每0.1 s對DI/DO進行一次刷新。
        ③每0.2 s對鍵盤進行一次掃描。
        ④每半秒對測量數據進行一次重新采集和計算。
        ⑤異步串行口與上位機使用Modhus通信,速率最高1 9 200 bps。
        ⑥CPU通過I2C總線與時鐘芯片和EEPROM通信。
        ⑦CPU通過SPI總線與LED數碼管及采集芯片通信。
        ⑧CPU要對所采集的6路信號進行FFT變換。
        ⑨當系統掉電時,CPU要能快速響應,把當前的電度底數寫入EEPROM中。

        上述任務中,任務⑤和任務⑨是強實時性的,如果對串口的收發事件得不到及時響應,接收時會導致字節丟失,發送時會導致字節間時間間隔太大,造成接收方的Modbus幀定界錯誤,對系統掉電事件如果不能及時響應會造成EEPROM的寫入失敗。其他任務只要在指定的周期內能得到執行就行,但是任務⑧比較特殊,使用通常的8位CPU進行6種信號的FFT變換,哪怕每種信號只做128點的FFT,運算一次也要好幾秒。下面來看用傳統編程結構實現上述設計時遇到的困擾。

        1.1 使用“前后臺方式”進行編程

        使用“前后臺方式”進行編程時,為保證任務⑤的及時性,使用了UART中斷,當UART完成一個字節的收發后產生中斷,在中斷程序中將接收到的字符保存在接收緩沖區或從發送緩沖區取下一個待發字符裝入UART進行發送,對Modbus協議的處理可以單獨用一個任務在中斷外處理,這保證了巾斷程序的簡短。為保證任務⑨響應的及時性,也必須為它安排一個中斷。因為當系統掉電時,系統只有不到10 ms的過渡時間,系統如果不能在這個時間內完成相關的操作,系統電壓將跌落至有效電壓以下而喪失工作能力。

        安排好了后臺的中斷任務后再來看看前臺的任務如何完成。這里遇到的最大的挑戰是對任務⑧的處理,因為任務⑧需要的執行時間太長了,簡單的把它當成一個任務處理將影響系統對其他任務的響應,在超級循環中的代碼結構如下:

        while(1){
        任務①;
        任務②;
        ……
        任務⑧;
        }

        由于任務⑧執行一次要幾秒鐘的時間,整個超級循環執行一次至少大于任務⑧需要的時間,也就是說這個超級循環循環一次要幾秒鐘時間,將滿足不了各任務響應時間的要求。

        要解決這個問題,只有把任務⑧拆分成很多個子任務,將每個子任務的耗時壓縮到10 ms左右,并定義好各個子任務完成后的狀態,在超級大循環中每次根據狀態只執行一個子任務,程序結構如下:

        while(1){
        任務①;
        任務②;
        ……
        switch(子任務狀態){
        case 子任務狀態①:
        子任務①;
        break;
        ……
        case 子任務狀態②:
        子任務②;
        break;
        ……
        case 子任務狀態:
        子任務;
        break;
        }
        }

        這樣,就需要把一個耗時幾秒的FFT運算任務拆分成幾百個耗時10 ms左有的子任務,這顯然是不可接受的。除此之外,超級大循環結構隱含的一個缺點就是隨著任務的增加,循環體的執行時間是線性增加的,在實際設計中即使沒有像任務⑧那樣的高耗時任務,當系統功能增加時要保證系統響應的及時性也是一個不小的挑戰。


        上一頁 1 2 下一頁

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 大英县| 靖江市| 喀什市| 福贡县| 攀枝花市| 色达县| 泰和县| 阿拉善右旗| 荔浦县| 察哈| 遂昌县| 京山县| 志丹县| 瑞安市| 蒙城县| 浪卡子县| 惠东县| 长顺县| 余庆县| 雷州市| 彝良县| 百色市| 崇仁县| 文水县| 扶余县| 延庆县| 喀什市| 南丰县| 离岛区| 深圳市| 石林| 任丘市| 南雄市| 富裕县| 敖汉旗| 蓬溪县| 滕州市| 肥西县| 罗平县| 扎兰屯市| 旌德县|