Linux下STM32開發(2)——簡單工程編寫、編譯與下載(Makefile)

一、先搭建好環境:

Linux下STM32開發(1)——編譯和燒錄環境搭建

 

二、需要的文件:

(1)啓動文件:startup_stm32f10x_hd.s

(2)鏈接文件:stm32_flash.ld

(3)c源碼文件:main.c

(4)頭文件:stm32f10x.h

(5)Makefile

完整工程文件下載:Linux下STM32編譯、燒錄示例工程 

打開下載的標準庫:STM32F10x_StdPeriph_Lib_V3.5.0STM32F10x標準庫V3.5(CSDN)因爲truestudio使用的是gcc編譯器,所以我們使用其文件夾的文件。

 

三、啓動文件

所在目錄:STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\TrueSTUDIO

 

四、鏈接文件

所在目錄:STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template\TrueSTUDIO

文件夾下是各種官方開發板的例子:

STM3210B-EVAL Linker script for STM32F103VB Device with 128KByte FLASH, 20KByte RAM
STM3210C-EVAL Linker script for STM32F107VC Device with 256KByte FLASH, 64KByte RAM
STM3210E-EVAL Linker script for STM32F103ZE Device with  512KByte FLASH, 64KByte RAM
STM3210E-EVAL_XL Linker script for STM32F103ZG Device with 1MByte FLASH, 96KByte RAM
STM32100B-EVAL Linker script for STM32F100VB Device with 128KByte FLASH, 8KByte RAM
STM32100E-EVAL Linker script for High-density value line Devices (STM32F100xE) with 512KByte FLASH, 32KByte RAM
stm32f10x_flash_extsram.ld Linker script for STM32F10x XL-density Devices with 1MByte FLASH, 96KByte RAM

如果沒有對應的芯片,需要根據使用的芯片修改  stm32_flash.ld 文件,可以修改RAM、ROM、堆棧大小等。

 

五、main.c

一個簡單的操作寄存器點燈程序:

#include "stm32f10x.h" 


int main(void)
{	
	// 開啓GPIOB 端口時鐘
	RCC_APB2ENR |= (1<<3);

	//清空控制PB0的端口位
	GPIOB_CRL &= ~( 0x0F<< (4*0));	
	// 配置PB0爲通用推輓輸出,速度爲10M
	GPIOB_CRL |= (1<<4*0);

	// PB0 輸出 低電平
	GPIOB_ODR &= ~(1<<0);
	
	while(1);
}



// 函數爲空,目的是爲了騙過編譯器不報錯
void SystemInit(void)
{	
}

 

六、stm32f10x.h

寄存器地址及結構體定義

/*本文件用於添加寄存器地址及結構體定義*/

/*片上外設基地址  */
#define PERIPH_BASE           ((unsigned int)0x40000000)

/*APB2 總線基地址 */
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
/* AHB總線基地址 */
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)

/*GPIOB外設基地址*/
#define GPIOB_BASE            (APB2PERIPH_BASE + 0x0C00)

/* GPIOB寄存器地址,強制轉換成指針 */
#define GPIOB_CRL			*(unsigned int*)(GPIOB_BASE+0x00)
#define GPIOB_CRH			*(unsigned int*)(GPIOB_BASE+0x04)
#define GPIOB_IDR			*(unsigned int*)(GPIOB_BASE+0x08)
#define GPIOB_ODR			*(unsigned int*)(GPIOB_BASE+0x0C)
#define GPIOB_BSRR	  *(unsigned int*)(GPIOB_BASE+0x10)
#define GPIOB_BRR			*(unsigned int*)(GPIOB_BASE+0x14)
#define GPIOB_LCKR		*(unsigned int*)(GPIOB_BASE+0x18)

/*RCC外設基地址*/
#define RCC_BASE      (AHBPERIPH_BASE + 0x1000)
/*RCC的AHB1時鐘使能寄存器地址,強制轉換成指針*/
#define RCC_APB2ENR		 *(unsigned int*)(RCC_BASE+0x18)

 

七、編譯步驟

在 gcc-arm-none-eabi/share/doc/gcc-arm-none-eabi 文件夾的readme.txt 有詳細的指令說明。

(1)啓動文件編譯(不進行預處理,並且正常提示告警信息)

arm-none-eabi-gcc -c -mthumb -mcpu=cortex-m3 -g -Wa,--warn -o startup_stm32f10x_hd.o startup_stm32f10x_hd.s

-mthumb:編譯全編譯成thumb指令集

-mcpu=cortex-m3 :cpu內核選擇

-Wa,--warn    向彙編器Assembler傳遞參數,正常提示告警信息

-W或–no-warn 關閉所有告警
–fatal-warnings  將所有的警告提示爲錯誤
–warn 正常提示告警信息

