IAR中常用的 #pragma 命令和擴充套件關鍵字
pragma 命令
1、#pragma message(“ ”) 編譯器編譯到此處,在Build視窗中列印相應文字資訊。
2、#pragma error “” 編譯器編譯到此處,在Build視窗中產生錯誤並列印其文字資訊。
3、#pragma inline [=forced | never] 用這個指令是建議編譯將這條指令後面的函式內聯到呼叫它的函式的函式體中去。 當#pragma inline = forced,則強制讓編譯器對函式內聯,如果內聯不成功,會發出警告訊息。
4、#pragma location = {address | register | NAME} 該指令用處
-
定位該指令之後的全域性或靜態變數到指定的absolute address上。其中變數必須定義為__no_init。 pragma location = address 等價於 @ address,其中變數也必須定義為__no_init 。 示例: __no_init volatile char alpha @ 0xFF2000 運用絕對地址定位,還需注意地址的對齊問題。
-
定位該指令之後的變數到指定暫存器中,其中該變數必須宣告為__no_init,同時該變數的作用域為整個檔案。 ===========register(暫存器R4-R11) pragma location = register 等價於 @ register,其中變數也必須定義為__no_init
-
將該指令之後的函式或變數放置到一個指定的section中。其中,不要試圖將那些通常放在不同section的變數放置在同一section中。 =============NAME(A user-defined section name; cannot be a section name predefined for use by the compiler and linker. pragma location = section 等價於 @ section
示例 變數放置在自定義的section中。 __no_init int alpha @ “MY_NOINIT”; /* OK */ #pragma location=”MY_CONSTANTS” const int beta; /* OK */
函式放置在自定義section中。 void f(void) @ “MY_FUNCTIONS”; void g(void) @ “MY_FUNCTIONS” { } #pragma location=”MY_FUNCTIONS” void h(void);
- #pragma required = symbol #pragma required確保連結輸出中包括某個符號所需的另一個符號。該指令必須放在緊鄰第二個符號的前邊。如果符號在應用中不可見,使用該指令。例如,如果僅通過某個變數所在的段對其進行間接引用,必須使用#pragma required。 eg: const char copyright[] = “Copyright by me”; #pragma required=copyright int main() { /* Do something here. */ } Even if the copyright string is not used by the application, it will still be included by the linker and available in the output.
5、擴充套件關鍵字
__no_init 正常情況下,應用程式啟動時,IAR執行時環境將全部全域性和靜態變數初始化為0。IAR C編譯器支援宣告不初始化的變數,使用__no_init型別限定符。宣告__no_init的變數不需初始化。一些關鍵資料在系統復位(如看門狗復位或其他原因造成的復位)時的數值是不能改變的!在這種情況下可用__no_init限定。
__root __root限定的函式和變數在即是沒有被任何函式引用的情況下,它依然存在於目的碼中而不會被優化掉。
__task 被該關鍵字限定的函式在被呼叫時不會做暫存器保護,即沒有暫存器入棧出棧操作。通常用在RTOS的啟動函式中。 By default, functions save the contents of used preserved registers on the stack upon entry, and restore them at exit. Functions that are declared __taskdo not save all registers, and therefore require less stack space. Because a function declared __taskcan corrupt registers that are needed by the calling function, you should only use __taskon functions that do not return or call such a function from assembler code. The function maincan be declared __task, unless it is explicitly called from the application. In real-time applications with more than one task, the root function of each task can be declared __task. 在IAR中實驗了一下,發現編譯器還是將暫存器進行了壓棧操作,不知為何?
__weak
在連結階段,一個symbol可以有多個weak定義和最多一個non-weak定義。如果symbol需要被程式引用,存在non-weak,則non-weak被引用。如果不在在non-weak,則weak中的一個會被應用。
--------------------- 本文來自 sunheshan 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/sunheshan/article/details/45531953?utm_source=copy