C語言定義數(shù)組起始地址對齊方式(IAR C99 Kinetis K66)


前言##

前幾天,主管找我問關(guān)于定義變量起始地址對齊方式的問題鸵隧。下面介紹一下問題:上位機(jī)生成了一個(gè)參數(shù)數(shù)組 char para[36541] = {...} ;數(shù)組比較大绸罗,已經(jīng)內(nèi)建好了結(jié)構(gòu)體,只要按照指針指到頭部地址即可正常讀取出來豆瘫,但是由于處理器讀取int 或者 float 數(shù)據(jù)類型比較要求數(shù)據(jù)地址是四字節(jié)對齊的珊蟀,而我們這個(gè)數(shù)組存放在內(nèi)存中是以兩個(gè)字節(jié)對齊的,這就導(dǎo)致了CPU無法讀取數(shù)據(jù)并死機(jī)在了讀取float數(shù)據(jù)類型處外驱;

主管提出育灸,能否直接指定該數(shù)組的存在于內(nèi)存中的起始地址?我一想昵宇,確實(shí)是磅崭,只要頭地址對了那就啥問題也沒有了。

主管又補(bǔ)充了一句瓦哎,他測試過了 #pragma pack(4) 這種編譯命令砸喻,實(shí)際效果是沒效果柔逼,于是我上網(wǎng)查了下,這個(gè)命令確實(shí)是數(shù)據(jù)對齊的命令割岛,但是只是對于結(jié)構(gòu)體內(nèi)部愉适。對于數(shù)組頭地址,我開始覺得有點(diǎn)挑戰(zhàn)了癣漆;

而且方法要簡單维咸,不要影響程序的運(yùn)行效率問題;

問題嘗試

今天在處理上次開會中提到的內(nèi)存分配的問題扑媚,改著改著忽然就靈光一閃腰湾,覺得這個(gè)問題應(yīng)該是可以解決的:

我拿出了自己使用的比較利索的C語言工具->IAR workbench for ARM; 測試平臺當(dāng)然還是最熟悉的Kinetis 系列的 K66 啦疆股!

先定義以下變量:測試看看存放于內(nèi)存中的位置费坊,代碼如下:

char aa[2] = {1,2}旬痹;

查看地址的方式有兩個(gè):

  • 通過IAR編譯器生成的MAP文件進(jìn)行查找
  • 就是通過IAR DEBUG工具中的 watch工具進(jìn)行查看

而我這種偷懶王必須采用第二種方式啊附井,多么直觀,哈哈哈哈两残;
如下是我通過IAR Debug watch中查看到的相關(guān)信息:

Expression Value Location Type
aa <<a>array>"??" 0x1FFF0070 char[2]
bb <<a>array>"??" 0x1FFF0072 char[2]

可以看出上面aa存放地址是 0x1FFF0070 而bb的地址存放在0x1FFF0072地址上永毅,bb的起始地址是一個(gè)2字節(jié)對齊的地址,并非四地址對齊的地址人弓。

明確目標(biāo)沼死,向前進(jìn)發(fā)

準(zhǔn)備修改bb的首地址到一個(gè)四字節(jié)對齊的地址上,或者八字節(jié)對齊的地址上

目標(biāo)明確過后就是嘗試了崔赌,我首先嘗試了下主管說過的

#pragma pack(x) ;

這類編譯命令意蛀,不出意外,一點(diǎn)影響都沒有健芭;

直到今天县钥,一個(gè)偶然中想到了是否可以使用IAR 鏈接時(shí)候使用的ICF文件(鏈接文件)進(jìn)行處理;
好慈迈,說做就做:開始嘗試若贮,寫了一個(gè)簡單的鏈接代碼測試一下:

//define block to place test  value 

define symbol m_data_start   = 0x1FFF0000;

define symbol m_data_end    = 0x1FFFFFFF;

define memory mem with size = 4G;    

