0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C語(yǔ)言中section關(guān)鍵字的作用?其在SDK實(shí)現(xiàn)開(kāi)機(jī)自啟動(dòng)的應(yīng)用?

Dp1040 ? 來(lái)源:嵌入式系統(tǒng) ? 2023-10-08 16:01 ? 次閱讀

1、section的作用

section主要作用是將函數(shù)或者變量放在指定段中,這樣就可在指定的位置取出。

//section demo with gcc
#include"stdio.h"

int__attribute__((section("my_fun")))test1(inta,intb)
{
return(a+b);
}

inttest(intb)
{
return2*b;
}

int__attribute__((section("my_fun")))test0(inta,intb)
{
return(a*b);
}

int__attribute__((section("my_val")))chengi;
int__attribute__((section("my_val")))chengj;

intmain(void)
{
intsum,c,j;
chengi=1,chengj=2;

sum=test1(chengi,chengj);
c=test(100);
j=test0(chengi,chengj);

printf("sum=%d,c=%d,j=%d
",sum,c,j);

return0;
}

編譯生成map文件:

gcc-o main.exe main.c-Wl,-Map,my_test.map

my_test.map 文件片段如下:

.text0x004014600xa0C:\Users\think\ccmGLaeH.o
0x00401460test
0x0040146amain

.text0x004015000x0c:/mingw/bin/../libmingw32.a(CRTglob.o)

......
my_fun0x004040000x200
[!provide]PROVIDE(___start_my_fun,.)

my_fun0x004040000x1cC:\Users\think\ccmGLaeH.o

0x00404000test1
0x0040400dtest0

[!provide]PROVIDE(___stop_my_fun,.)

.data0x004050000x200

0x00405000\__data_start_\_=.
......
*(.data_cygwin_nocopy)
my_val0x004060000x200

[!provide]PROVIDE(___start_my_val,.)

my_val0x004060000x8C:\Users\think\ccdMcTrl.o
0x00406000chengi
0x00406004chengj

[!provide]PROVIDE(___stop_my_val,.)

.rdata0x004070000x400

分析可見(jiàn),使用section修飾的函數(shù)和變量在自定義的片段,而且是連續(xù)存放在___start_xx到___stop_xx之間,這樣可根據(jù)變量的地址得出與其同段變量的地址,為后續(xù)自動(dòng)初始化等功能提供了基礎(chǔ)。

2、 自動(dòng)初始化

基于前面section的作用,可以將同類(lèi)函數(shù)指針全部使用同一個(gè)段名修飾,然后開(kāi)機(jī)后系統(tǒng)自動(dòng)檢索段內(nèi)函數(shù)指針,逐個(gè)執(zhí)行,對(duì)上層應(yīng)用就是無(wú)需主動(dòng)調(diào)用,系統(tǒng)自動(dòng)初始化。

考慮到硬件初始化與應(yīng)用功能初始化的先后順序,可以對(duì)段名進(jìn)行分配,map文件按段名排序。自動(dòng)初始化主體是OS_INIT_EXPORT宏。

范例代碼出自中國(guó)移動(dòng)的oneos開(kāi)源版本,使用gcc,方案和國(guó)產(chǎn)RT-Thread類(lèi)似。

typedefos_err_t(*os_init_fn_t)(void);

#defineOS_INIT_EXPORT(fn,level)
const os_init_fn_t __os_call_##fn OS_SECTION(".init_call."level)=fn

#defineOS_BOARD_INIT(fn)OS_INIT_EXPORT(fn,"1")

#defineOS_PREV_INIT(fn)OS_INIT_EXPORT(fn,"2")

#defineOS_DEVICE_INIT(fn)OS_INIT_EXPORT(fn,"3")

#defineOS_CMPOENT_INIT(fn)OS_INIT_EXPORT(fn,"4")

#defineOS_ENV_INIT(fn)OS_INIT_EXPORT(fn,"5")

#defineOS_APP_INIT(fn)OS_INIT_EXPORT(fn,"6")

例如shell初始化函數(shù),定義如下:

OS_APP_INIT(sh_system_init);

將宏定義展開(kāi):

/*含義是函數(shù)指針__os_call_sh_system_init
*其指向sh_system_init函數(shù),且該指針編譯后放在".init_call.6"段
*/
constos_init_fn_t__os_call_sh_system_init
__attribute__((section((".init_call.6"))))=sh_system_init

系統(tǒng)自身也有自定義函數(shù),用來(lái)標(biāo)記起止點(diǎn)函數(shù)。

OS_INIT_EXPORT(os_init_start,"0");//段起點(diǎn)__start
OS_INIT_EXPORT(os_board_init_start,"0.end");
OS_INIT_EXPORT(os_board_init_end,"1.end");
OS_INIT_EXPORT(os_init_end,"6.end");//段終點(diǎn)__stop

最終生成的map文件,如下圖所示:

//系統(tǒng)底層在合適的時(shí)機(jī)調(diào)用如下兩函數(shù),將指定段區(qū)間內(nèi)的所有函數(shù)自動(dòng)執(zhí)行

voidos_board_auto_init(void)
{
constos_init_fn_t*fn_ptr_board_init_start;
constos_init_fn_t*fn_ptr_board_init_end;
constos_init_fn_t*fn_ptr;

fn_ptr_board_init_start=&__os_call_os_board_init_start+1;
fn_ptr_board_init_end=&__os_call_os_board_init_end-1;

//將段首尾區(qū)間內(nèi)的函數(shù)全部遍歷執(zhí)行
for(fn_ptr=fn_ptr_board_init_start;fn_ptr<=?fn_ptr_board_init_end;?fn_ptr++)
????{
????????(void)(*fn_ptr)();
????}
????return;
}

static?void?os_other_auto_init(void)
{
????const?os_init_fn_t?*fn_ptr_other_init_start;
????const?os_init_fn_t?*fn_ptr_other_init_end;
????const?os_init_fn_t?*fn_ptr;

????fn_ptr_other_init_start?=?&__os_call_os_board_init_end?+?1;
????fn_ptr_other_init_end???=?&__os_call_os_init_end?-?1;

????for?(fn_ptr?=?fn_ptr_other_init_start;?fn_ptr?<=?fn_ptr_other_init_end;?fn_ptr++)
????{
????????(void)(*fn_ptr)();
????}
????return;
}

系統(tǒng)執(zhí)行os_other_auto_init時(shí)實(shí)現(xiàn)了sh_system_init的自動(dòng)執(zhí)行,即使應(yīng)用層沒(méi)有顯示的去調(diào)用它。使用符號(hào)段的方式實(shí)現(xiàn)初始化函數(shù)自動(dòng)執(zhí)行,應(yīng)用層修改軟件,增加功能啟動(dòng)或者裁剪,對(duì)底層代碼無(wú)需任何改動(dòng)。

注意:段中函數(shù)類(lèi)型都是一樣的,范例是同一類(lèi)函數(shù)指針,也可以是結(jié)構(gòu)體,需要確保每個(gè)成員占用空間大小相同,這樣才能逐個(gè)遍歷。

3、總結(jié)

不同編譯器對(duì)section屬性的定義略有差異,但效果相同。

/*Compiler Related Definitions*/
#ifdefined(__CC_ARM)||defined(__CLANG_ARM)  /*ARM Compiler*/
#defineSECTION(x)__attribute__((section(x)))
#elifdefined(__IAR_SYSTEMS_ICC__)/*for IAR Compiler*/
#defineSECTION(x)@x
#elifdefined(__GNUC__)/*GNU GCC Compiler*/
#defineSECTION(x)__attribute__((section(x)))
#elifdefined(__ADSPBLACKFIN__)/*for VisualDSP++Compiler*/
#defineSECTION(x)__attribute__((section(x)))
#elifdefined(_MSC_VER)
#defineSECTION(x)
#elifdefined(__TI_COMPILER_VERSION__)
/*
*The way that TI compiler set section is different from other(at least
*GCC and MDK)compilers.See ARM Optimizing C/C++Compiler 5.9.3 for more
*details.
*/
#defineSECTION(x)
#else
#errornot supported tool chain
#endif

上面的#error也是個(gè)應(yīng)用技巧,配搭#if / #else / #endif在編譯階段即可發(fā)現(xiàn)代碼問(wèn)題,一般用于判斷宏定義的配置是否在預(yù)期之外,編譯報(bào)錯(cuò)必須修改。

配合C關(guān)鍵字,對(duì)代碼的安全校驗(yàn)、擴(kuò)展移植都會(huì)有很好的效果。對(duì)小型項(xiàng)目、個(gè)人獨(dú)立開(kāi)發(fā)看不出效果,但對(duì)復(fù)雜的多人合作的項(xiàng)目,合適的關(guān)鍵字對(duì)代碼的穩(wěn)定性和架構(gòu)是錦上添花。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    180

    文章

    7595

    瀏覽量

    135872
  • RT-Thread
    +關(guān)注

    關(guān)注

    31

    文章

    1261

    瀏覽量

    39840
  • gcc編譯器
    +關(guān)注

    關(guān)注

    0

    文章

    78

    瀏覽量

    3346

原文標(biāo)題:C語(yǔ)言中section關(guān)鍵字的實(shí)際作用

文章出處:【微信號(hào):玩點(diǎn)嵌入式,微信公眾號(hào):玩點(diǎn)嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    C語(yǔ)言關(guān)鍵字const的幾種用法

    本期來(lái)講解一個(gè)C語(yǔ)言關(guān)鍵字——const。
    發(fā)表于 06-21 11:05 ?1540次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語(yǔ)言</b><b class='flag-5'>關(guān)鍵字</b>const的幾種用法

    C語(yǔ)言中關(guān)鍵字static的作用是什么

    C語(yǔ)言中關(guān)鍵字static的作用是什么?用預(yù)處理指令#define 聲明一個(gè)函數(shù),輸入天數(shù)得到有多少秒?
    發(fā)表于 12-24 06:53

    C語(yǔ)言中的volatile關(guān)鍵字

    volatile關(guān)鍵字是一種類(lèi)型修飾符,用它聲明的類(lèi)型變量表示可以被某些編譯器未知的因素更改。
    發(fā)表于 05-27 09:32 ?3264次閱讀

    單片機(jī)C語(yǔ)言中常用到的關(guān)鍵字及數(shù)據(jù)類(lèi)型

    單片機(jī)C語(yǔ)言中常用到的關(guān)鍵字及數(shù)據(jù)類(lèi)型。
    發(fā)表于 11-03 10:57 ?13次下載

    標(biāo)準(zhǔn)C語(yǔ)言總共有32個(gè)關(guān)鍵字

    標(biāo)準(zhǔn)C語(yǔ)言總共有32個(gè)關(guān)鍵字
    發(fā)表于 01-12 15:59 ?0次下載

    C語(yǔ)言32個(gè)關(guān)鍵字

    C語(yǔ)言32個(gè)關(guān)鍵字,感興趣的小伙伴們可以看看。
    發(fā)表于 07-26 16:29 ?66次下載

    C語(yǔ)言中關(guān)鍵字

    C語(yǔ)言中的入門(mén)教程
    發(fā)表于 10-14 16:24 ?3次下載

    淺析C語(yǔ)言中typedef關(guān)鍵字作用

    C 語(yǔ)言提供了 typedef 關(guān)鍵字,您可以使用它來(lái)為類(lèi)型取一個(gè)新的名字。
    的頭像 發(fā)表于 11-08 08:42 ?5955次閱讀

    【嵌入式】C語(yǔ)言中volatile關(guān)鍵字

    volatile06. 附錄01. volatile概述volatile是C語(yǔ)言中的一個(gè)關(guān)鍵字。將變量定義為volatile就表示告訴編譯器這個(gè)變量可能會(huì)被竟想不到地改變,在這種情況下,編譯器就不會(huì)去假設(shè)這個(gè)變量的值了,及優(yōu)化器
    發(fā)表于 10-21 10:21 ?6次下載
    【嵌入式】<b class='flag-5'>C</b><b class='flag-5'>語(yǔ)言中</b>volatile<b class='flag-5'>關(guān)鍵字</b>

    C語(yǔ)言中__attribute__ 關(guān)鍵字的用法

    嵌入式開(kāi)發(fā),離不開(kāi) C 語(yǔ)言,C語(yǔ)言中有很多語(yǔ)法會(huì)直接或間接影響你代碼的質(zhì)量,下面就來(lái)講講__attribute__ 關(guān)鍵字的用法。 1.
    發(fā)表于 10-19 09:06 ?1.2w次閱讀

    C語(yǔ)言32個(gè)關(guān)鍵字可以分為這幾類(lèi)

    C語(yǔ)言是一種面向過(guò)程、抽象化的通用程序設(shè)計(jì)語(yǔ)言,廣泛應(yīng)用于嵌入式底層和系統(tǒng)開(kāi)發(fā)。C語(yǔ)言關(guān)鍵字共有
    的頭像 發(fā)表于 12-31 15:28 ?4920次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語(yǔ)言</b>32個(gè)<b class='flag-5'>關(guān)鍵字</b>可以分為這幾類(lèi)

    淺析C語(yǔ)言中的regiseter關(guān)鍵字

    C語(yǔ)言中重要的關(guān)鍵字有很多,static const extern我們之前都講過(guò),還有一個(gè)面試中出現(xiàn)的頻率也比較高:register。
    的頭像 發(fā)表于 08-25 17:10 ?1072次閱讀
    淺析<b class='flag-5'>C</b><b class='flag-5'>語(yǔ)言中</b>的regiseter<b class='flag-5'>關(guān)鍵字</b>

    static關(guān)鍵字的三種用法

    C語(yǔ)言中關(guān)鍵字"static"可以用于不同的上下文,具有不同的作用。以下是"static"
    的頭像 發(fā)表于 11-10 08:00 ?485次閱讀
    static<b class='flag-5'>關(guān)鍵字</b>的三種用法

    快速掌握C語(yǔ)言關(guān)鍵字

    C語(yǔ)言中的32個(gè)關(guān)鍵字你知道多少個(gè)呢?根據(jù)關(guān)鍵字作用分為四類(lèi):數(shù)據(jù)類(lèi)型關(guān)鍵字、控制語(yǔ)句
    的頭像 發(fā)表于 07-06 08:04 ?284次閱讀
    快速掌握<b class='flag-5'>C</b><b class='flag-5'>語(yǔ)言</b><b class='flag-5'>關(guān)鍵字</b>

    C語(yǔ)言關(guān)鍵字--typedef

    C語(yǔ)言關(guān)鍵字使用方法學(xué)習(xí)指南!
    的頭像 發(fā)表于 10-07 12:44 ?153次閱讀