【嵌入式】基于makefile的STM32編譯方法探索

0.前言

初學(xué)單片機的時候通常使用IDE(通常是keil),IDE的好處是上手快捷谴麦;但是IDE將很多東西屏蔽了蠢沿,例如什么是編譯、鏈接匾效、加載文件等舷蟀。編譯、鏈接功能均是由一個個命令實現(xiàn)的面哼,如果把這些命令比作工地上干活的工人野宜,那么makefile就是指導(dǎo)工人干活的圖紙,make命令這是負(fù)責(zé)解讀makefile這張圖紙的工程師精绎。出于好奇心驅(qū)使決定嘗試使用makefile方式編譯stm32的程序速缨。

先介紹總體思路,makefile只是一個工具代乃,makefile也需要調(diào)用IDE背后的命令工具旬牲,所以要想實現(xiàn)用makefile編譯STM32 程序需要分兩步走:

  • 搞懂keil怎么將一個個源碼程序轉(zhuǎn)換為可以下載到芯片中的文件仿粹。
  • 用makefile的方式將IDE做的工作實現(xiàn)。

1.解密keil

1.1 IDE的bat文件

在keil下新建一個工程原茅,


圖1 設(shè)置工程屬性
圖2 選擇生成batch file

如圖2 所示吭历,在output->Create Batch File,編譯后在工程目錄下找到了led.BAT文件,

SETPATH=F:\keil\ARM\BIN40\;C:\Python27\Lib\sitepackages\PyQt4;C:\PROGRAMDATA\ORACLE\JAVA\JAVAPATH;C:\Windows\SYSTEM32;C:\Windows;C:\Windows\SYSTEM32\WBEM;C:\Windows\SYSTEM32\WINDOWSPOWERSHELL\V1.0\;D:\FLASH MAGIC;D:\PROGRAM FILES (X86)\MATLAB\RUNTIME\WIN64;D:\PROGRAM FILES (X86)\MATLAB\BIN;D:\PROGRAM FILES (X86)\MATLAB\POLYSPACE\BIN;D:\PROGRAM FILES (X86)\FLASH MAGIC;D:\software\Bluetooth Software\;D:\software\Bluetooth Software\syswow64;D:\Program Files\common;C:\Program Files (x86)\Microsoft SQL Server\90\Tools\binn\;C:\Program Files\CMake\bin;C:\Python27;F:\Program Files (x86);F:\keil\ARM\BIN40
SET ARMCC41INC=F:\keil\ARM\RV31\INC
SET ARMCC41LIB=F:\keil\ARM\RV31\LIB
SET CPU_TYPE=STM32F103C8
SET CPU_VENDOR=STMicroelectronics
SET UV2_TARGET=led
SET CPU_CLOCK=0x00000000                                                                                    
"F:\keil\ARM\BIN40\ArmCC" --Via "main.__i"
"F:\keil\ARM\BIN40\ArmCC" --Via "stm32f10x_it.__i"
"F:\keil\ARM\BIN40\ArmAsm" --Via ".\startup_stm32f10x_md._ia"
"F:\keil\ARM\BIN40\ArmCC" --Via "stm32f10x_gpio.__i"
"F:\keil\ARM\BIN40\ArmCC" --Via "stm32f10x_rcc.__i"
"F:\keil\ARM\BIN40\ArmCC" --Via "core_cm3.__i"
"F:\keil\ARM\BIN40\ArmCC" --Via "system_stm32f10x.__i"
"F:\keil\ARM\BIN40\ArmLink" --Via "led.lnp"
F:\keil\ARM\BIN40\fromelf.exe "led.axf" --i32combined --output "led.hex"

神奇的是擂橘,運行該bat文件(PS:bat是windows下的一種批處理文件晌区,類似于linux下的shell腳本),竟然就可以生成想要的hex文件通贞±嗜簦看來keil的奧秘就藏在這個bat文件中了。bat文件分為兩段昌罩,第一段是 幾個SET命令哭懈,設(shè)置了一些變量;第二段是ArmCC茎用,ArmAsm遣总,ArmLink,fromelf.exe命令構(gòu)成轨功,但是 --Via “main.__i” 這種是什么鬼就不得而知旭斥。

1.2 編譯

查看keil的幫助文檔:
--via=filename*

This option instructs the compiler to read additional command-line options
from a specified file. The options read from the file are added to the current
command line. Via commands can be nested within via files.

Syntax

--via=*filename

