解決軟件和硬件接口問題的嵌入式系統(tǒng)設計實例
嵌入式系統(tǒng)設計中,軟件和硬件的接口問題經(jīng)常困擾軟件開發(fā)工程師。正確理解接口在處理器與高級語言開發(fā)環(huán)境方面的約束條件,可以加速整個系統(tǒng)設計,并為改進系統(tǒng)的質量、性能和可靠性以及縮短開發(fā)周期和減少成本提供保證,本文從兩個設計實例的比較入手,介紹了嵌入式系統(tǒng)的設計原則以及關于寄存器及其域的種種考慮。
嵌入式系統(tǒng)設計通常分為兩個部分:硬件設計和軟件開發(fā)。這兩部分任務通常由不同的設計小組負責,相互間很少有覆蓋的地方。由于軟件小組很少涉足前面的硬件設計,采用這種方式進行開發(fā)經(jīng)常會遇到問題,特別是硬件與軟件開發(fā)環(huán)境之間的接口性能較差時,會導致系統(tǒng)開發(fā)時間延長、開發(fā)成本提高,最終推遲產(chǎn)品的上市。
最理想的解決方案是軟件小組參與硬件設計,但是在時間安排、資金和人員方面往往又是不實際的。一種變通的方法是創(chuàng)建一套硬件接口規(guī)范來加速軟件開發(fā)流程。從軟件開發(fā)者的角度來理解最優(yōu)化的硬件接口設計能有效地防止軟件開發(fā)中出現(xiàn)不必要的硬件問題,這種方法對硬件設計流程造成的影響也很小。
嵌入式系統(tǒng)結構的一般模型
從系統(tǒng)角度看,嵌入式系統(tǒng)是多種系統(tǒng)要素之間的很多接口的集合,這里羅列的主要資源是系統(tǒng)處理器。處理器接口可以分成兩大類,分別標識為本地總線和硬件總線。值得注意的是,本文中的總線是根據(jù)處理器利用資源時的訪問類型單獨定義的,與具體的硬件連接沒有對應關系。
本地總線是資源與處理器之間的接口總線,它允許無限制的連續(xù)訪問。無限制訪問意味著處理器能夠利用其內部數(shù)據(jù)類型(如字節(jié)、字和雙字)訪問一個資源的所有要素;連續(xù)訪問是指所有資源要素占用的資源地址空間是連續(xù)的,中間沒有任何間隔。RAM和EPROM就是與本地總線接口的常見范例。
硬件總線與資源的連接通常有某些限制,如大小、位置、尋址、地址空間或重定位等。只接受字寫入的I/O端口,或者使用前必須先作映射的PCI總線上的外圍芯片是硬件總線接口的一些實例。采用硬件總線連接對軟件設計工程師訪問資源有一定的限制,可能在軟件設計、開發(fā)和集成過程中產(chǎn)生復雜代碼和代碼錯誤。
正確的硬件總線接口設計能夠加快軟件設計進程,通常也能加快硬件驗證速度。本文重點介紹與可編程邏輯資源相連接的硬件總線的設計與實現(xiàn)。
系統(tǒng)定義的實例
這里考慮兩種不同的硬件實現(xiàn)方式。該系統(tǒng)是處理器控制的三軸伺服系統(tǒng),本部分的系統(tǒng)設計僅限于位置反饋控制的設計,因此有助于我們專注于硬件接口的實現(xiàn)。
該系統(tǒng)的兩種實現(xiàn)方式都實現(xiàn)了處理器與用戶ASIC(或FPGA)的接口,從而為三軸伺服提供驅動與反饋信息。每個系統(tǒng)中的ASIC必須利用32位數(shù)據(jù)總線使處理器與三套驅動/反饋資源連接。每種資源包含有一個帶符號的10位驅動寄存器、一個帶符號的8位位置寄存器和一個3位的錯誤狀態(tài)寄存器,任何一個位置位都表示一種錯誤狀態(tài),由它產(chǎn)生軸驅動(axis drive)的關閉信息。
圖1和圖2表示了一種寄存器接口的可能實現(xiàn)方式,分別標識為系統(tǒng)實現(xiàn)A和系統(tǒng)實現(xiàn)B。為了描述方便,后文以系統(tǒng)A和系統(tǒng)B分別指代這兩種實現(xiàn)。
當采用VHDL(或其它高級硬件設計方法)實現(xiàn)時,這兩種硬件接口的設計復雜性幾乎是相等的。系統(tǒng)A顯得稍微高效些,因為其寄存器地址譯碼相對簡單些,所采用的硬件數(shù)量也比系統(tǒng)B少。為了減少與處理器接口的可編程器件中邏輯單元的數(shù)量,大多數(shù)硬件設計工程師會選擇系統(tǒng)A的實現(xiàn)方式。
表1所示的偽隨機碼為軸驅動程序,可用于A、B兩個系統(tǒng)。偽隨機碼設計用于基于先進處理器的系統(tǒng)實現(xiàn),并運行于實時操作系統(tǒng),以通用軸控制程序的三份獨立挎貝(或任務實例)實現(xiàn)軸的控制。當使用系統(tǒng)A中定義的接口時只需偽隨機碼中那些帶星號的代碼行。
很明顯,即使在代碼原型階段系統(tǒng)B所需的代碼也比系統(tǒng)A少很多。系統(tǒng)B中的硬件設計要稍微復雜一些,但能減輕軟件開發(fā)的負擔。后文將回顧這兩個實例系統(tǒng)和偽隨機碼。
在閱讀本文時,硬件設計工程師可能會產(chǎn)生這個問題:“為什么第一個設計的效率要比第二個低?”。兩種實現(xiàn)方式控制軸向操作的參數(shù)是相同的,而第一種方法所需的可編程硬件器件數(shù)量顯然要比第二種少。為了正確回答這個問題,設計工程師必須從系統(tǒng)的角度來看待這個設計,而不是硬件設計工程師慣用的“邏輯門”角度。下一部分將闡述硬件設計工程師開發(fā)系統(tǒng)硬件接口時常會遇到的一些概念,將進一步討論這些技術,并檢查將這些概念應用于實例系統(tǒng)設計后的結果。
為了滿足項目要求,對整個系統(tǒng)結構進行優(yōu)化時需要在硬件與軟件實現(xiàn)之間作出折衷,現(xiàn)實中是沒有項目能滿足這里提到的所有理想軟件接口要求的。對理想狀態(tài)的認識有助于硬件設計工程師識別并消除影響軟件設計的一些障礙。
設計原則
1. 采用標準總線訪問
有效的嵌入式硬件接口設計的一般原則是:對軟件設計工程師來說,硬件設計應確保對硬件資源的訪問盡可能透明。處理器使用所有標準的讀寫指令可以實現(xiàn)透明訪問,而不用考慮前面的訪問內容或時序。
像頁寄存器設置、地址線上的寫數(shù)據(jù)編碼等都可能嚴重影響代碼的開發(fā),并常常需要開發(fā)標準訪問與所需特殊訪問之間完成相互轉換的驅動程序。
通常不可避免要采用一些特殊總線,但需要慎重考慮特殊訪問空間的使用選擇,因為這種情況會給系統(tǒng)軟件設計帶來一定的困難。系統(tǒng)A采用了只寫寄存器,因此要求系統(tǒng)軟件提供“影子”內存(Shadow memory)來保存寫入到資源的數(shù)據(jù)。而系統(tǒng)B由于允許所有的寄存器都可讀寫,因此沒有這種限制。
2. 開發(fā)基于處理器的資源接口
硬件設計工程師習慣于從下至上分析資源接口問題以及與系統(tǒng)總線的連接,而通過分析處理器在系統(tǒng)中對資源的訪問過程則更好。
“處理器與資源”間的接口常常是最重要的接口,在硬件設計流程中它的效率應是最優(yōu)先考慮的對象。統(tǒng)一規(guī)劃整個系統(tǒng)的資源訪問對于正確理解由硬件設計選擇所引起的訪問限制很重要。
現(xiàn)有最先進的系統(tǒng)包含有存儲控制器和可再映射總線,它們會改變處理器與資源接口之間的訪問類型。一般地說,一個不合格的硬件接口設計在軟件小組試圖與實際資源連接前是不可能反映出來的,這一點對于設計硬件接口很重要。
3. 系統(tǒng)內存映射的創(chuàng)建與維護
對于一個好的系統(tǒng)設計來說,所有資源的存儲器映射都非常重要。如前所述,存儲器映射的設計應考慮到具體處理器要求,而不是簡單地說明一個資源所解碼的地址線類型。如果采用的是寄存器可配置資源,如PCI總線,硬件設計工程師應在存儲器映射中配置所有與該資源有關的配置寄存器,并提供用以創(chuàng)建硬件驗證所需的靜態(tài)映射的配置寄存器初始化值。
硬件設計工程師還必須認真考慮動態(tài)重配置的優(yōu)越性。在可重配置總線上沒有新增(或減少)資源的系統(tǒng)能演變成一個靜態(tài)映射,方法是強迫配置寄存器在系統(tǒng)復位后回復到同一值。這個“靜態(tài)”系統(tǒng)圖為硬件集成和軟件開發(fā)提供了一個穩(wěn)定的統(tǒng)一結構,同時還避免了在系統(tǒng)代碼中使用易產(chǎn)生錯誤的指針操作。
最后,隨著系統(tǒng)的不斷成熟,存儲器映射也必須不斷完善,并隨著軟硬件開發(fā)的進展不斷改進。
4. 統(tǒng)一的訪問模式
當前的嵌入式系統(tǒng)由于復雜度的提高,通常由多人共同合作進行設計。每個硬件部件的設計必須與整體一致,這樣才能開發(fā)出統(tǒng)一的資源訪問模式。如果不同功能模塊的訪問不一致的話,在軟件開發(fā)期間就會產(chǎn)生潛在的訪問限制錯誤,從而可能需要為每個子系統(tǒng)設計專門的軟件驅動程序。對不同邏輯塊的不一致訪問也會使硬件集成和驗證變得困難重重。
例如設計工程師在調試器上編輯4個十六進制數(shù)字并不能保證處理器會使用一個16位的讀/寫周期,因此,對軟件開發(fā)和硬件集成中使用調試工具設置多種類型的限制訪問也具有一定的困難。這樣看來,評估仿真器處理多個限制性訪問地址空間的能力就非常有用,特別是在用“限制外”訪問方式觸發(fā)總線故障的處理器結構中。
寄存器設計
既然硬件設計工程師的重點已經(jīng)從邏輯門和總線轉移到了系統(tǒng)設計,我們再來審視一下任何處理器系統(tǒng)中最常用到的寄存器設計。寄存器接口允許高速訪問資源,其訪問的效率對系統(tǒng)的性能有很大的影響。
寄存器的結構與訪問
設計工程師應該精心選擇硬件寄存器大小,使處理器能最有效地進行硬件訪問。一般來說,總是采用系統(tǒng)內部整數(shù)訪問方式。寄存器應該被譯碼為連續(xù)的組(沒有地址空檔),這樣可以加速指針或陣列索引對寄存器的訪問。任何可寫的寄存器也應該是以同樣的格式可讀,這樣可以避免使用本地存儲器來緩存這些寄存器值。
控制一個子系統(tǒng)的寄存器應該以相同的結構形式在一起分組,使軟件能使用通用的驅動程序對它們進行訪問。當設計中需要多個同一類型的子系統(tǒng)時這點尤其重要。
為了避免被編碼成獨立進程的軟件任務之間發(fā)生沖突,獨立的子系統(tǒng)不能在系統(tǒng)處理器訪問期間共享可寫寄存器。這些“獨立”的軟件進程在訪問共享寄存器時會產(chǎn)生競爭,除非在系統(tǒng)代碼中使用不可中斷的讀/寫驅動程序。根據(jù)操作系統(tǒng)的不同,多個進程共享寄存器甚至可能會產(chǎn)生功能調用的額外開銷。訪問共享寄存器的同時還有執(zhí)行其它進程的做法是錯誤的,也是軟件設計的通病,會導致間歇性的系統(tǒng)故障,影響集成和測試系統(tǒng)軟件的進度。
系統(tǒng)A違反了很多上文提到的原則,如采用只寫寄存器,共享控制和狀態(tài)寄存器,以及沒有為每個軸提供公共的寄存器映射。系統(tǒng)A必須用專門的驅動程序來緩沖寫輸出數(shù)據(jù),移位并屏蔽軸驅動與位置信息,并防止軸驅動寄存器內容被為每個軸任務編寫的代碼所影響。系統(tǒng)B由于分離并重組了與每個軸有關的寄存器,因此能克服這些問題。
寄存器復位內容
硬件設計工程師應仔細考慮系統(tǒng)的復位狀態(tài)。硬件設計通常采用啟動程序來取得系統(tǒng)啟動后的控制權,并將系統(tǒng)初始化到一個安全的狀態(tài)。系統(tǒng)復位后應將硬件置于一個確定的安全狀態(tài),并且硬件應持續(xù)保持安全狀態(tài)直到系統(tǒng)軟件初始化完成為止。代碼也應在軟件控制下復位硬件以幫助調試、自檢和原始代碼的開發(fā)。
系統(tǒng)A不控制驅動寄存器的復位內容,需要代碼的介入來將所有三個軸的驅動寄存器設置為零。這種結構會產(chǎn)生嚴重的系統(tǒng)設計問題,因為處理器通常是保持在復位狀態(tài),直到FPGA和ASIC加電并得到配置后處理器才正常工作。如果開發(fā)人員使用仿真器,那么在集成過程中系統(tǒng)A還會出現(xiàn)另外的問題:被仿真器控制的處理器在系統(tǒng)加電后可能需要很長的初始化時間才能正常工作。在軟件取得控制權之前系統(tǒng)A和B的軸都處于隨機驅動狀態(tài)。
系統(tǒng)B在加電后會將所有軸驅動寄存器設為零,它對軸驅動設置的控制并不依賴于啟動時間。因為系統(tǒng)B沒有隱藏的狀態(tài)機,因此在本設計中沒有必要考慮增加額外的軟件復位寄存器。
寄存器域設計
大多數(shù)資源接口所包含的數(shù)據(jù)項并不正好適合一個寄存器。這種情況下,硬件設計工程師必須將一個寄存器分成若干域。合理的域結構對系統(tǒng)性能來說非常重要,與寄存器接口設計有相似的影響。有效的域接口設計規(guī)則類似于寄存器設計規(guī)則,但設計工程師還需要特別注意域的順序與放置,還要對寄存器中未用到一些字節(jié)作一定的處理。
1. 寄存器的域
域被定義為寄存器中若干位的子集,主要用于報告或控制資源的一個功能要素。在硬件設計中最常用的域類型有:1. 布爾域:真或假,通常是一位;2. 多位狀態(tài)域和控制域:多位用于報告或控制內部相關功能;3. 列舉狀態(tài)域和控制域:多個位的集合,其中每個位代表了一種不同的硬件狀態(tài);4. 數(shù)字域:多個位組合在一起用來代表一定的數(shù)量值。
從軟件使用者角度看,最有效的域結構是每個寄存器只用一個域。這種理想的軟件結構可能導致硬件實現(xiàn)效率低,因此一個好的系統(tǒng)設計需要在軟硬件設計之間作出折衷,在每個寄存器中應放置多個域。
下文將著重討論一個寄存器中假設存在多個域的情況,不過,當對資源的某個特殊參數(shù)進行的有效訪問將嚴重影響系統(tǒng)軟件性能時,硬件設計工程師仍應該考慮使用單個域的寄存器。
2. 域結構
前文提到的用于寄存器的結構概念同樣也適合于寄存器內部的域。一個寄存器應該只包含屬于設計中同一功能要素的域,并且該寄存器中的所有可寫域都應該是可讀的。
那些包含有屬于多個功能要素的域的寄存器同樣需要特殊驅動程序支持,這樣才能使多個進程安全地訪問每個域。而配置為“只寫”功能的域需要分配影子內存來保存寄存器域中的前一狀態(tài)值。硬件設計工程師原來設想的簡單的“屏蔽/寫”操作現(xiàn)在變成了繁雜的多步功能調用,首先必須禁止中斷和任務切換,然后讀本地存儲器,屏蔽輸入輸出值,再進行硬件寄存器寫,最后開放中斷和多任務切換。如果寄存器中所有域能得到有效安排,通過一個軟件任務就能訪問全部域的話,上述情況就能得到有效避免。
由于系統(tǒng)A將屬于不相關功能的多個域組合放在一個寄存器中,因此它需要使用特殊的驅動程序。而系統(tǒng)B則遵循“單個寄存器內的域按任務進行組織”的原則,將每個域放置在屬于自己的專用寄存器中,因此能高效地訪問資源中的每個軸參數(shù)。
3. 十六進制數(shù)字對齊
硬件設計工程師還應該明白針對處理器和軟件開發(fā)環(huán)境進行對齊約束。如果將域放置在錯誤的地址上而超出字的邊界,將迫使軟件設計工程師只能按塊訪問每個域,進而增加訪問復雜性,降低訪問的速度。在調試過程中,用零值填充域是非常有用的,可以使每個域的最低位對齊十六進制數(shù)字(4位)的邊界:當在邏輯分析儀、調試儀或仿真器上顯示寄存器情況時,十六進制數(shù)字對齊會有助于域值的可視化提取。系統(tǒng)A的寄存器域是沒有對齊的,因此從原始的十六進制數(shù)據(jù)中提取域值很困難。由于控制域沒有對齊,在查錯時屏蔽測試輸入也十分困難。而系統(tǒng)B的所有域都是按十六進制偶數(shù)數(shù)字對齊,因此通過寄存器讀可以很容易地確定每個域的狀態(tài),并且能方便地將某個域設為指定值。
4. 域位置的分配與順序
寄存器內域的設置也會嚴重影響軟件實現(xiàn)的效率。布爾域和多位域通常與位置無關,但當列舉域和數(shù)字域被放置在寄存器的最低位(LSB)時對它們的訪問效率通常是最高的(LSB的實際位數(shù)取決于處理器類型,位0不一定是LSB)。將域配置在寄存器的LSB中可以有效地消除對域內容屏蔽后的移位操作,也使測試設備或進行可視化檢查的調試儀訪問寄存器時能更容易地識別域值。
系統(tǒng)A中用于軸2和軸3的域值在使用前必須要求軟件進行屏蔽和移位。而系統(tǒng)B則將所有數(shù)字域配置在寄存器的LSB中,從而能完成更有效的訪問。系統(tǒng)B的集成性也更好,資源寄存器的十六進制數(shù)據(jù)能真正分離成正確的域值。
5. 未用數(shù)據(jù)位
寄存器中的未用位同樣也會影響軟件實現(xiàn)的效率。所有未用位應回歸為零,并且寫入操作時無需對它們作特殊的處理,這樣可以避免不必要的屏蔽與清除操作。這個規(guī)則的唯一一個例外是包含數(shù)字域為2的補碼的寄存器,并且在寄存器中剩余的最高位(MSB)沒有用的情況。在這種情況下,使硬件實現(xiàn)符號將域的MSB擴展到未用位就非常有用。以這種方式擴展的數(shù)字域能夠被處理器直接訪問,因為帶符號的數(shù)值無需軟件符號的擴展。當對特殊的數(shù)字域變量的訪問速度嚴重影響整體系統(tǒng)性能時,將該類型的域與“單個寄存器單個域”結合起來考慮將非常有用。由于無需屏蔽或符號擴展,這些域能以內部數(shù)據(jù)訪問的方式直接訪問。
當系統(tǒng)A中需要從寄存器提取域值時,要求軟件對每個數(shù)字域值進行符號擴展,而系統(tǒng)B允許通過對寄存器的內部整數(shù)訪問直接訪問域值。
6. 域類型選擇
域類型的正確選擇也能極大地提高軟件實現(xiàn)效率。在打開或關閉獨立資源功能時布爾域是最有效的。要注意的是,只有當寄存器是可讀寫時單位域才容易編碼。如果硬件寄存器對域的訪問有限制,就需要專門的緩沖器(有可能再加上一個專門的驅動程序)來保存當前的內容。限制性訪問同時也會限制一些編程構造的使用,如位域(bit field),從而影響系統(tǒng)代碼的可讀性,且無助于減少編程錯誤。
當表達資源狀態(tài)的數(shù)據(jù)需要占用一定范圍的值時數(shù)字域就很有用。當一個域能保持正值和負值使用時,帶符號的表達式通常需要更多的軟件工作。另外,還要避免在數(shù)字域中對其它數(shù)據(jù)進行編碼(如利用域符號表示一個不相關的資源狀態(tài))。
從硬件實現(xiàn)來看,多位域更有效,但在寫入系統(tǒng)代碼時會增加代碼的復雜度。列舉類型通常能更好地反映資源中相關功能的實際可用性,可以有效防止沖突功能的采用(如將存儲器塊切換到本地總線上)。列舉類型還應提供這樣的可選項:無條件允許切換之間存在“停放帶”,無條件允許系統(tǒng)軟件中存在“先中斷再實現(xiàn)”的代碼切換。
系統(tǒng)A中對軸驅動域的“只寫”訪問使軟件對目標域的訪問效率很低,必須用RAM保存寫過程中不作修改的過去的軸內容。系統(tǒng)B中由于每個寄存器都只有一個域并允許讀寫操作,因此不存在這樣的問題。
實例系統(tǒng)的性能評估
為了評估最終系統(tǒng)軟件的性能,將列表1中的偽隨機碼正確轉換成C代碼并同時用于A、B系統(tǒng)中,然后利用內部存儲器中的結構模擬每個系統(tǒng)的硬件接口。代碼中應避免使用位域,因為標準C實現(xiàn)不能在限制性訪問的地址空間上正確工作。系統(tǒng)代碼模擬運行于PowerPC,編譯工具采用的是Green Hills MultiC,目標操作系統(tǒng)是VxWorks,編譯器設置在中級優(yōu)化度(目的是幫助調試,并允許設計工程師把每條匯編指令與每一行C代碼聯(lián)系起來)。
表1列出了偽隨機碼的每一行,并給出了每個系統(tǒng)實現(xiàn)所用到的匯編指令與功能調用數(shù)量。另外還對兩個實現(xiàn)所用的代碼執(zhí)行速度進行測試。子程序升級系統(tǒng)B軸的速度要比系統(tǒng)A快5.3倍,這主要歸功于任務阻塞與去阻塞功能調用的去除。要注意的是實際系統(tǒng)中的加速效果可能并不明顯,因為實際的硬件訪問時間對總的執(zhí)行時間影響最大。
在實驗中要提升兩個實現(xiàn)所用編譯器的優(yōu)化度,結果發(fā)現(xiàn)優(yōu)化度的提高對系統(tǒng)B無效,對系統(tǒng)A來說只是減少了很少的代碼,并且速度卻稍有降低。這樣的結果表明,系統(tǒng)B的硬件接口在軸域的資源訪問上非常接近內部訪問的效能。
另外,為了對兩種實現(xiàn)所用到的硬件設備進行評估,要用VHDL對硬件接口進行編碼,然后用賽靈思的Webpack軟件進行綜合,并把設計映射到賽靈思的Virtex FPGA中。采用Virtex系列芯片的結果是系統(tǒng)A要消耗56個功能片(slice),系統(tǒng)B要消耗85個功能片。V300E-PQ240器件總共具有3072個片,因此系統(tǒng)A占用可用資源的1.8%,系統(tǒng)B則占2.8%。9500系列器件的內部資源更有限些,比如XC95288XL-PQ208,系統(tǒng)A將占用該器件可用資源的18%,系統(tǒng)B則占30%。
仔細考察這兩個設計發(fā)現(xiàn),系統(tǒng)B所用的額外資源中最主要的驅動源是組合型軸尋址方案。為了驗證這一結果,重新組織寄存器映射,以便將每個軸作為一個獨立資源使用,單個軸映射按地址位邊界對齊。這一變通的實現(xiàn)方式保留了系統(tǒng)B的所有軟件接口優(yōu)點,同時減少了整體硬件器件的使用,Virtex系列器件的片利用率能降低2.3%,9500系列的利用率能降低22%。
硬件設計會極大地影響系統(tǒng)軟件實現(xiàn)的復雜性和質量。一個好的硬件設計要求設計人員能根據(jù)硬件實現(xiàn)與最終軟件設計環(huán)境的復雜性做出決定,正確理解硬件接口設計對軟件開發(fā)流程的影響能極大地改進系統(tǒng)質量、性能和可靠性,同時減少系統(tǒng)開發(fā)的周期與成本。
作者: Christopher Leddy
高級系統(tǒng)工程師
Raytheon公司
Email:caleddy@west.raytheon.com
嵌入式系統(tǒng)設計中,軟件和硬件的接口問題經(jīng)常困擾軟件開發(fā)工程師。正確理解接口在處理器與高級語言開發(fā)環(huán)境方面的約束條件,可以加速整個系統(tǒng)設計,并為改進系統(tǒng)的質量、性能和可靠性以及縮短開發(fā)周期和減少成本提供保證,本文從兩個設計實例的比較入手,介紹了嵌入式系統(tǒng)的設計原則以及關于寄存器及其域的種種考慮。
嵌入式系統(tǒng)設計通常分為兩個部分:硬件設計和軟件開發(fā)。這兩部分任務通常由不同的設計小組負責,相互間很少有覆蓋的地方。由于軟件小組很少涉足前面的硬件設計,采用這種方式進行開發(fā)經(jīng)常會遇到問題,特別是硬件與軟件開發(fā)環(huán)境之間的接口性能較差時,會導致系統(tǒng)開發(fā)時間延長、開發(fā)成本提高,最終推遲產(chǎn)品的上市。
最理想的解決方案是軟件小組參與硬件設計,但是在時間安排、資金和人員方面往往又是不實際的。一種變通的方法是創(chuàng)建一套硬件接口規(guī)范來加速軟件開發(fā)流程。從軟件開發(fā)者的角度來理解最優(yōu)化的硬件接口設計能有效地防止軟件開發(fā)中出現(xiàn)不必要的硬件問題,這種方法對硬件設計流程造成的影響也很小。
嵌入式系統(tǒng)結構的一般模型
從系統(tǒng)角度看,嵌入式系統(tǒng)是多種系統(tǒng)要素之間的很多接口的集合,這里羅列的主要資源是系統(tǒng)處理器。處理器接口可以分成兩大類,分別標識為本地總線和硬件總線。值得注意的是,本文中的總線是根據(jù)處理器利用資源時的訪問類型單獨定義的,與具體的硬件連接沒有對應關系。
本地總線是資源與處理器之間的接口總線,它允許無限制的連續(xù)訪問。無限制訪問意味著處理器能夠利用其內部數(shù)據(jù)類型(如字節(jié)、字和雙字)訪問一個資源的所有要素;連續(xù)訪問是指所有資源要素占用的資源地址空間是連續(xù)的,中間沒有任何間隔。RAM和EPROM就是與本地總線接口的常見范例。
硬件總線與資源的連接通常有某些限制,如大小、位置、尋址、地址空間或重定位等。只接受字寫入的I/O端口,或者使用前必須先作映射的PCI總線上的外圍芯片是硬件總線接口的一些實例。采用硬件總線連接對軟件設計工程師訪問資源有一定的限制,可能在軟件設計、開發(fā)和集成過程中產(chǎn)生復雜代碼和代碼錯誤。
正確的硬件總線接口設計能夠加快軟件設計進程,通常也能加快硬件驗證速度。本文重點介紹與可編程邏輯資源相連接的硬件總線的設計與實現(xiàn)。
系統(tǒng)定義的實例
這里考慮兩種不同的硬件實現(xiàn)方式。該系統(tǒng)是處理器控制的三軸伺服系統(tǒng),本部分的系統(tǒng)設計僅限于位置反饋控制的設計,因此有助于我們專注于硬件接口的實現(xiàn)。
該系統(tǒng)的兩種實現(xiàn)方式都實現(xiàn)了處理器與用戶ASIC(或FPGA)的接口,從而為三軸伺服提供驅動與反饋信息。每個系統(tǒng)中的ASIC必須利用32位數(shù)據(jù)總線使處理器與三套驅動/反饋資源連接。每種資源包含有一個帶符號的10位驅動寄存器、一個帶符號的8位位置寄存器和一個3位的錯誤狀態(tài)寄存器,任何一個位置位都表示一種錯誤狀態(tài),由它產(chǎn)生軸驅動(axis drive)的關閉信息。
圖1和圖2表示了一種寄存器接口的可能實現(xiàn)方式,分別標識為系統(tǒng)實現(xiàn)A和系統(tǒng)實現(xiàn)B。為了描述方便,后文以系統(tǒng)A和系統(tǒng)B分別指代這兩種實現(xiàn)。
當采用VHDL(或其它高級硬件設計方法)實現(xiàn)時,這兩種硬件接口的設計復雜性幾乎是相等的。系統(tǒng)A顯得稍微高效些,因為其寄存器地址譯碼相對簡單些,所采用的硬件數(shù)量也比系統(tǒng)B少。為了減少與處理器接口的可編程器件中邏輯單元的數(shù)量,大多數(shù)硬件設計工程師會選擇系統(tǒng)A的實現(xiàn)方式。
表1所示的偽隨機碼為軸驅動程序,可用于A、B兩個系統(tǒng)。偽隨機碼設計用于基于先進處理器的系統(tǒng)實現(xiàn),并運行于實時操作系統(tǒng),以通用軸控制程序的三份獨立挎貝(或任務實例)實現(xiàn)軸的控制。當使用系統(tǒng)A中定義的接口時只需偽隨機碼中那些帶星號的代碼行。
很明顯,即使在代碼原型階段系統(tǒng)B所需的代碼也比系統(tǒng)A少很多。系統(tǒng)B中的硬件設計要稍微復雜一些,但能減輕軟件開發(fā)的負擔。后文將回顧這兩個實例系統(tǒng)和偽隨機碼。
在閱讀本文時,硬件設計工程師可能會產(chǎn)生這個問題:“為什么第一個設計的效率要比第二個低?”。兩種實現(xiàn)方式控制軸向操作的參數(shù)是相同的,而第一種方法所需的可編程硬件器件數(shù)量顯然要比第二種少。為了正確回答這個問題,設計工程師必須從系統(tǒng)的角度來看待這個設計,而不是硬件設計工程師慣用的“邏輯門”角度。下一部分將闡述硬件設計工程師開發(fā)系統(tǒng)硬件接口時常會遇到的一些概念,將進一步討論這些技術,并檢查將這些概念應用于實例系統(tǒng)設計后的結果。
為了滿足項目要求,對整個系統(tǒng)結構進行優(yōu)化時需要在硬件與軟件實現(xiàn)之間作出折衷,現(xiàn)實中是沒有項目能滿足這里提到的所有理想軟件接口要求的。對理想狀態(tài)的認識有助于硬件設計工程師識別并消除影響軟件設計的一些障礙。
設計原則
1. 采用標準總線訪問
有效的嵌入式硬件接口設計的一般原則是:對軟件設計工程師來說,硬件設計應確保對硬件資源的訪問盡可能透明。處理器使用所有標準的讀寫指令可以實現(xiàn)透明訪問,而不用考慮前面的訪問內容或時序。
像頁寄存器設置、地址線上的寫數(shù)據(jù)編碼等都可能嚴重影響代碼的開發(fā),并常常需要開發(fā)標準訪問與所需特殊訪問之間完成相互轉換的驅動程序。
通常不可避免要采用一些特殊總線,但需要慎重考慮特殊訪問空間的使用選擇,因為這種情況會給系統(tǒng)軟件設計帶來一定的困難。系統(tǒng)A采用了只寫寄存器,因此要求系統(tǒng)軟件提供“影子”內存(Shadow memory)來保存寫入到資源的數(shù)據(jù)。而系統(tǒng)B由于允許所有的寄存器都可讀寫,因此沒有這種限制。
2. 開發(fā)基于處理器的資源接口
硬件設計工程師習慣于從下至上分析資源接口問題以及與系統(tǒng)總線的連接,而通過分析處理器在系統(tǒng)中對資源的訪問過程則更好。
“處理器與資源”間的接口常常是最重要的接口,在硬件設計流程中它的效率應是最優(yōu)先考慮的對象。統(tǒng)一規(guī)劃整個系統(tǒng)的資源訪問對于正確理解由硬件設計選擇所引起的訪問限制很重要。
現(xiàn)有最先進的系統(tǒng)包含有存儲控制器和可再映射總線,它們會改變處理器與資源接口之間的訪問類型。一般地說,一個不合格的硬件接口設計在軟件小組試圖與實際資源連接前是不可能反映出來的,這一點對于設計硬件接口很重要。
3. 系統(tǒng)內存映射的創(chuàng)建與維護
對于一個好的系統(tǒng)設計來說,所有資源的存儲器映射都非常重要。如前所述,存儲器映射的設計應考慮到具體處理器要求,而不是簡單地說明一個資源所解碼的地址線類型。如果采用的是寄存器可配置資源,如PCI總線,硬件設計工程師應在存儲器映射中配置所有與該資源有關的配置寄存器,并提供用以創(chuàng)建硬件驗證所需的靜態(tài)映射的配置寄存器初始化值。
硬件設計工程師還必須認真考慮動態(tài)重配置的優(yōu)越性。在可重配置總線上沒有新增(或減少)資源的系統(tǒng)能演變成一個靜態(tài)映射,方法是強迫配置寄存器在系統(tǒng)復位后回復到同一值。這個“靜態(tài)”系統(tǒng)圖為硬件集成和軟件開發(fā)提供了一個穩(wěn)定的統(tǒng)一結構,同時還避免了在系統(tǒng)代碼中使用易產(chǎn)生錯誤的指針操作。
最后,隨著系統(tǒng)的不斷成熟,存儲器映射也必須不斷完善,并隨著軟硬件開發(fā)的進展不斷改進。
4. 統(tǒng)一的訪問模式
當前的嵌入式系統(tǒng)由于復雜度的提高,通常由多人共同合作進行設計。每個硬件部件的設計必須與整體一致,這樣才能開發(fā)出統(tǒng)一的資源訪問模式。如果不同功能模塊的訪問不一致的話,在軟件開發(fā)期間就會產(chǎn)生潛在的訪問限制錯誤,從而可能需要為每個子系統(tǒng)設計專門的軟件驅動程序。對不同邏輯塊的不一致訪問也會使硬件集成和驗證變得困難重重。
例如設計工程師在調試器上編輯4個十六進制數(shù)字并不能保證處理器會使用一個16位的讀/寫周期,因此,對軟件開發(fā)和硬件集成中使用調試工具設置多種類型的限制訪問也具有一定的困難。這樣看來,評估仿真器處理多個限制性訪問地址空間的能力就非常有用,特別是在用“限制外”訪問方式觸發(fā)總線故障的處理器結構中。
寄存器設計
既然硬件設計工程師的重點已經(jīng)從邏輯門和總線轉移到了系統(tǒng)設計,我們再來審視一下任何處理器系統(tǒng)中最常用到的寄存器設計。寄存器接口允許高速訪問資源,其訪問的效率對系統(tǒng)的性能有很大的影響。
寄存器的結構與訪問
設計工程師應該精心選擇硬件寄存器大小,使處理器能最有效地進行硬件訪問。一般來說,總是采用系統(tǒng)內部整數(shù)訪問方式。寄存器應該被譯碼為連續(xù)的組(沒有地址空檔),這樣可以加速指針或陣列索引對寄存器的訪問。任何可寫的寄存器也應該是以同樣的格式可讀,這樣可以避免使用本地存儲器來緩存這些寄存器值。
控制一個子系統(tǒng)的寄存器應該以相同的結構形式在一起分組,使軟件能使用通用的驅動程序對它們進行訪問。當設計中需要多個同一類型的子系統(tǒng)時這點尤其重要。
為了避免被編碼成獨立進程的軟件任務之間發(fā)生沖突,獨立的子系統(tǒng)不能在系統(tǒng)處理器訪問期間共享可寫寄存器。這些“獨立”的軟件進程在訪問共享寄存器時會產(chǎn)生競爭,除非在系統(tǒng)代碼中使用不可中斷的讀/寫驅動程序。根據(jù)操作系統(tǒng)的不同,多個進程共享寄存器甚至可能會產(chǎn)生功能調用的額外開銷。訪問共享寄存器的同時還有執(zhí)行其它進程的做法是錯誤的,也是軟件設計的通病,會導致間歇性的系統(tǒng)故障,影響集成和測試系統(tǒng)軟件的進度。
系統(tǒng)A違反了很多上文提到的原則,如采用只寫寄存器,共享控制和狀態(tài)寄存器,以及沒有為每個軸提供公共的寄存器映射。系統(tǒng)A必須用專門的驅動程序來緩沖寫輸出數(shù)據(jù),移位并屏蔽軸驅動與位置信息,并防止軸驅動寄存器內容被為每個軸任務編寫的代碼所影響。系統(tǒng)B由于分離并重組了與每個軸有關的寄存器,因此能克服這些問題。
寄存器復位內容
硬件設計工程師應仔細考慮系統(tǒng)的復位狀態(tài)。硬件設計通常采用啟動程序來取得系統(tǒng)啟動后的控制權,并將系統(tǒng)初始化到一個安全的狀態(tài)。系統(tǒng)復位后應將硬件置于一個確定的安全狀態(tài),并且硬件應持續(xù)保持安全狀態(tài)直到系統(tǒng)軟件初始化完成為止。代碼也應在軟件控制下復位硬件以幫助調試、自檢和原始代碼的開發(fā)。
系統(tǒng)A不控制驅動寄存器的復位內容,需要代碼的介入來將所有三個軸的驅動寄存器設置為零。這種結構會產(chǎn)生嚴重的系統(tǒng)設計問題,因為處理器通常是保持在復位狀態(tài),直到FPGA和ASIC加電并得到配置后處理器才正常工作。如果開發(fā)人員使用仿真器,那么在集成過程中系統(tǒng)A還會出現(xiàn)另外的問題:被仿真器控制的處理器在系統(tǒng)加電后可能需要很長的初始化時間才能正常工作。在軟件取得控制權之前系統(tǒng)A和B的軸都處于隨機驅動狀態(tài)。
系統(tǒng)B在加電后會將所有軸驅動寄存器設為零,它對軸驅動設置的控制并不依賴于啟動時間。因為系統(tǒng)B沒有隱藏的狀態(tài)機,因此在本設計中沒有必要考慮增加額外的軟件復位寄存器。
寄存器域設計
大多數(shù)資源接口所包含的數(shù)據(jù)項并不正好適合一個寄存器。這種情況下,硬件設計工程師必須將一個寄存器分成若干域。合理的域結構對系統(tǒng)性能來說非常重要,與寄存器接口設計有相似的影響。有效的域接口設計規(guī)則類似于寄存器設計規(guī)則,但設計工程師還需要特別注意域的順序與放置,還要對寄存器中未用到一些字節(jié)作一定的處理。
1. 寄存器的域
域被定義為寄存器中若干位的子集,主要用于報告或控制資源的一個功能要素。在硬件設計中最常用的域類型有:1. 布爾域:真或假,通常是一位;2. 多位狀態(tài)域和控制域:多位用于報告或控制內部相關功能;3. 列舉狀態(tài)域和控制域:多個位的集合,其中每個位代表了一種不同的硬件狀態(tài);4. 數(shù)字域:多個位組合在一起用來代表一定的數(shù)量值。
從軟件使用者角度看,最有效的域結構是每個寄存器只用一個域。這種理想的軟件結構可能導致硬件實現(xiàn)效率低,因此一個好的系統(tǒng)設計需要在軟硬件設計之間作出折衷,在每個寄存器中應放置多個域。
下文將著重討論一個寄存器中假設存在多個域的情況,不過,當對資源的某個特殊參數(shù)進行的有效訪問將嚴重影響系統(tǒng)軟件性能時,硬件設計工程師仍應該考慮使用單個域的寄存器。
2. 域結構
前文提到的用于寄存器的結構概念同樣也適合于寄存器內部的域。一個寄存器應該只包含屬于設計中同一功能要素的域,并且該寄存器中的所有可寫域都應該是可讀的。
那些包含有屬于多個功能要素的域的寄存器同樣需要特殊驅動程序支持,這樣才能使多個進程安全地訪問每個域。而配置為“只寫”功能的域需要分配影子內存來保存寄存器域中的前一狀態(tài)值。硬件設計工程師原來設想的簡單的“屏蔽/寫”操作現(xiàn)在變成了繁雜的多步功能調用,首先必須禁止中斷和任務切換,然后讀本地存儲器,屏蔽輸入輸出值,再進行硬件寄存器寫,最后開放中斷和多任務切換。如果寄存器中所有域能得到有效安排,通過一個軟件任務就能訪問全部域的話,上述情況就能得到有效避免。
由于系統(tǒng)A將屬于不相關功能的多個域組合放在一個寄存器中,因此它需要使用特殊的驅動程序。而系統(tǒng)B則遵循“單個寄存器內的域按任務進行組織”的原則,將每個域放置在屬于自己的專用寄存器中,因此能高效地訪問資源中的每個軸參數(shù)。
3. 十六進制數(shù)字對齊
硬件設計工程師還應該明白針對處理器和軟件開發(fā)環(huán)境進行對齊約束。如果將域放置在錯誤的地址上而超出字的邊界,將迫使軟件設計工程師只能按塊訪問每個域,進而增加訪問復雜性,降低訪問的速度。在調試過程中,用零值填充域是非常有用的,可以使每個域的最低位對齊十六進制數(shù)字(4位)的邊界:當在邏輯分析儀、調試儀或仿真器上顯示寄存器情況時,十六進制數(shù)字對齊會有助于域值的可視化提取。系統(tǒng)A的寄存器域是沒有對齊的,因此從原始的十六進制數(shù)據(jù)中提取域值很困難。由于控制域沒有對齊,在查錯時屏蔽測試輸入也十分困難。而系統(tǒng)B的所有域都是按十六進制偶數(shù)數(shù)字對齊,因此通過寄存器讀可以很容易地確定每個域的狀態(tài),并且能方便地將某個域設為指定值。
4. 域位置的分配與順序
寄存器內域的設置也會嚴重影響軟件實現(xiàn)的效率。布爾域和多位域通常與位置無關,但當列舉域和數(shù)字域被放置在寄存器的最低位(LSB)時對它們的訪問效率通常是最高的(LSB的實際位數(shù)取決于處理器類型,位0不一定是LSB)。將域配置在寄存器的LSB中可以有效地消除對域內容屏蔽后的移位操作,也使測試設備或進行可視化檢查的調試儀訪問寄存器時能更容易地識別域值。
系統(tǒng)A中用于軸2和軸3的域值在使用前必須要求軟件進行屏蔽和移位。而系統(tǒng)B則將所有數(shù)字域配置在寄存器的LSB中,從而能完成更有效的訪問。系統(tǒng)B的集成性也更好,資源寄存器的十六進制數(shù)據(jù)能真正分離成正確的域值。
5. 未用數(shù)據(jù)位
寄存器中的未用位同樣也會影響軟件實現(xiàn)的效率。所有未用位應回歸為零,并且寫入操作時無需對它們作特殊的處理,這樣可以避免不必要的屏蔽與清除操作。這個規(guī)則的唯一一個例外是包含數(shù)字域為2的補碼的寄存器,并且在寄存器中剩余的最高位(MSB)沒有用的情況。在這種情況下,使硬件實現(xiàn)符號將域的MSB擴展到未用位就非常有用。以這種方式擴展的數(shù)字域能夠被處理器直接訪問,因為帶符號的數(shù)值無需軟件符號的擴展。當對特殊的數(shù)字域變量的訪問速度嚴重影響整體系統(tǒng)性能時,將該類型的域與“單個寄存器單個域”結合起來考慮將非常有用。由于無需屏蔽或符號擴展,這些域能以內部數(shù)據(jù)訪問的方式直接訪問。
當系統(tǒng)A中需要從寄存器提取域值時,要求軟件對每個數(shù)字域值進行符號擴展,而系統(tǒng)B允許通過對寄存器的內部整數(shù)訪問直接訪問域值。
6. 域類型選擇
域類型的正確選擇也能極大地提高軟件實現(xiàn)效率。在打開或關閉獨立資源功能時布爾域是最有效的。要注意的是,只有當寄存器是可讀寫時單位域才容易編碼。如果硬件寄存器對域的訪問有限制,就需要專門的緩沖器(有可能再加上一個專門的驅動程序)來保存當前的內容。限制性訪問同時也會限制一些編程構造的使用,如位域(bit field),從而影響系統(tǒng)代碼的可讀性,且無助于減少編程錯誤。
當表達資源狀態(tài)的數(shù)據(jù)需要占用一定范圍的值時數(shù)字域就很有用。當一個域能保持正值和負值使用時,帶符號的表達式通常需要更多的軟件工作。另外,還要避免在數(shù)字域中對其它數(shù)據(jù)進行編碼(如利用域符號表示一個不相關的資源狀態(tài))。
從硬件實現(xiàn)來看,多位域更有效,但在寫入系統(tǒng)代碼時會增加代碼的復雜度。列舉類型通常能更好地反映資源中相關功能的實際可用性,可以有效防止沖突功能的采用(如將存儲器塊切換到本地總線上)。列舉類型還應提供這樣的可選項:無條件允許切換之間存在“停放帶”,無條件允許系統(tǒng)軟件中存在“先中斷再實現(xiàn)”的代碼切換。
系統(tǒng)A中對軸驅動域的“只寫”訪問使軟件對目標域的訪問效率很低,必須用RAM保存寫過程中不作修改的過去的軸內容。系統(tǒng)B中由于每個寄存器都只有一個域并允許讀寫操作,因此不存在這樣的問題。
實例系統(tǒng)的性能評估
為了評估最終系統(tǒng)軟件的性能,將列表1中的偽隨機碼正確轉換成C代碼并同時用于A、B系統(tǒng)中,然后利用內部存儲器中的結構模擬每個系統(tǒng)的硬件接口。代碼中應避免使用位域,因為標準C實現(xiàn)不能在限制性訪問的地址空間上正確工作。系統(tǒng)代碼模擬運行于PowerPC,編譯工具采用的是Green Hills MultiC,目標操作系統(tǒng)是VxWorks,編譯器設置在中級優(yōu)化度(目的是幫助調試,并允許設計工程師把每條匯編指令與每一行C代碼聯(lián)系起來)。
表1列出了偽隨機碼的每一行,并給出了每個系統(tǒng)實現(xiàn)所用到的匯編指令與功能調用數(shù)量。另外還對兩個實現(xiàn)所用的代碼執(zhí)行速度進行測試。子程序升級系統(tǒng)B軸的速度要比系統(tǒng)A快5.3倍,這主要歸功于任務阻塞與去阻塞功能調用的去除。要注意的是實際系統(tǒng)中的加速效果可能并不明顯,因為實際的硬件訪問時間對總的執(zhí)行時間影響最大。
在實驗中要提升兩個實現(xiàn)所用編譯器的優(yōu)化度,結果發(fā)現(xiàn)優(yōu)化度的提高對系統(tǒng)B無效,對系統(tǒng)A來說只是減少了很少的代碼,并且速度卻稍有降低。這樣的結果表明,系統(tǒng)B的硬件接口在軸域的資源訪問上非常接近內部訪問的效能。
另外,為了對兩種實現(xiàn)所用到的硬件設備進行評估,要用VHDL對硬件接口進行編碼,然后用賽靈思的Webpack軟件進行綜合,并把設計映射到賽靈思的Virtex FPGA中。采用Virtex系列芯片的結果是系統(tǒng)A要消耗56個功能片(slice),系統(tǒng)B要消耗85個功能片。V300E-PQ240器件總共具有3072個片,因此系統(tǒng)A占用可用資源的1.8%,系統(tǒng)B則占2.8%。9500系列器件的內部資源更有限些,比如XC95288XL-PQ208,系統(tǒng)A將占用該器件可用資源的18%,系統(tǒng)B則占30%。
仔細考察這兩個設計發(fā)現(xiàn),系統(tǒng)B所用的額外資源中最主要的驅動源是組合型軸尋址方案。為了驗證這一結果,重新組織寄存器映射,以便將每個軸作為一個獨立資源使用,單個軸映射按地址位邊界對齊。這一變通的實現(xiàn)方式保留了系統(tǒng)B的所有軟件接口優(yōu)點,同時減少了整體硬件器件的使用,Virtex系列器件的片利用率能降低2.3%,9500系列的利用率能降低22%。
硬件設計會極大地影響系統(tǒng)軟件實現(xiàn)的復雜性和質量。一個好的硬件設計要求設計人員能根據(jù)硬件實現(xiàn)與最終軟件設計環(huán)境的復雜性做出決定,正確理解硬件接口設計對軟件開發(fā)流程的影響能極大地改進系統(tǒng)質量、性能和可靠性,同時減少系統(tǒng)開發(fā)的周期與成本。
作者: Christopher Leddy
高級系統(tǒng)工程師
Raytheon公司
Email:caleddy@west.raytheon.com
本站內容除特別聲明的原創(chuàng)文章之外,轉載內容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點。轉載的所有的文章、圖片、音/視頻文件等資料的版權歸版權所有權人所有。本站采用的非本站原創(chuàng)文章及圖片等內容無法一一聯(lián)系確認版權者。如涉及作品內容、版權和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當措施,避免給雙方造成不必要的經(jīng)濟損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。