最近需要在 ARM Cortex M3 上開發一個安全監控系統,茲將程式寫作時需要注意的事項整理如下:
l 區域變數(Local
Variable)
Ø 若使用較大的變數定義(long),會使用運算較慢的指令集,造成整體效能較慢,但不會增加çode size。
Ø 但使用較小的變數定義(),則需要多餘的指令作變數轉換,會增加code size。
Ø 編譯器有個最佳化選項 ”all-in-register locals”,會將local變數放在register上(Cortex
M3共有13個 32-bit general-purpose registers),當暫存器用完的時候,local變數才會放入到stack中。如此可以加速存取local
變數的時間。
建議:使用 int, unsigned int, 和 long,而不要使用
short。
l 全域變數(Global
Variable)
編譯器假設每次函數切換時,全域變數都可能會被更改,需要重新載入。
建議:盡可能使用
local variable或使用 static variable (less reloading)取代。
若需要全域變數,則可以在函數一開始,宣告一個local variable,將全域變數的值代入,以加速運行速度。
作法舉例如下:
Int x=1;
Func()
{
Int lx=x;
x=x+1;
x=lx;
}
l 全域常數(Global
Constant)
針對不同的編譯器,對於全域常數的處理方式各不相同。例如:在SRAM配置全域常數空間,但是將初始值留在Flash中,如此則會佔據兩倍空間。並且當系統要存取此值時,需要載入記憶體,而不是簡單的執行 move 指令。
建議:使用 local constant或是enum來定義常數。
l 浮點數
因為Cortex-M3並沒有支援硬體的浮點運算器,所以盡量不要使用浮點數。若要使用,則需要使用軟體的浮點運算,根據所使用的演算法不同,效能可以差異十倍以上。最好是確認有哪些最佳化的演算法可用。
l 函數
Ø 函數所帶的參數個數
最多只用四個參數,否則會造成效能降低。Because the first four arguments are passed in registers, and the
remaining arguments are passed on the stack.
Ø 遞迴
recursion
若要使用遞迴,則將遞迴函數宣告為static。
l 針對周邊裝置處理,需要特別注意
Ø 變數宣告可能要使用
volatile
Ø Back-to-back stores
Ø 與周邊裝置溝通存取變數時,最好將需要存取變數的動作分開作,以STR指令為例。
Ø 較慢的方法
MyPeriph_reg0 = x;
MyPeriph_reg1 = y;
MyPeriph_reg2 = z;
Ø 較快的方法(因為STR可以在background完成)
MyPeriph_reg0 = x;
y = some computation
MyPeriph_reg1 = y;
z = some computation
MyPeriph_reg2 = z;
l Volatile的用法說明
由於編譯器優化的關係,若某個變數i存在於暫存器中, 存取時,CPU便可能會直接從暫存器中取值,而不會去找尋記憶體中對應的值 (因為訪問register比訪問ram快)。
若應用程式所定義的變數,會被編譯器未知的因素更改(例如存取周邊裝置的值),那麼就需要CPU每次都到記憶體中取值,以避免取出的值不正確,如此則需要在變數宣告之前加上volatile,避免編譯器針對此變數優化。
宣告範例:
volatile int x; // x is in
volatile memory
volatile int *p; // p points to volatile
memory
int *
volatile vp; // vp is a volatile pointer to non-volatile memory
volatile
int* const cpv = &mem; // cpv is a const pointer to volatile memory
l 最佳化 (-O0, -O1, -O2, -O3)
當程式運行無誤之後,可以在編譯時加上最佳化選項使得執行速度較快,程式碼較小。但若仍然在除錯階段,則要小心使用最佳化選項。此選項會使的程式碼執行步驟與程式設計師所預想的稍有不同。
l 開發ARM時可以選用各種編譯器,官方網站上建議有三種工具
當程式運行無誤之後,可以在編譯時加上最佳化選項使得執行速度較快,程式碼較小。但若仍然在除錯階段,則要小心使用最佳化選項。此選項會使的程式碼執行步驟與程式設計師所預想的稍有不同。
l 開發ARM時可以選用各種編譯器,官方網站上建議有三種工具
Ø ARM® RVDS™ (ARM Workbench)
Ø ARM/Keil
RealView MDK tools (μVision IDE)
Ø DS-5 (Eclipse IDE)
我現在拿到的產品附的工具是Keil,後續開發時遇到的問題,會陸續整理在此部落格中。