C語言編譯步驟
1.預處理 gcc -E
2.編譯 gcc -S
3.彙編 gcc -C
4.連線 gcc -l
複製程式碼
- 預處理
- 一般就是處理巨集以及標頭檔案
- 編譯
- 在這個階段將C語言轉化為彙編程式碼。
- 一般會進行程式的優化
- 彙編
- 將彙編程式碼轉化為機器碼
- 連線
程式元件 | 所屬類別 |
---|---|
機器程式碼指令 | Code |
常量 | RO-data |
初值非0的全域性變數 | RW-data |
初值為0的全域性變數 | ZI-data |
區域性變數 | ZI-data棧空間 |
使用malloc動態分配的空間 | ZI-data堆空間 |
程式狀態與區域 | 組成 |
---|---|
程式執行時的只讀區域(RO) | Code + RO data |
程式執行時的可讀寫區域(RW) | RW data + ZI data |
程式儲存時佔用的ROM區 | Code + RO data + RW data |
*.dep,*.d依賴檔案
- Dependency file
- 記錄的是工程或其它檔案的依賴,主要記錄了引用的標頭檔案路徑,其中*.dep是整個工程的依賴,它以工程名命名,而*.d是單個原始檔的依賴,它們以對應的原始檔名命名。
*.crf交叉引用檔案
- Cross-Reference file
- 它主要包含了瀏覽資訊(browse information),即原始碼中的巨集定義、變數及函式的定義和宣告的位置。
o、axf及elf檔案
- *.o、*.elf、*.axf以及前面提到的lib檔案都是屬於目標檔案,它們都是使用ELF格式來儲存的。
- Executable and Linking Format
- 目標檔案主要有如下三種型別
- 可重定位的檔案(Relocatable File),包含基礎程式碼和資料,但它的程式碼及資料都沒有指定絕對地址,因此它適合於與其他目標檔案連結來建立可執行檔案或者共享目標檔案。 這種檔案一般由編譯器根據原始碼生成。
- 可執行檔案(Executable File) ,它包含適合於執行的程式,它內部組織的程式碼資料都有固定的地址(或相對於基地址的偏移),系統可根據這些地址資訊把程式載入到記憶體執行。這種檔案一般由連結器根據可重定位檔案連結而成,它主要是組織各個可重定位檔案,給它們的程式碼及資料一一打上地址標號,固定其在程式內部的位置,連結後,程式內部各種程式碼及資料段不可再重定位(即不能再參與連結器的連結)。
- 共享目標檔案(Shared Object File), 它的定義比較難理解,我們直接舉例,MDK生成的*.lib檔案就屬於共享目標檔案,它可以繼續參與連結,加入到可執行檔案之中。另外,Linux的.so,如/lib/ glibc-2.5.so,Windows的DLL都屬於這一類
常見檔案型別
sct 分散載入檔案的格式與應用
當工程按預設配置構建時, MDK 會根據我們選擇的晶片型號,獲知晶片的內部 FLASH 及內部 SRAM 儲存器概況,生成一個以工程名命名的字尾為*.sct 的分散載入檔案 (Linker Control File, scatter loading)。
程式啟動後連結地址和啟動地址有可能不一樣。會有一段程式將所有的程式自舉到連結地址指定的地方。
儲存 | 大小(十進位制) | 大小(十六進位制) | 起始地址 |
---|---|---|---|
片上儲存 RAM(ITCM) | 512K | 0x0008 0000 | 0x0000 0000 |
off-chip SDRAM | 32M | 0x0200 0000 | 0x8000 0000 |
QSPI nor Flash | 32M | 0x0200 0000 | 這個是由自己對映的 |
NAND Flash | 128M | 0x8000 0000 | 同樣是自己對映的 |
片上 DTCM | 512k | 0x0008 0000 | 0x2000 0000 |
假設使用 QSPI nor flash。將其對映到 0x80000000的地址(SEMC external memories 起始地址)。
#define m_data_start 0x80000000
#define m_data_size 0x01E00000
#define m_ncache_start 0x81E00000
#define m_ncache_size 0x00200000
#define m_data2_start 0x20000000
#define m_data2_size 0x00020000
#define m_data3_start 0x20200000
#define m_data3_size 0x00040000
複製程式碼
如上,分為了四個段。
- m_data_start與m_ncache_start共同佔據所有QSPI nor flash的地址。
- m_data2_start與m_data3_start共同佔據部分DTCM區域
- 那麼最上面圖中IRAM2配置的就是ITCM的區域了。只不過ITCM的大小是可以配置的。猜測是為了相容以前的晶片。
- 不過以前只是用過arm9。不清楚ITCM的操作,等以後補上。
程式狀態與區域 | 組成 |
---|---|
程式執行時的只讀區域(RO) | Code + RO Data |
程式執行時的讀寫區域(RW) | RW Data+ ZI Data |
程式儲存時的佔用區域(ROM) | Code + RO Data +RW Data |
節區屬性描述符 | 說明 |
---|---|
RO code & Code | 只讀程式碼段 |
RO Data & Const | 只讀資料段 |
RO & TEXT | 包括RO code 和 RO Data |
RW Data | 讀寫資料段 |
RW CODE | 讀寫程式碼段 |
RW & Data | 包括 RW Data 和 RW Code |
ZI & BSS | 初始為0的段 |
XO | 只可執行的段 |
ENTRY | 節區的入口 |
上面m_data_start表示的是片上chip的可讀寫區域開始地址。
- m_flash_config_start就是片上flash的起始地址以及大小。
- m_data2_start就是片外的sdram的起始地址以及大小。
更正
*.sct 檔案 改成 *.scf檔案。在工程檔案中沒找到*.sct。興許是改名字了。但是沒找到關於官方檔案的解釋。暫且先這樣。
參考資料
MDK的編譯過程及檔案型別全解 https://flash-rtd.readthedocs.io/zh_CN/latest/
MDK的幫助手冊 《ARM Development Tools》
Keil sct分散載入檔案 https://blog.csdn.net/kobesdu/article/details/38258449
KEIL下分散載入檔案 *.sct檔案 http://www.cnblogs.com/darren-715/p/3457214.html
MDK的編譯過程及檔案型別全解 https://www.cnblogs.com/yangguang-it/p/7697967.html
配置DTCM,ITCM和OCRAM http://forum.armfly.com/forum.php?mod=viewthread&tid=86733
如何讓RT1050的程式碼執行速度飛起來 http://www.eeworld.com.cn/mp/ZLG/a57247.jspx
複製程式碼