Linux下開發STM32單片機

     一開始學習51單片機就是用的MDK這個IDE軟件,IDE軟件雖然看起來直觀好像更加容易入門(由於有界面看起來很形象),可是實際上IDE倒是向咱們這些入門人員隱藏了背後真實存在的過程,讓咱們覺得編譯就是點一下一個按鍵就完成了。直到使用了大半年的STM32芯片,我以爲不能一直依賴IDE軟件,因此打算試試在Linux下開發STM32,首先須要一個 linux下STM32的編譯器查了一下,度娘告訴我 arm-none-eabi-gcc編譯器是能夠編譯STM32的代碼的,因此須要如今Linux(ubantu)下安裝好arm-none-eabi-gcc這裏就不寫怎麼安裝了。而後咱們開始開發一個STM32的LED程序,可能在MDK軟件下,沒人不會可是在Linux下沒接觸過了就無從下手了。我也是第一次嘗試學習因此記錄下。linux

    由於在MDK上開發過STM32因此我知道須要下面幾個文件shell

core_cm3.c
core_cm3.h
system_stm32f10x.c
stm32f10x.h
stm32f10x_conf.h
system_stm32f10x.h
startup_stm32f103xb.s

因此把他們從之前的工程中考出來,放到linux下的目錄下備用,這裏須要注意是,啓動文件startup_stm32f103xb.s是和MDK下不一樣的須要在ST官網上去下載。ide

 而後須要的瞭解的就是linux下的編譯命令函數

arm-none-eabi-gcc -c  xxx.c -o   name   這個命令就是將一個c文件編譯生成name名稱的.o文件。可是這裏還須要用到一些編譯標誌暫時不用清楚做用,先打通流程最終的編譯命令就是學習

arm-none-eabi-gcc -o   「」name「」  -c   -W -Wall -g -I $(INC)  -lm  -lc -mcpu=cortex-m3 -mthumb -D STM32F10X_HD -D USE_STDPERIPH_DRIVER -O1 -std=gnu11

 

而後是將上面的 c 文件挨個編譯一下,產生對應的.o文件。測試

其中編譯 core-m3這個文件時遇到報錯,查詢到是兩個函數中須要修改以下。具體緣由是由於對應的編譯器的彙編語句不一樣。ui

修改前 uint32_t __STREXB(uint8_t value, uint8_t *addr) { uint32_t result=0; __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); return(result); } uint32_t __STREXH(uint16_t value, uint16_t *addr) { uint32_t result=0; __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); return(result); } 修改後 uint32_t __STREXB(uint8_t value, uint8_t *addr) { uint32_t result=0; __ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); return(result); } uint32_t __STREXH(uint16_t value, uint16_t *addr) { uint32_t result=0; __ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); return(result); }

最後再來補充一個控制LED閃燈的驅動程序,使用過STM32單片機的必定不難理解底下的這段代碼。就是控制GPIOA_PIN8高低電平切換。spa

#include "stm32f10x.h"


int main(void) { int i,j; RCC->APB2ENR = 0x00000004; GPIOA->CRH = 0x00000003; while(1) { GPIOA->BSRR=(0x00000001<<8); for(j=0;j<720000;j++); GPIOA->BSRR=(0x00000001<<24); for(i=0;i<720000;i++); } return 0; }

最後得編譯上面的代碼,獲得main.c  對應的.o文件。以下.net

看着這些.o文件是否是挺面熟,在MDK工程的obj文件夾下有這一堆文件,而後後面須要用這些文件最終生成HEX文件。前回避了Makefile到這裏鏈接腳本是必須的了,不過好處是能夠暫時不用本身寫,直接用ST提供的腳本隨便一個同系列的芯片的連接腳本吧內存定義那一部分改爲對應芯片的FLASH和RAM大小就行。code

而後執行下面的命令  注意-T是指指定鏈接腳本就是STM32F103X6_FLASH.ld

arm-none-eabi-gcc system_stm32f10x.o startup_stm32f103xb.o  core_cm3.o  main.o -T STM32F103X6_FLASH.ld -o led.elf -mthumb -mcpu=cortex-m3 -W -Wall -lm -lc

這時我遇到了這樣一個問題

官方鏈接文件中有一段和現有的arm-none-eabi-gcc版本不兼容致使的 exit undefined的問題錯誤碼

gcc 連接出錯exit.c:(.text.exit+0x16): undefined reference to `_exit'這個連接給出瞭解決方法和緣由說明(https://blog.csdn.net/weixin_30224379/article/details/95334513)

 我選擇在連接腳本中增長_exit 符號提供給連接器,而後再次執行連接命令目錄下獲得led.elf文件,到這裏就算是大功告成了,接下來若是你只須要執行兩條簡單的命令就能夠獲得對應的能夠燒錄的文件

arm-none-eabi-objcopy  led.elf led.bin -Obinary 獲得bin文件 
arm-none-eabi-objcopy led.elf led.hex -Oihex 獲得hex文件 

最終我在Windows下使用串口燒錄軟件將,程序下載到板子上,燈歡快的閃起來了。因此這也算是個人第一個Linux下的ARM程序開發,後來我學着寫了一個Makefile測試了下能夠用,可是吃相難看放到最後,當作回憶。。。。。

 1 TOP    = $(shell pwd)
 2 COMPLIT     = arm-none-eabi  3 TARGET        := led  4 ASM            := $(COMPLIT)-as  5 CC           := $(COMPLIT)-gcc  6 LD           := $(COMPLIT)-ld  7 OBJCOPY     = $(COMPLIT)-objcopy  8 OBJDUMP     = $(COMPLIT)-objdump  9 OBJ          =  system_stm32f10x.o startup_stm32f103xb.o  core_cm3.o  main.o 10 SRC =         $(TOP)/src/
11 INC =         $(TOP)/inc/
12 FLAG         :=  -W -Wall -g -I $(INC)  -lm  -lc -mcpu=cortex-m3 -mthumb -D STM32F10X_HD -D USE_STDPERIPH_DRIVER -O1 -std=gnu11 13 
14 all: $(OBJ)
15     $(CC) $(OBJ) -T STM32F103X6_FLASH.ld -o $(TARGET).elf   -mthumb -mcpu=cortex-m3 -W -Wall -lm -lc 16     $(OBJCOPY) $(TARGET).elf  $(TARGET).bin -Obinary 17     $(OBJCOPY) $(TARGET).elf  $(TARGET).hex -Oihex 18 main.o: 19     $(CC) -o main.o   -c  $(FLAG) $(SRC)main.c 20 startup_stm32f103xb.o: startup_stm32f103xb.s   $(INC)system_stm32f10x.h 21     $(ASM) -o startup_stm32f103xb.o startup_stm32f103xb.s 22 system_stm32f10x.o: 23     $(CC) -o system_stm32f10x.o -c  $(FLAG)  $(SRC)system_stm32f10x.c 24 core_cm3.o: 25     $(CC) -o core_cm3.o -c $(FLAG)  $(SRC)core_cm3.c 26 
27 
28 clean: 29     rm *.o
makefile
相關文章
相關標籤/搜索