開發環境:KEIL-MDK(RealView)
需求說明
要在C代碼程序中獲取編譯器最終生成的bin文件大小。
思路
通過讀取編譯器中生成的鏈接符號變量來計算。
解決方案
比如,測試程序中生成的Code大小爲1906個字節,RO-data的大小爲486個字節。兩者相加1906+486=2392.
項目配置:
分散加載腳本:
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x08000000 0x00080000 { ; load region size_region
ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20000000 0x00020000 { ; RW data
.ANY (+RW +ZI)
}
}
注意:其中的執行域的名稱爲ER_IROM1。
添加代碼:
extern int Image$$ER_IROM1$$RO$$Base;
extern int Image$$ER_IROM1$$RO$$Limit;
#define LINKER_VAR_IROM_START Image$$ER_IROM1$$RO$$Base
#define LINKER_VAR_IROM_LIMIT Image$$ER_IROM1$$RO$$Limit
{
int *pBase, *pLimit;
int nSize;
pBase = &LINKER_VAR_IROM_START;
pLimit = &LINKER_VAR_IROM_LIMIT;
nSize = (int)pLimit - (int)pBase;
}
測試驗證
從圖中可以看出,pBase和pLimit這兩個變量已經得到了鏈接器的結果。兩者相減,結果即爲2392.
還可以用簡單方法:
extern int Image$$ER_IROM1$$RO$$Length;
#define LINKER_VAR Image$$ER_IROM1$$RO$$Length
int n;
n = (int)&LINKER_VAR;
同樣的方法,可以獲取RW部分的大小。
extern int Image$$RW_IRAM1$$RW$$Length;
#define LINKER_VAR_RW Image$$RW_IRAM1$$RW$$Length
int k;
k = (int)&LINKER_VAR_RW;
n+k即可得到bin文件的大小。
參考資料:
MDK-ARM鏈接程序使用了兩種方式控制程序的鏈接,即鏈接控制命令選項和鏈接腳本文件。當使用鏈接控制命令選項時,鏈接器定義了Image%%RW%%Base、Image%%RW%%Limit、Image%%RO%%Base、Image%%RO%%Limit、Image%%ZI%%Base和Image%%ZI%%Limit等6個段地址描述符。這6個描述符可以直接在程序中引用。而在使用鏈接腳本文件後,這6個描述符號沒有了,取而代之的是鏈接腳本文件中的段描述符,格式爲:Image%%段名%%Base 和Image%%段名%%Limit。 (要把上述的%換成$)
http://www.realview.asia/support/man/docs/armlink/armlink_pge1362065952432.htm
Image$$ execution region symbols
https://blog.csdn.net/czg13548930186/article/details/78535419
C代碼中如何使用鏈接腳本中定義的變量