define region test_region = mem:[from m_data_start to m_data_end];

define block  test_block with alignment = 4 {section .test};

place in test_region {block test_block};

這里定義了一下鏈接文件(*.icf)將 .test這個(gè)段放在了0x00000410 ~ 0x1FFFFFFF這個(gè)區(qū)段中以四字節(jié)對齊的地址上;

然后回去在變量定義中修改成如下代碼:

char aa[2] = {1,2};

#pragma location = ".test"

char bb[2] = {3,4};

這里意思是數(shù)組aa依然按照編譯器缺省規(guī)則編譯痒留,而數(shù)組bb則存放到 .test段中谴麦;

究竟是否成功呢?打開IAR Debug watch:驚喜啊狭瞎,真的是跋敢啤:

以下是4字節(jié)對齊aa、bb首地址

Expression Value Location Type
aa <<a>array>"??" 0x1FFF0070 char[2]
bb <<a>array>"??" 0x1FFF04A8 char[2]

好家伙熊锭,真的是成了四字節(jié)對齊的地址了(0x1FFF04A8 % 4 == 0)弧轧;為了確保是這個(gè)樣子雪侥,多實(shí)驗(yàn)幾下看看,看看是不是對的精绎,于是將鏈接中關(guān)于對齊部分代碼修改如下:

define block  test_block with alignment = 8 {section .test};

再使用IAR debug watch查看一下地址:

以下是8字節(jié)對齊的aa速缨、bb首地址

Expression Value Location Type
aa <<a>array>"??" 0x1FFF0070 char[2]
bb <<a>array>"??" 0x1FFF04A8 char[2]

地址竟然和上面一樣,使用計(jì)算器計(jì)算一下發(fā)現(xiàn)(0x1FFF04A8 % 8 == 0)代乃,確定是8字節(jié)對齊的旬牲。

我心里還是有點(diǎn)疑慮,看看16搁吓、32字節(jié)對齊會有啥樣子原茅?

以下是16字節(jié)對齊的aa、bb首地址

Expression Value Location Type
aa <<a>array>"??" 0x1FFF0070 char[2]
bb <<a>array>"??" 0x1FFF04B0 char[2]

新地址計(jì)算一下(0x1FFF04B0 % 16 == 0 )

以下是32字節(jié)對齊的aa堕仔、bb首地址

Expression Value Location Type
aa <<a>array>"??" 0x1FFF0070 char[2]
bb <<a>array>"??" 0x1FFF04C0 char[2]

新地址計(jì)算一下(0x1FFF04C0 % 32 == 0 )

結(jié)論

通過這一系列的嘗試擂橘。發(fā)現(xiàn)ICF文件(鏈接文件)中的塊alignment關(guān)鍵字可以使塊的首地址按照2^x(2,4,8,16,32...)方式對齊;而我們定義這一個(gè)塊就存放一個(gè)變量摩骨,那么這個(gè)變量的首地址的對齊方式就是一個(gè)可控的值通贞。

展望

由于項(xiàng)目中使用的參數(shù)文件是上位機(jī)生成的一個(gè)數(shù)組,按道理這個(gè)參數(shù)是不需要被被修改的恼五,本著提高CPU的效率考慮(CPU復(fù)位時(shí)候程序初始化需要搬運(yùn).data段到RAM中)昌罩,我們可以定義到該變量到CODE中成為一個(gè)常量表,可以提高系統(tǒng)啟動(dòng)的速率灾馒;

以下為改進(jìn)的icf文件關(guān)鍵代碼:

//define block to place test  value 

define symbol m_text_start    = 0x00000410;

define symbol m_text_end     = 0x001FFFFF;

define memory mem with size = 4G;    

define region test_region = mem:[from m_text_start to m_text_end];

define block  test_block with alignment = 4 {section .test};

place in test_region {block test_block};

以下為改進(jìn)了的測試數(shù)組定義

char aa[2] = {1,2};

#pragma location = ".test"

