產品的日新月異及不斷增長的需求使嵌入式設計者需縮短設計週期以符合市場需求。然而在嵌入式設計中,能夠降低設計風險、節省時間和減少精力的編譯器通用編碼(compiler independence)卻往往最易被忽略。對於任何項目來說,微控制器中的編譯器通用編碼功能可大幅提昇其靈活性。
工欲善其事,必先利其器
通用編碼功能使設計者能夠根據他們的項目需求選擇合適的編譯器。比較不同的編譯器,可以清楚地看出在相同條件下不同編譯環境的性能差異。每個編譯器都具不同的特性,有的編譯器可優化彙編功能,使生成的代碼非常小;有的專注於執行速度;也有的根本不進行任何優化。在微控制器選擇過程中,如果應用程式碼的大小是最終的決定因素,那麼編碼大小的優化程度將是一個重要的參考。如果不考慮代碼大小,那麼授權費用或許是一個問題。如今,8051編譯器的授權費價格範圍可高達數千美元或甚至不需任何費用。設計人員透過通用編碼來開發專案將可獲得更大的靈活性,並可將專案輕鬆的轉移到不同的編譯環境。
對於過度依賴特定編譯環境的設計人員來說,如果選擇的特定編譯器突然無法使用時,那將會變成一個負擔。例如,如果設計人員僅使用特定編譯器來開發一個專案,一旦不能使用該編譯環境將對專案非常不利。在相同的例子中,如果設計人員以通用編碼的方式進行,若需切換到一個新的編譯環境時,僅需要於標頭檔進行少量修改即可。該編碼只需要做一些小幅度的修改即可避免編譯器的錯誤或警告,但整體來說,轉換編譯器所耗費的精力幾乎是微乎其微的。
實現編譯器通用編碼
執行編譯器通用編碼非常簡單 - 設計者只需於標頭檔添加一個與編譯器相關的典型C語言進行巨集函數即可完成編譯器的通用編碼。
設計人員只需在標頭檔中說明編譯器相關語法的不同之處,不需針對特定編譯器編寫整個項目。因此,若需要使用另一個編譯環境或使用中的編譯器無法使用時,設計人員的融通性會更強,這種編程方法所帶來的好處和便利可讓微控制器編碼的開發過程更具效率及靈活性。
通用編碼最大的好處是源代碼可讀性高,除錯時間短。採用這種編碼方式後,定義的中斷、指標和變數能夠在同一個位置修改,並傳送到整個項目。此外,包含在標頭檔中的特定結構體和總體變數有助於編譯器對多位元組資料儲存的處理。如果編碼時沒有考慮到儲存模式的差異,可能會導致錯誤發生,而且這種錯誤很難被檢查出來,這應予以重視。
重覆使用代碼
除了在編譯器之間可靈活切換及易於使用外,編譯器通用代碼比編譯器特定代碼更具有可讀性。這種可讀性可以縮短除錯時間,進而降低整體成本。在一個應用中,不同設計人員會使用相同的源代碼於專案中,而這些源代碼需能適用於多種編譯環境。這種情況下,開發人員應詳細說明專案中測試通過的工具及如何將不同編譯環境整合到最終專案中。這種靈活性提高了設計人員間代碼的重覆使用率。
如何做到?
在源代碼中使用巨集函數而非編譯器特定的語法是實現編譯器通用編碼的基礎。為了支援不同的編譯環境,專案中僅需包含巨集函數標頭檔的額外檔。此檔包含一系列“if”條件句,“if”語句中的參數是編譯器名稱。編譯器名稱一旦被選用,整個項目將使用該編譯器的特定巨集函數。因此,若要修改源代碼中的多行代碼,僅需修改巨集函數檔中的一行代碼。
試圖將一個新的編譯環境整合到一個專案時,巨集函數非常有用。例如,如果在巨集函數檔中編寫了不正確的中斷定義,開發人員僅需更改一個特定的巨集函數,而無需更改源代碼中的每一個中斷服務程式定義。為了把新的編譯器整合到專案中,開發人員需要在巨集函數檔中添加一個新段落,該段中需含“if”語句及巨集函數列表。同時,開發人員可以使用編譯器特定的語法編寫每個巨集函數,該語法可以在編譯器特定文檔中找到。經過對巨集函數檔的微幅修改,新的編譯環境將可以與之相容。
使用巨集函數標頭檔與使用微處理器相關的標頭檔的目的是相同的,都是為特殊功能寄存器、位址和位元定義而服務的。巨集函數的標頭檔最大的目的是使編碼開發過程更加容易。每個編譯器有自己特定的語法用於下列專案:
- 中斷
- 中斷標準
- 寄存器區
- 儲存段定義
- 儲存段中的定位變數
- 指向儲存段的指標
- 空操作(NOPs)
- 特殊功能寄存器聲明
- 特殊功能寄存器位元聲明
如果上述任何一項使用了編譯器特定語法,都將使專案不具有編譯器通用性。當轉換編譯環境時,其他潛在的問題包括:多位元組儲存模式差異、通用指標、定址和變數的預設值。在Big Endian中,編譯器保存多位元組資料中的最高位元組值到最低儲存位址;在Little Endian中,編譯器保存多位元組資料中的最低位元組值到最低儲存位址。其關鍵的區別特別注意源代碼中是否有對多位元組數的任何操作。
Memory Location | Contents |
---|---|
X | 01 |
X+1 | 02 |
X+2 | 03 |
X+3 | 04 |
Memory Location | Contents |
---|---|
X | 04 |
X+1 | 03 |
X+2 | 02 |
X+3 | 01 |
通用指針格式也可能有所不同。在三位元組指標中,某些編譯器可能使用最低位元組保存儲存目標的段位址,其餘兩個位元組保存段內位址。而另一些編譯器可能使用最高位元組儲存目標的段位址,其餘兩個位元組用來保存段內位址。初始化一個位於特定儲存區的變數,也可能導致潛在的問題,因為並非所有的編譯器皆允許變數在初始化定義。
可通用於編譯器內的巨集函數的標頭檔例子和微控制器範例代碼可從Silicon Labs網站下載:https://www.silabs.com/products/mcu/Pages/SoftwareDownloads.aspx
代碼範例和可通用於編譯器的巨集函數標頭檔都可以在Silicon Labs的整合開發環境(IDE)中打開。Compiler_defs.h包含8051編譯環境巨集函數、SDCC、Raisonance、Keil、Tasking和IAR。儲存段、中斷、中斷標準、寄存器區、定位變數和儲存相關指標的巨集函數都包含在此檔中。此標頭檔可用於任何Silicon Labs微控制器,也可用於包含特殊功能寄存器(SFR, special function register)、中斷向量和可位定址特殊功能寄存器的設備相關的標頭檔中。當編譯環境整合於項目時,Compiler_defs.h中的巨集函數可以作為一個起點。
總結
微控制器採用通用編碼於所有編譯器可帶來許多好處與便利,任何開發人員都應考慮這個問題。通用編碼可帶給開發人員顯著的靈活彈性、降低了與編譯器相依賴的風險,同時也可對編譯器的性能進行測試和對比。它只需調整標頭檔中的一行代碼,即可應用到整個專案,除了節省了除錯時間,同時也提昇了效率。
Evan Schulz,Silicon Labs應用工程師 本文曾刊載於新電子雜誌
更多Silicon Labs MCU系列產品資訊,請聯繫sales@edom.com.tw
益登電子報 2010/11/19
沒有留言:
張貼留言