Where:

*filename

is the name of a via file containing options to be included on the command line.

Example

Given a source file main.c, a via file apcs.txt containing the line:

--apcs=/rwpi --no_lower_rwpi --via=L_apcs.txt 

and a second via file L_apcs.txt containing the line:

-L--rwpi -L--callgraph

compiling main.c with the command line:

armcc main.c -L-o”main.axf" --via=apcs.txt

compiles main.c using the command line:

armcc --no_lower_rwpi --apcs=/rwpi -L--rwpi -L--callgraph -L-o"main.axf" main.c

現(xiàn)在清楚了,編譯一個文件需要指定各種編譯選項古涧,這些選項可以直接寫在命令行中垂券,同時可以將這些命令選項寫在一個文件中,然后使用“--via”指明該文件蒿褂。
打開生成的main.__i文件圆米,內(nèi)容如下:

-c 
--cpu Cortex-M3 
-g 
-O0 
--apcs=interwork 
-IE:\src\stm32\CMSIS -IE:\src\stm32\StartUp -IE:\src\stm32\StdPeriph_Lib\inc -IE:\src\stm32\led -I "F:\keil\ARM\INC" -I "F:\keil\ARM\INC\ST\STM32F10x" 
-DSTM32F10X_MD -DUSE_STDPERIPH_DRIVER
-o "main.o" 
--omf_browse "main.crf" --depend "main.d" "E:\src\stm32\led\main.c"

這些都是執(zhí)行armcc命令帶的參數(shù),-c啄栓,-I -g是比較通用娄帖,--cpu顯然是指明CPU的類型,編寫makefile的時候可以直接借用昙楚。

1.3 鏈接

執(zhí)行ArmLink命令時候的使用的命令參數(shù)在文件led.lnp中近速,其中內(nèi)容如下:

--cpu Cortex-M3 "main.o" "stm32f10x_it.o" ".\startup_stm32f10x_md.o" "stm32f10x_gpio.o" "stm32f10x_rcc.o" "core_cm3.o" "system_stm32f10x.o" --strict --scatter "led.sct" 
--autoat --summary_stderr --info summarysizes --map --xref --callgraph --symbols 
--info sizes --info totals --info unused --info veneers 
 --list ".\led.map" -o "led.axf"

注意其中的--scatter "led.sct",該選項表示鏈接器ArmLink使用的鏈接文件led.sct; -o "led.axf",表示鏈接生成的目標(biāo)文件堪旧。
知識點:hex削葱,axf,bin淳梦,elf格式文件文件

  • bin文件:最純粹的二進(jìn)制文件析砸,就是匯編程序直接匯編成為二進(jìn)制代碼,在裸機
    條件下運行的是bin文件爆袍∈追保可以說bin文件是沒有其他幾種格式文件復(fù)雜的格式作郭。
    文件本身不包含任何地址信息,在將bin文件燒寫到flash中必須要指定地址弦疮。
  • hex文件:intel格式文件夹攒,它里面除包含精華的bin部分還有其他的一些信息,
    hex文件常常被用做很多ISP工具的文件格式胁塞。
  • axf文件:arm調(diào)試文件格式咏尝,同樣這個文件格式的文件除包含bin文件部分,還包含
    了一些調(diào)試相關(guān)的信息啸罢。
  • elf文件:是一種目標(biāo)文件格式编检,在有操作系統(tǒng)條件下例如linux中的目標(biāo)文件就是
    采用elf文件格式,這種文件需要在有OS的支持下才可以運行伺糠。如果將elf文件放到
    裸機中運行蒙谓,肯定會出錯。
  • 聯(lián)系 這幾種文件格式中bin文件是最為基本的训桶,bin文件是沒有任何的
    “雜質(zhì)”的機器碼文件,其他的幾種格式的文件都是在這種文件的基礎(chǔ)上加入其他相關(guān)的信息形成的酣倾。

1.4 生成hex文件

fromelf.exe "led.axf" --i32combined --output "led.hex" 命令是講生成的axf文件轉(zhuǎn)換為hex文件舵揭,isp下載的使用的就是hex文件。

2.編寫makefile

由之前的分析躁锡,知道了午绳,怎么用命令將源文件轉(zhuǎn)換為hex文件,下面就用makefile將這些命令組合起來映之。

2.1 安裝windows版make工具

下載一個windows版的GNU make工具 拦焚,安裝到本地。http://www.gnu.org/software/make/manual/make.html