const char bb[2] = {3,4};

以下是通過IAR Debug Watch 所觀察到的變量數(shù)據(jù):

Expression Value Location Type
aa <<a>array>"??" 0x1FFF0070 char[2]
bb <<a>array>"??" 0x00013748 char[2]

可以發(fā)現(xiàn)該地址存在于flash空間中茎用,仍然是一個(gè)4字節(jié)對齊的地址,成功睬罗,哈哈哈哈绘搞,這次任務(wù)完成;

寄語

樓主文筆特別差傅物,很多時(shí)候表詞不達(dá)意,或者用詞錯(cuò)誤琉预,亦或者對于東西理解不深入等等董饰。但是希望我的分享能夠解決你的實(shí)際問題。也希望你閱讀過程中發(fā)現(xiàn)對文章的技術(shù)或者其他方法有懷疑的提出反饋圆米,一起討論學(xué)習(xí)卒暂,一起進(jìn)步。謝謝閱讀娄帖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末也祠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子近速,更是在濱河造成了極大的恐慌诈嘿,老刑警劉巖堪旧,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異奖亚,居然都是意外死亡淳梦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門昔字,熙熙樓的掌柜王于貴愁眉苦臉地迎上來爆袍,“玉大人,你說我怎么就攤上這事作郭≡赡遥” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵夹攒,是天一觀的道長蜘醋。 經(jīng)常有香客問我,道長芹助,這世上最難降的妖魔是什么堂湖? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮状土,結(jié)果婚禮上无蜂,老公的妹妹穿的比我還像新娘。我一直安慰自己蒙谓,他們只是感情好斥季,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著累驮,像睡著了一般酣倾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谤专,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天躁锡,我揣著相機(jī)與錄音,去河邊找鬼置侍。 笑死映之,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蜡坊。 我是一名探鬼主播杠输,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼秕衙!你這毒婦竟也來了蠢甲?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤据忘,失蹤者是張志新(化名)和其女友劉穎鹦牛,沒想到半個(gè)月后搞糕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡能岩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年寞宫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拉鹃。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辈赋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出膏燕,到底是詐尸還是另有隱情钥屈,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布坝辫,位于F島的核電站篷就,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏近忙。R本人自食惡果不足惜竭业,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望及舍。 院中可真熱鬧未辆,春花似錦、人聲如沸锯玛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽攘残。三九已至拙友,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間歼郭,已是汗流浹背遗契。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留病曾,地道東北人姊途。 一個(gè)月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像知态,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子立叛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 開篇廢話 這幾天一直忙著積累知識负敏,還沒有來得及總結(jié)呢,前些日子講述了一種在C語言環(huán)境中設(shè)置數(shù)組的對齊的方式秘蛇,但是那...
    爪爪熊閱讀 2,663評論 2 5
  • 指針是C語言中廣泛使用的一種數(shù)據(jù)類型其做。 運(yùn)用指針編程是C語言最主要的風(fēng)格之一顶考。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu); ...
    朱森閱讀 3,446評論 3 44
  • 昨天被其他用戶提醒《婆媳之間的那些事》被鎖定妖泄,看了半天不知是怎么回事驹沿?心里還總在嘀咕是不是哪個(gè)用戶看上自己沒寫完的...
    薔薇花兒落地開閱讀 141評論 2 2
  • 小時(shí)候,很多人大概都寫過這樣的作文蹈胡。長大了渊季,我要成為什么樣的人。 有人說罚渐,我要成為科學(xué)家...老梗却汉,有人說我要當(dāng)明...
    Connection_u_i閱讀 553評論 0 0
  • “這次可以給我照片了嗎?”嘟嘟荷并,糖糖的手機(jī)里忽然傳來一條微信合砂。糖糖一頭烏黑的長發(fā)如瀑布般披在肩上,一雙大眼睛閃閃發(fā)...
    一滴露水閱讀 426評論 9 5