跳轉到內容

嵌入式控制系統設計/設計模式

來自Wikibooks,開放世界中的開放書籍
的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/

華夏公益教科書