嵌入式控制系統設計/設計模式
|
嵌入式控制系統設計的 Wikibook
嵌入式控制系統設計
|
針對即時環境的程式設計非常困難,需要對整個系統(硬體和軟體)有很好的理解。在理想情況下,系統的每個部分都得到了很好的描述並且易於理解,但現實世界很少允許這種理想情況。因此,系統應該對系統中的不確定性具有魯棒性。設計模式對所有設計人員都是有用的支援:它們是基於過去大量系統中已有效方法的針對常見問題的通用解決方案。模式也適用於建立可在多個應用程式中重用和調整的可移植程式碼。
設計模式總是帶有一定的上下文:它們是一系列設計力量的結果,這些力量將設計拉向不同的方向,而模式則提供了一種平衡的解決方案。但是,不同系統中的力量可能如此不同,以至於由此產生的權衡也導致了不同的模式。
當為微控制器(如 PICmicro)程式設計時,程式通常是用機器語言或低階語言(如組合語言)編寫的。彙編程式往往更小,並且在活動記憶體中效率更高。儘管如此,當控制器擁有足夠的資源時,也可以使用更高級別的語言,例如 C。文章"使用高階程式語言"簡要列出了使用高階語言相對於組合語言的優勢。(甚至更高級別的語言也具有相對於 C 的相同優勢,但它們很少在小型微控制器上可用)。
在本節中,我們將僅討論在組合語言程式設計中使用的設計模式。這些設計模式看起來非常基礎,但對其有很好的理解非常重要。不需要掌握組合語言知識,但對理解本節有所幫助。
當您經常需要執行相同的操作時,可以使用子程式。透過將值放入暫存器中,您可以向子程式傳遞引數。子程式的結果也將儲存在暫存器中。這裡我們給出一個簡單的子程式示例
Start movlw 02h ; Put the value 02h in the working register W
movwf PORTA ; Move the value from the working register W into memory location PORTA, this will turn on a led
call Delay ; Call subroutine
movlw 00h ; Put the value 00h in the working register W
movwf PORTA ; Move the value from the working register W into memory location PORTA, this will turn off a led
goto Start
Delay ; Subroutine Delay
Loop1 decfsz COUNT,1 ; decrease value of COUNT, and skip next instruction if zero
goto Loop1 ; goto label Loop1
return
有時您需要一個可以儲存值的結構。或者您需要進行轉換,但從表中獲取值更容易。然後使用資料表非常方便。
在 PICmicro 上,常量資料表(在 Flash 記憶體中)是一種正常的子程式。當呼叫子程式時,工作暫存器中的值將用於確定處理器必須跳過的指令數量。這是透過增加“程式計數器”來完成的?程式計數器是當前執行的指令的地址。增加計數器將使處理器跳過後續指令。一個小例子,在資料表中,我們有 5 個 LED(5 位)閃爍的順序。
Start movlw 05h ; Put value 5 in the working register (this is initialization value)
movwf COUNT1 ; Assign the value of the working register to COUNT1
Loop1 call Table ; Look the pattern in the table
movwf PORTA ; Move the pattern of the working register to the led register
call Delay ; Call subroutine
decf COUNT1,F ; Decrease, put a byte in the COUNT1 register
btfsz STATUS,Z ; Test if overhead
goto Loop1 ; No, get next pattern
goto Start ; Yes, run the program from the start again
Delay ; Subroutine delay
Loop2 decfsz COUNT2,F ; Decrease value of COUNT1, and skip next instruction if zero
goto Loop2 ; Goto label Loop2
return
Table addwf PCL ; Add value to get pattern
retlw 01h ; Return pattern 00001b, LED1 - ON
retlw 02h ; Return pattern 00010b, LED2 - ON
retlw 03h ; Return pattern 00100b, LED3 - ON
retlw 04h ; Return pattern 01000b, LED4 - ON
retlw 05h ; Return pattern 10000b, LED5 - ON
- 文章PIC“微控制器記憶體方法:表格”詳細介紹了訪問表格的各種方法,“跨越 256 位元組頁面邊界”的陷阱(在長度超過 256 位元組的表格中始終發生,有時甚至在非常短的表格中也發生),以及解決方法。
- 文章“檔案選擇暫存器”討論了檔案選擇暫存器,該暫存器用於讀取和寫入RAM 中的值陣列。
待辦事項:編寫有關基本中斷程式設計的內容
我們將在後面的章節中斷服務中詳細討論中斷服務。
看門狗定時器是處理器中的一個內部定時器。該定時器的目的是避免嵌入式控制器卡死。
看門狗定時器的原理很簡單,它在預定義的時間後重置嵌入式控制器。但這隻有在程式沒有首先重置看門狗定時器的情況下才會發生。
因此,程式應該在預定義的時間內重置看門狗定時器。當看門狗定時器未及時重置時,程式可能卡死,微控制器將自行重置。另請參閱:RTOS 看門狗定時器,看門狗定時器。
彙編程式通常是特定於硬體的,並且不太可移植和模組化。這使得大型複雜系統的程式設計變得相當困難。這可以透過使用處理處理器和硬體介面的“抽象層”來解決。此層也稱為系統的“核心”。核心還負責硬體特定的呼叫和任務管理,這使得能夠專注於最重要的任務;建立即時程式。當然,需要更多時間和更多記憶體,但這使程式更靈活和模組化。此外,使用更高級別的程式語言也使程式碼更易於移植和除錯。
在下一節中,我們將描述一些重要的設計模式。
即時程式設計中最重要的困難在於確保指定的操作會在確定的時刻發生。因此,準確瞭解每個操作需要多長時間非常重要。
此模式包含兩個部分。在第一部分中,執行時間不可預測的所有操作都已完成。這包括記憶體分配、硬體初始化和物件建立。此部分稱為系統配置。配置完成後,即可啟動主迴圈。
更多資訊:邏輯架構與物理架構
更多資訊:C++
- 所有記憶體分配應在啟動之前完成。
非同步/同步設計模式也稱為
- 中斷服務例程/延遲服務例程 (ISR/DSR)
- 一級中斷處理程式/二級中斷處理程式 (FLIH/SLIH)
- 快速中斷處理程式/慢速中斷處理程式
- 中斷上半部分/中斷下半部分
當資料到達輸入時,處理器將執行預定義的中斷函式。有時需要在使用資料之前對其進行處理。應儘可能縮短中斷函式的執行時間,以允許新資料到達,並避免錯過新資料(由於中斷鎖定)。
在此設計模式中,資料處理分為兩個階段。
- 中斷服務例程 (ISR):這是在中斷髮生時處理資料的函式。通常,它只是讀取輸入上的資料並將其寫入緩衝區。它在停用中斷的情況下執行,並以“中斷返回”結束,該操作啟用中斷。
- 延遲服務例程 (DSR):這是一個在後臺持續執行並處理新資料的函式。它在啟用中斷的情況下執行,並以正常的“返回”結束。
- 無資料丟失。
- 有時可能會有超過所需數量的資料到達。然後,DSR 函式將僅處理所需的資料。
此模式也稱為狀態模式或FSM模式。
系統通常由不同的狀態或階段組成,每個狀態都必須完成一些操作。因此,嵌入式控制器應該根據系統的狀態對輸入做出不同的反應。
這可以透過程式設計 FSM 來實現,這是一個類,其中函式的行為根據系統的狀態而有所不同。
我們將在後面的章節中更詳細地討論有限狀態機,嵌入式控制系統設計/有限狀態機與Petri網
死鎖是指兩個或多個相互競爭的程序都在等待對方完成,從而導致兩者都無法繼續執行的情況。這通常表現為類似於“先有雞還是先有蛋”這樣的悖論。
在計算機領域,死鎖指的是一種特定情況,即兩個或多個程序都在等待另一個程序釋放資源,或者多個程序以環形鏈的方式等待資源(參見必要條件)。死鎖是多程序中常見的問題,在多程序中,許多程序共享一種特定型別的互斥資源,稱為軟體或軟鎖。用於分時和/或即時市場的計算機通常配備硬體鎖(或硬鎖),它保證了對程序的獨佔訪問,強制進行序列化。死鎖尤其令人頭疼,因為沒有通用的解決方案可以避免(軟)死鎖。
這種情況可以比作兩個人在畫圖,他們之間只有一支鉛筆和一把尺子。如果一個人拿了鉛筆,另一個人拿了尺子,當拿鉛筆的人需要尺子,而拿尺子的人需要鉛筆時,就會發生死鎖,在他們放棄尺子之前。這兩個請求都無法滿足,因此發生了死鎖。
在排程中,優先順序反轉是一種反模式。優先順序反轉發生在低優先順序任務持有高優先順序任務所需的共享資源時。這會導致高優先順序任務的執行被阻塞,直到低優先順序任務釋放資源,從而有效地“反轉”了這兩個任務的相對優先順序。如果在此期間某些不依賴於共享資源的中等優先順序任務嘗試執行,它將優先於低優先順序任務和高優先順序任務。
在某些情況下,優先順序反轉可能不會造成直接的危害——高優先順序任務的延遲執行沒有被注意到,並且最終低優先順序任務會釋放共享資源。但是,在許多情況下,優先順序反轉也會導致嚴重的問題。如果高優先順序任務被剝奪了資源,則可能導致系統故障或觸發預定義的糾正措施,例如看門狗定時器重置整個系統。火星探路者遇到的麻煩是即時系統中優先順序反轉導致問題的經典案例。
優先順序反轉還可以降低系統的感知效能。低優先順序任務通常具有較低的優先順序,因為它們不必立即完成(例如,它們可能是批處理作業或其他非互動式活動)。類似地,高優先順序任務具有較高的優先順序,因為它們更有可能受到嚴格的時間約束——它可能正在向互動式使用者提供資料,或根據即時響應保證執行操作。由於優先順序反轉會導致低優先順序任務的執行阻塞高優先順序任務,因此它可能導致系統響應能力降低,甚至違反響應時間保證。
連結:http://www.eventhelix.com/RealtimeMantra/Patterns/
連結:http://technology.niagarac.on.ca/staff/mboldin/18F_Instruction_Set/