啓動文件一般是由彙編寫成,彙編文件的格式有.S和.s之分:

  • .S:表明文件中含有預處理指令(比如#define),需要先進行處理;
  • .s:表明文件不需要處理,可以直接編譯;

之前添加的啓動文件是小寫.s,所以直接進行編譯。如果使用的是.S文件,需要帶上-x assembler-with-cpp參數先進行預處理。

編譯後生成 startup_stm32f10x_hd.o 文件



(2)c源文件編譯

arm-none-eabi-gcc -c -mthumb -mcpu=cortex-m3 -g -Wall -o main.o main.c
-wall 輸出所有警告

 編譯後生成 main.o 文件

(3)鏈接

arm-none-eabi-gcc -o test.elf main.o startup_stm32f10x_hd.o -mthumb -mcpu=cortex-m3 -T stm32_flash.ld -specs=nosys.specs -static -Wl,-cref,-u,Reset_Handler -Wl,-Map=test.map -Wl,--gc-sections -Wl,--defsym=malloc_getpagesize_P=0x80 -Wl,--start-group -lc -lm -Wl,--end-group

鏈接器根據 stm32_flash.ld 文件鏈接 startup_stm32f10x_hd.omain.o 兩個文件,生成包含調試信息的elf文件。

-T 指定鏈接文件

鏈接後生成 test.elf 和 test.map 文件

 

(4)生成 bin 和 hex 文件

arm-none-eabi-objcopy test.elf test.bin
arm-none-eabi-objcopy test.elf -Oihex test.hex

利用arm-none-eabi-objcopy工具可以將elf文件轉化爲適合於單片機的bin文件和hex文件,其中參數-O(大寫o)用於指定輸出文件的格式(默認是bin格式)

生成 test.hex 和 test.bin 文件

 

八、Makefile

集合以上的步驟編寫Makefile

TARGET=test
CC=arm-none-eabi-gcc
OBJCOPY=arm-none-eabi-objcopy
RM=rm -f
CORE=3
CPUFLAGS=-mthumb -mcpu=cortex-m$(CORE)
LDFLAGS = -T stm32_flash.ld -Wl,-cref,-u,Reset_Handler -Wl,-Map=$(TARGET).map -Wl,--gc-sections -Wl,--defsym=malloc_getpagesize_P=0x80 -Wl,--start-group -lc -lm -Wl,--end-group
CFLAGS=-g -o
$(TARGET):startup_stm32f10x_hd.o main.o
	$(CC) $^ $(CPUFLAGS) $(LDFLAGS) $(CFLAGS) $(TARGET).elf
startup_stm32f10x_hd.o:startup_stm32f10x_hd.s
	$(CC) -c $^ $(CPUFLAGS) $(CFLAGS) $@
main.o:main.c
	$(CC) -c $^ $(CPUFLAGS) $(CFLAGS) $@

bin:
	$(OBJCOPY) $(TARGET).elf $(TARGET).bin
hex:
	$(OBJCOPY) $(TARGET).elf -Oihex $(TARGET).hex
clean:
	$(RM) *.o $(TARGET).*
  • 使用命令make編譯生成elf文件;
  • 使用命令make bin將elf文件轉化生成bin文件;
  • 使用命令make hex將elf文件轉化生成hex文件;
  • 使用命令make clean即可清除掉所有編譯產生的文件。

 

九、下載燒錄

ST-LINK:

使用的命令

  • openocd -f <接口配置文件> -f <目標芯片配置文件>(絕對路徑)
  • telnet localhost 4444
  • >halt
  • >flash write_image erase <燒錄文件>(絕對路徑)
  • >reset

(1)配置使用 stlink 連接到 stm32f1x 芯片

openocd -f /usr/local/share/openocd/scripts/interface/stlink-v2.cfg -f /usr/local/share/openocd/scripts/target/stm32f1x.cfg 

 

(2)使用telnet連接到openocd

打開另外一個終端(上一個終端不要關閉),輸入以下命令:

telnet localhost 4444

(3)使用以下命令燒錄 

命令 描述
halt 芯片掛起,相當於關機
flash write_image erase <燒錄文件> 將文件下載到芯片flash(使用絕對路徑)
reset 芯片復位
flash write_image erase /home/pjw/STM32/project/LED

 

(4)第一個終端會相應輸出信息:

 

九、修改Makefile,實現一鍵下載

(1)修改Makefile:

定義openocd 的路徑,燒錄器,芯片型號:

TARGET=test
CC=arm-none-eabi-gcc
OBJCOPY=arm-none-eabi-objcopy
RM=rm -f
CORE=3
CPUFLAGS=-mthumb -mcpu=cortex-m$(CORE)
LDFLAGS = -T stm32_flash.ld -Wl,-cref,-u,Reset_Handler -Wl,-Map=$(TARGET).map -Wl,--gc-sections -Wl,--defsym=malloc_getpagesize_P=0x80 -Wl,--start-group -lc -lm -Wl,--end-group
CFLAGS=-g -o
INTERRFACE_CFG=/usr/local/share/openocd/scripts/interface/stlink-v2.cfg
TARGET_CFG=/usr/local/share/openocd/scripts/target/stm32f1x.cfg 
PWD=$(shell pwd)

$(TARGET):startup_stm32f10x_hd.o main.o
	$(CC) $^ $(CPUFLAGS) $(LDFLAGS) $(CFLAGS) $(TARGET).elf
startup_stm32f10x_hd.o:startup_stm32f10x_hd.s
	$(CC) -c $^ $(CPUFLAGS) $(CFLAGS) $@
main.o:main.c
	$(CC) -c $^ $(CPUFLAGS) $(CFLAGS) $@

bin:
	$(OBJCOPY) $(TARGET).elf $(TARGET).bin
hex:
	$(OBJCOPY) $(TARGET).elf -Oihex $(TARGET).hex
clean:
	$(RM) *.o $(TARGET).*
	
downlad:
	openocd -f $(INTERRFACE_CFG) -f $(TARGET_CFG) -c init -c halt -c "flash write_image erase $(PWD)/$(TARGET).bin" -c reset -c shutdown

(2)使用 make download 命令即可下載,如圖,下載成功

 

參考:

https://blog.csdn.net/Mculover666/article/details/84888539

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章