文章分享

當(dāng)前位置:首頁>文章分享

GCC設(shè)置部分代碼的編譯選項

摘錄:HCTech 無錫和控電子   時間:2025-02-21   訪問量:1379

前言:本文測試編譯器為arm-none-eabi-gcc 2018-q4-major [gcc-8-branch revision 267074]

==================================================================

GCC可以對部分代碼設(shè)置不同的編譯選項,在編譯時使用其指明的選項,而不用編譯命令里指定的參數(shù)。

有幾種方法可以實現(xiàn)該功能。

 

1. 使用#pragma指令

參數(shù)值可以是數(shù)字,也可以是字符串。數(shù)字就是優(yōu)化級別,以O(shè)開頭的字符串也被認為是一個優(yōu)化級別(例如(“O1”)(“-O1”)和(“1”)是相同的作用),其他的字符串選項如果沒有-前綴,編譯器自動添加-f,例如("unroll-loops")代表-funroll-loops。

該指令最小的作用域為函數(shù),也就是說無法在函數(shù)內(nèi)部使用,但可以作用于多個函數(shù)。

具體實現(xiàn):

Function Specific Option Pragmas,在特定代碼前保存當(dāng)前的編譯選項,然后對特定的代碼使用指定編譯選項,最后再恢復(fù)之前保存的編譯選項。

1 #pragma GCC push_options2 #pragma GCC optimize ("O0")3 ...your code...4 #pragma GCC pop_options

 

1 #pragma GCC push_options2 #pragma GCC optimize ("unroll-loops")3 ...your code...4 #pragma GCC pop_options

 

1 #pragma GCC push_options2 #pragma GCC optimize ("-funroll-loops")3 ...your code...4 #pragma GCC pop_options

 


1 ......2 #pragma GCC unroll 23     for(i=0;i<N;i++)4     {5         ......6     }7 ......


 

注:#pragma GCC unroll n

You can use this pragma to control how many times a loop should be unrolled.
It must be placed immediately before a for, while or do loop or a #pragma
GCC ivdep, and applies only to the loop that follows. n is an integer constant
expression specifying the unrolling factor. The values of 0 and 1 block any
unrolling of the loop.

 

2. 使用__attibute__屬性

參數(shù)值可以是數(shù)字,也可以是-開頭的字符串。數(shù)字就是優(yōu)化級別。以-O開頭的字符串也被認為是一個優(yōu)化選項(例如(“O1”)(“-O1”)和(“1”)是相同的作用),其他的字符串選項如果沒有-前綴,編譯器自動添加-f,例如("unroll-loops")代表-funroll-loops。

該選項作用于單個函數(shù),需要在函數(shù)開頭添加選項屬性。

 


#define OPTIMIZE_ZERO     __attribute__ ((__optimize__ ("-O0")))#define OPTIMIZE_UNROLL   __attribute__ ((__optimize__ ("-funroll-loops")))#define OPTIMIZE_UNROLL_ZERO   __attribute__ ((__optimize__ ("unroll-loops","O0")))#define SECTION_ITCM      __attribute__ ((section (".itcm")))#define SECTION_DTCM      __attribute__ ((section (".dtcm")))int test_int[4] SECTION_DTCM;

OPTIMIZE_ZERO  int main(void)
{
    ......
 }
 
OPTIMIZE_UNROLL_ZERO  int test(void)
{
    ......
}

SECTION_ITCM int sec_tcm(void)
{
    ......
}


 

注:-funroll-loops選項用于循環(huán)展開。

 

3. 修改Linker腳本

對于指定目標文件,如果我們想讓該文件中所有的text/data/bss等段內(nèi)容放置在指定地址,應(yīng)該怎么實現(xiàn)?

第一種方法,可以用本文第二段中的__attribute__屬性,對文件中的每個函數(shù)或者變量加上指定前綴,然后在Linker腳本安排好對應(yīng)的Section即可,這樣雖然可以滿足需求但是稍顯繁瑣。

查閱GCC的文檔,沒有找到使用#pragma指令對多個函數(shù)或者變量設(shè)置Section屬性的辦法,因此第二種辦法需要從Linker文件下手。

GCC使用的Linker腳本為LD文件,從文件中摘出.text段分配關(guān)系為例:


  .text :
  {
    . = ALIGN(4);    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH


 上述的LD文件內(nèi)容指定了所有文件的.text.text*段放置在FLASH所在基地址。

其中*符號為多字符通配符,加入.text*是因為如果編譯器開啟-ffunction-sections選項,會給所有的函數(shù)生成單獨的text段,例如main函數(shù)會生成.text.main段,加入.text*就可以覆蓋這些text段。

假如我們想把目標文件中test.o這個文件從中取出來放在另外的FLASH2地址,可以這么實現(xiàn):

(1)在FLASH段的描述中使用EXCLUDE_FILE把該文件排除:


  .text :
  {
    . = ALIGN(4);    *(EXCLUDE_FILE(*test.o) .text)    /* .text sections (code) */
    *(EXCLUDE_FILE(*test.o) .text*)    /* .text* sections (code) */
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH


(2)在FLASH2段的描述中填入該文件text段:


  .text_back :
  {
    . = ALIGN(4);    *test.o(.text)    /* .text sections (code) */
    *test.o(.text*)    /* .text* sections (code) */
    . = ALIGN(4);
  } >FLASH2


 


上一篇:使用 openssl 生成證書(含openssl詳解)

下一篇:沒有了!

在線咨詢

點擊這里給我發(fā)消息 售前咨詢專員

點擊這里給我發(fā)消息 售后服務(wù)專員

在線咨詢

免費通話

24小時免費咨詢

請輸入您的聯(lián)系電話,座機請加區(qū)號

免費通話

微信掃一掃

微信聯(lián)系
返回頂部