C語言再學習24——__attribute__ (at())地址定位

前言:

爲了方便查看博客,特意申請了一個公衆號,附上二維碼,有興趣的朋友可以關注,和我一起討論學習,一起享受技術,一起成長。

在這裏插入圖片描述


1. __ attribute __((at)) 絕對定位

__ attribute __( at(絕對地址) )的作用:

(1)絕對定位到 Flash;

(2)絕對定位到 RAM。

__ attribute __ :用來指定變量或結構位域的特殊屬性,關鍵字後的雙括弧中的內容是屬性說明;

at:用來設置變量的絕對地址,指定某個變量處於內存或 FLASH 裏面的某個給定的地址。

1.1 定位到 FLASH

定位到 flash 中,常用於固化信息,例如:設備的出廠信息,FLASH 標記等;

const uint8_t usFlashInitVal[] __attribute__((at(0x00030000))) = {0x11,0x22,0x33,0x44,0x55,0x66};//定位在flash中,0x00030000開始的6個字節信息固定

1.2 定位到 RAM

常用於數據量較大的緩存,如:串口接收數據。也用於某個位置的特定變量。

uint8_t ucUsartRecvBuffer[USART_RECV_LEN] __attribute__ ((at(0x00025000)));	//接收緩衝,最大USART_RECV_LEN個字節,起始地址爲 0x00025000

注:

  1. 絕對定位不能在函數中定義,局部變量是定義在棧區,棧區是自動分配、釋放,不能定義爲絕對地址,只能於函數外定義;

  2. 定義的長度不能超過棧或 Flash 的大小,否則導致棧、Flash 溢出。

1.3 測試

比如:在 0x08010000 的 flash 地址上固定寫入數據,如下圖:

在這裏插入圖片描述
如果不加 const 修飾,則定位到了 RAM 。

編譯出來各部分文件大小:

在這裏插入圖片描述

打開編譯出來二進制文件,如下圖:

在這裏插入圖片描述
最後,我們來看一下加與不加 const uint8_t ucaSysFlashVal[] attribute((at(0x08010000))) =
{0x11, 0x22, 0x33, 0x44}; 的 map 表的區別:

原編譯結束的 map 文件各部分文件大小:

在這裏插入圖片描述

添加定位代碼後的 map 文件各部分的大小:

在這裏插入圖片描述
可以發現添加後,RO Data 的大小發生了變化,即定位後 FLASH 的空間佔用加大,並且打開 bin 文件,可以發現中間部分由全 0 填充。


參考:

  1. C語言中__attribute__ ((at())絕對定位的應用
  2. STM32學習筆記之__attribute__ ((at())絕對定位分析
  3. MDK const U16__attribute__((at(0x0800E400)))RO-data統計特別大
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章