<output id="yn1pw"></output>
    <wbr id="yn1pw"></wbr>

    <form id="yn1pw"><legend id="yn1pw"></legend></form>

  1. 更多課程 選擇中心

    嵌入式培訓
    達內IT學院

    400-111-8989

    嵌入式:傳統編程結構的局限性

    • 發布:嵌入式培訓
    • 來源:嵌入式資訊
    • 時間:2020-09-01 14:31

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

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

    (1)每半秒對前顯示屏的顯示數據進行一次刷行。

    (2)每0.1秒對DI/DO進行一次刷新。

    (3)每0.2秒對鍵盤進行一次掃描。

    (4)每半秒對測量數據進行一次重新采集和計算。

    (5)異步串行口與上位機使用Modbus通信,速率最高19200bps。

    (6)CPU通過IIC總線與時鐘芯片和EEprom通信。

    (7)CPU通過SPI總線與LED數碼管及采集芯片通信。

    (8)CPU要對所采集的6路信號進行FFT變換。

    (9)當系統掉電時,CPU要能快速響應以把當前的電度底數寫入EEprom中。

    上述任務中,任務(5)和任務(9)是強實時性的,如果對串口的收發事件得不到及時響應,接收時會導致字節丟失,發送時會導致字節間時間間隔太大造成接收方的Modbus幀定界錯誤,對系統掉電事件如果不能及時響應會造成EEprom的寫入失敗。

    其它任務只要在指定的周期內能得到執行就行,但是任務(8)比較特殊,使用通常的8位CPU進行6種信號的FFT變換,哪怕每種信號只做128點的FFT,運算一次也要好幾秒。下面來看用傳統編程結構實現上述設計時遇到的困擾。

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

    使用“前后臺方式”進行編程時,為保證任務(5)的及時性,使用了UART中斷,當UART完成一個字節的收發后產生中斷,在中斷程序中將接收到的字符保存在接收緩沖區或從發送緩沖區取下一個待發字符裝入UART進行發送,對Modbus協議的處理可以單獨用一個任務在中斷外處理,這保證了中斷程序的簡短。

    為保證任務(9)響應的及時性,也必須為它安排一個中斷。因為當系統掉電時,系統只有不到10ms的過渡時間,系統如果不能在這個時間內完成相關的操作,系統電壓將跌落至有效電壓以下而喪失工作能力。

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

    while(1)

    {

    任務(1);

    任務(2);

    ………

    任務(8);

    }

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

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

    while(1)

    {

    任務(1);

    任務(2);

    ………

    Switch (子任務狀態)

    {

    case 子任務狀態1:

    子任務1;

    break;

    case 子任務狀態2:

    子任務2;

    break;

    …………

    case 子任務狀態n:

    子任務n;

    break;

    }

    }

    這樣,就需要把一個耗時幾秒的FFT運算任務拆分成幾百個耗時10ms左右的子任務,這顯然是不可接受的。

    除此之外,超級大循環結構隱含地一個缺點就是隨著任務的增加,循環體的執行時間是線性增加的,在實際設計中即使沒有象任務(8)那樣的高耗時任務,當系統功能增加時要保證系統響應的及時性也是一個不小的挑戰。

    1.2 使用“時間觸發編程模式”進行編程

    “時間觸發編程模式”的核心是建立一個基于時間觸發的合作式的任務調度器,在系統中盡量減少事件觸發(減少中斷的使用),系統通過任務調度器完成各任務的調度執行,下面是“時間觸發編程模式”的典型程序結構:

    /*--------------------主函數-----------------------*/

    Void main(void)

    {

    SCH_Init();//設置調度器

    SCH_Add_Task(任務函數名,任務調度延遲,任務調度周期);//將任務加入調度器的任務隊列

    SCH_Start();//刷新任務隊列

    while(1)

    {

    SCH_Dispatch_Tasks(); //執行任務調度器

    }

    }

    /*-------------------定時中斷函數---------------------*/

    Void SCH_Update(void) interrupt

    {

    //刷新任務隊列

    }

    系統中每個任務都定義了優先級、任務循環周期和任務延遲時間,系統時器中斷程序SCH_Update()按設定的節拍對任務隊列進行刷新,在超級大循環中只執行任務調度器SCH_Dispatch_Tasks(),根據任務隊列的狀態安排任務的執行。

    這種編程結構避免了超級大循環結構循環時間隨代碼量的增加而線性增加的問題,但是,由于任務是不可剝奪的,一旦任務啟動執行,任務調度器只有在當前任務完成后才有機會執行,這就要求每個任務占用CPU的時間不能太長,否則將影響整個系統的響應速度。

    所以,FFT運算在這種編程模式下還是必須進行有效的拆分,否則就必須提高CPU的檔次或使用可剝奪型的搶先式RTOS,這勢必造成系統成本的增加。那么有沒有更好的解決辦法呢?

    編程結構對“時間觸發編程模式”進行了改進,使之在不提高硬件成本的情況下,使編程人員更直觀地定義任務,減少任務特性對系統程序結構的沖擊,使程序結構簡單明了并提高系統的實時響應速度。

    對于“時間觸發編程模式”咱們下一篇詳細了解。最后,達內嵌入式培訓機構提醒每一個it愛好者:如果你想要在短時間內快速入門,順利掌握一門技術,建議還是認真學習視頻。多練習,多動手。

    版權聲明:轉載文章來自公開網絡,版權歸作者本人所有,推送文章除非無法確認,我們都會注明作者和來源。如果出處有誤或侵犯到原作者權益,請與我們聯系刪除或授權事宜。

    預約申請免費試聽課

    填寫下面表單即可預約申請免費試聽!怕錢不夠?可就業掙錢后再付學費! 怕學不會?助教全程陪讀,隨時解惑!擔心就業?一地學習,可全國推薦就業!

    上一篇:嵌入式系統開發中如何提升技巧?
    下一篇:嵌入式:對“時間觸發編程模式”的改進

    單片機:寫1清零,寫0清零,有什么區別?

    嵌入式工程師一定不要亂用全局變量

    嵌入式培訓靠譜嗎?就業怎么樣?

    新手如何學習單片機?

    • 掃碼領取資料

      回復關鍵字:視頻資料

      免費領取 達內課程視頻學習資料

    • 視頻學習QQ群

      添加QQ群:1143617948

      免費領取達內課程視頻學習資料

    Copyright ? 2021 Tedu.cn All Rights Reserved 京ICP備08000853號-56 京公網安備 11010802029508號 達內時代科技集團有限公司 版權所有

    選擇城市和中心
    黑龍江省

    吉林省

    河北省

    湖南省

    貴州省

    云南省

    廣西省

    海南省

    高清在线不卡一区二区_2019最新国产高清不卡a_亚洲欧洲日本aⅴ 百度 好搜 搜狗
    <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>