2.2 編寫makefile

編寫一個點亮LED的程序杠输,程序本身由startup_stm32f10x_md.s和main.c兩個文件組成赎败。整個編譯makefile由三個文件組成,分別是common_compile.mk,common_config.mk,Makefile
common_compile.mk的內(nèi)容如下

%.o:%.c  
    $(ARMCC) $(CFLAGS) $(INC) $(CMACRO) $< -o $@  
      
%.o:%.s  
    $(ARMASM) $(ASMFLAGS) $(INC) $(CMACRO) $< -o $@    
  
all:$(OBJS)  
    $(ARMLINK) --libpath "$(KEIL_PATH)\RV31\LIB"  $(LINKFLAGS)   $(MAP) $(INFO) $^ -o $(TARGET).axf  
    $(FROMELF) --bin -o $(TARGET).bin $(TARGET).axf  
    $(FROMELF) --i32 -o $(TARGET).hex $(TARGET).axf  
    del $(OBJHTM) $(OBJAXF) $(OBJS)  
  
#   若只是生成LIB庫蠢甲,只需要以下一條命令就可以了   
#   $(ARMAR) $(APPNAME).lib -r $(OBJS)  
          
.PHONY : clean  
  
clean:  
    -del $(OBJS) *.map *.htm 

common_config.mk內(nèi)容如下

SHELL=cmd.exe
KEIL_PATH = F:\Keil\ARM
ARMCC = $(KEIL_PATH)\BIN40\armcc  
ARMASM =$(KEIL_PATH)\BIN40\armasm
ARMAR = $(KEIL_PATH)\BIN40\armar  
ARMLINK =$(KEIL_PATH)\BIN40\armlink  
FROMELF = $(KEIL_PATH)\BIN40\fromelf  
  
TARGET =.\output\stm32
OBJMAP := .\stm32.map 
OBJHTM := .\output\*.htm  
OBJAXF := .\output\*.axf  


CFLAGS := -c --cpu Cortex-M3 -D__MICROLIB -g -O0 --apcs=interwork  
CMACRO :=  
ASMFLAGS := --cpu Cortex-M3 -g --apcs=interwork --pd "__MICROLIB SETA 1"  
LINKFLAGS := --cpu Cortex-M3 --library_type=microlib --scatter=led.sct  --strict  
MAP := --autoat --summary_stderr --info summarysizes --map --xref --callgraph --symbols   
INFO := --info sizes --info totals --info unused --info veneers  

Makefile內(nèi)容如下

include ./common_config.mk
  
OBJS = .\main.o .\startup_stm32f10x_md.o   
         
  
INC += -I$(KEIL_PATH)\INC\St\STM32F10x  
INC += -I$(KEIL_PATH)\RV31\INC  
  
include ./common_compile.mk

命令行中執(zhí)行make命令僵刮,成功編譯輸出bin,hex文件鹦牛。

Paste_Image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末搞糕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子曼追,更是在濱河造成了極大的恐慌窍仰,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件礼殊,死亡現(xiàn)場離奇詭異驹吮,居然都是意外死亡鲫忍,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門钥屈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來悟民,“玉大人,你說我怎么就攤上這事篷就∩淇鳎” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵竭业,是天一觀的道長智润。 經(jīng)常有香客問我,道長未辆,這世上最難降的妖魔是什么窟绷? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮咐柜,結(jié)果婚禮上兼蜈,老公的妹妹穿的比我還像新娘。我一直安慰自己拙友,他們只是感情好为狸,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著遗契,像睡著了一般辐棒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上牍蜂,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天漾根,我揣著相機與錄音,去河邊找鬼鲫竞。 笑死辐怕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贡茅。 我是一名探鬼主播秘蛇,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼顶考!你這毒婦竟也來了赁还?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤驹沿,失蹤者是張志新(化名)和其女友劉穎艘策,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渊季,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡朋蔫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年罚渐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驯妄。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡荷并,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出青扔,到底是詐尸還是另有隱情源织,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布微猖,位于F島的核電站谈息,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏凛剥。R本人自食惡果不足惜侠仇,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望犁珠。 院中可真熱鬧逻炊,春花似錦、人聲如沸盲憎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽饼疙。三九已至,卻和暖如春慕爬,著一層夾襖步出監(jiān)牢的瞬間窑眯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工医窿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留磅甩,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓姥卢,卻偏偏與公主長得像卷要,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子独榴,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

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