ubuntu linux下建立stm32开发环境: GCC安装以及工程Makefile建立

买了一个STM32开发板,却不想在window下开发,也不想用那么占内存的IAR MDK等软件,所以决定在ubuntu下建立该开发环境,像之前avr linux一样,找了下资料,国内有人做过,但都没有很详尽的教程,所以花了三四天才完成.其实原理很简单,就是安装适用与STM32的GCC,以及建立该工程,主要是Makefile加上STM32的官方库.

个人原创,转载请注明原文出处:

  http://blog.csdn.net/embbnux/article/details/17616809

参考:

How-to manual  Installing a toolchain for Cortex-M3/STM32 on Ubuntu   by Peter Seng

环境:

              ubuntu 13.10

stm32f103zet6

 一  STM 32 GCC 安装

stm32 属于arm cortex-m系列thumb指令集,所以给arm用的arm-none-eabi就可以了,首先是下载

下载地址:

https://launchpad.net/gcc-arm-embedded/+download

下载其中的gcc-arm-none-eabi-version-linux.tar.bz2

解压到你知道的目录会产生 gcc-arm-none-eabi的文件夹

把该编译器添加到你的环境中:


sudo gedit  ~/.bashrc

在最后一行添加:


export PATH=$PATH:/your_stm_gcc_dir/gcc-arm-none-eabi-4_8-2013q4/bin

因为我之前有添加过树莓派的编译器了,所以实际上是这样的:


export PATH=$PATH:/your_pi_gcc_dir/tools-master/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/:/your_stm_gcc_dir/gcc-arm-none-eabi-4_8-2013q4/bin

两个编译器环境中间用冒号隔开;

注销后测试:


arm-none-eabi-gcc -v

可以查看到该编译器的版本,就表示可以了.

二  工程环境的建立

新建个工程文件夹,及其目录


mkdir stm_project
cd stm_project
mkdir libs
mkdir src
mkdir inc

下载,安装官方库:

stm32的寄存器不像51 avr等单片机,那么少,自己写写库,背背寄存器就可以了,所以ST公司提供了他们官方的库,为了避免重复造轮子,就直接采用他们的库,库版本为STM32_USB-FS-Device_Lib_V4.0.0,这个库多了usb支持,下载的话到st官网搜索stm32f10x就有了.

下载链接:

 stsw-stm32121.zip 

解压,把解压好的文件夹复制到刚才新建的libs里面.

在工程根目录下新建Makefile.common文件,这个为通用makefile


# include Makefile

#This file is included in the general Makefile, the libs Makefile and the src Makefile
#Different optimize settings for library and source files can be realized by using arguments
#Compiler optimize settings:
# -O0 no optimize, reduce compilation time and make debugging produce the expected results (default).
# -O1 optimize, reduce code size and execution time, without much increase of compilation time.
# -O2 optimize, reduce code execution time compared to ‘O1’, increase of compilation time.
# -O3 optimize, turns on all optimizations, further increase of compilation time.
# -Os optimize for size, enables all ‘-O2’ optimizations that do not typically increase code size and other code size optimizations.
#Recommended optimize settings for release version: -O3
#Recommended optimize settings for debug version: -O0
#Valid parameters :
# OptLIB=0 --> optimize library files using the -O0 setting
# OptLIB=1 --> optimize library files using the -O1 setting
# OptLIB=2 --> optimize library files using the -O2 setting
# OptLIB=3 --> optimize library files using the -O3 setting
# OptLIB=s --> optimize library files using the -Os setting
# OptSRC=0 --> optimize source files using the -O0 setting
# OptSRC=1 --> optimize source files using the -O1 setting
# OptSRC=2 --> optimize source files using the -O2 setting
# OptSRC=3 --> optimize source files using the -O3 setting
# OptSRC=s --> optimize source files using the -Os setting
# all --> build all
# libs --> build libs only
# src --> build src only
# clean --> clean project
# tshow --> show optimize settings
#Example:
# make OptLIB=3 OptSRC=0 all tshow

TOP=$(shell readlink -f "$(dir $(lastword $(MAKEFILE_LIST)))")
PROGRAM=main
LIBDIR=$(TOP)/libs

#Adust the following line to the library in use
#=========add by embbnux 根据你的库不同,调整这个地方的库目录地址====================#
 STMLIB=$(LIBDIR)/STM32_USB-FS-Device_Lib_V4.0.0/Libraries
#=========add by embbnux 根据你的stm32芯片型号容量不同,修改这个地方的TypeOfMCU=======#
#Adjust TypeOfMCU in use, see CMSIS file "stm32f10x.h"#STM32F103RBT (128KB FLASH, 20KB RAM) --> STM32F10X_MD#TypeOfMCU=STM32F10X_MD#STM32F103RET (512KB FLASH, 64KB RAM) --> STM32F10X_HD#STM32F103ZET (512KB FLASH, 64KB RAM) --> STM32F10X_HD
#============================================================================#
TypeOfMCU=STM32F10X_HD
#============================================================================#
TC=arm-none-eabi
CC=$(TC)-gcc
LD=$(TC)-ld -v
OBJCOPY=$(TC)-objcopy
AR=$(TC)-ar
GDB=$(TC)-gdb
INCLUDE=-I$(TOP)/inc
INCLUDE+=-I$(STMLIB)/CMSIS/Include
INCLUDE+=-I$(STMLIB)/CMSIS/Device/ST/STM32F10x/Include
INCLUDE+=-I$(STMLIB)/CMSIS/Device/ST/STM32F10x/Source/Templates
INCLUDE+=-I$(STMLIB)/STM32F10x_StdPeriph_Driver/inc
INCLUDE+=-I$(STMLIB)/STM32_USB-FS-Device_Driver/inc
COMMONFLAGS=-g -mcpu=cortex-m3 -mthumb
COMMONFLAGSlib=$(COMMONFLAGS)
#Commands for general Makefile and src Makefile
ifeq ($(OptSRC),0)
  COMMONFLAGS+=-O0
  InfoTextSrc=src (no optimize, -O0)
else ifeq ($(OptSRC),1)
  COMMONFLAGS+=-O1
  InfoTextSrc=src (optimize time+ size+, -O1)
else ifeq ($(OptSRC),2)
  COMMONFLAGS+=-O2
  InfoTextSrc=src (optimize time++ size+, -O2)
else ifeq ($(OptSRC),s)
    COMMONFLAGS+=-Os
   InfoTextSrc=src (optimize size++, -Os)
else
  COMMONFLAGS+=-O3
  InfoTextSrc=src (full optimize, -O3)
endif
CFLAGS+=$(COMMONFLAGS) -Wall -Werror $(INCLUDE)
CFLAGS+=-D $(TypeOfMCU)
CFLAGS+=-D VECT_TAB_FLASH

#Commands for libs Makefile
ifeq ($(OptLIB),0)
  COMMONFLAGSlib+=-O0
  InfoTextLib=libs (no optimize, -O0)
else ifeq ($(OptLIB),1)
  COMMONFLAGSlib+=-O1
  InfoTextLib=libs (optimize time+ size+, -O1)
else ifeq ($(OptLIB),2)
  COMMONFLAGSlib+=-O2
  InfoTextLib=libs (optimize time++ size+, -O2)
else ifeq ($(OptLIB),s)
  COMMONFLAGSlib+=-Os
  InfoTextLib=libs (optimize size++, -Os)
else
  COMMONFLAGSlib+=-O3
  InfoTextLib=libs (full optimize, -O3)
endif
CFLAGSlib+=$(COMMONFLAGSlib) -Wall -Werror $(INCLUDE)
CFLAGSlib+=-D $(TypeOfMCU)
CFLAGSlib+=-D VECT_TAB_FLASH

编译库文件:

进入libs文件夹,新建Makefile:


# libs Makefile
include ../Makefile.common
LIBS+=libstm32.a
CFLAGSlib+=-c

all: libs

libs: $(LIBS)

libstm32.a:
 @echo -n "Building $@ ..."
 @cd $(STMLIB)/CMSIS/Device/ST/STM32F10x/Source/Templates && \
 $(CC) $(CFLAGSlib) \
 system_stm32f10x.c
 @cd $(STMLIB)/STM32F10x_StdPeriph_Driver/src && \
 $(CC) $(CFLAGSlib) \
 -D"assert_param(expr)=((void)0)" \
 -I../../CMSIS/Include \
 -I../../CMSIS/Device/ST/STM32F10x/Include \
 -I../inc \
 *.c
# @cd $(STMLIB)/STM32_USB-FS-Device_Driver/src && \
# $(CC) $(CFLAGSlib) \
# -D"assert_param(expr)=((void)0)" \
# -I../../CMSIS/Include \
# -I../../CMSIS/Device/ST/STM32F10x/Include \
# -I../inc \
# *.c
 @$(AR) cr $(LIBDIR)/$@ \
 $(STMLIB)/CMSIS/Device/ST/STM32F10x/Source/Templates/system_stm32f10x.o \
 $(STMLIB)/STM32F10x_StdPeriph_Driver/src/*.o \
# $(STMLIB)/STM32_USB-FS-Device_Driver/src/*.o
 @echo "done."
.PHONY: libs clean tshow

clean:
 rm -f $(STMLIB)/CMSIS/Device/ST/STM32F10x/Source/Templates/system_stm32f10x.o
 rm -f $(STMLIB)/STM32F10x_StdPeriph_Driver/src/*.o
 rm -f $(STMLIB)/STM32_USB-FS-Device_Driver/src/*.o
 rm -f $(LIBS)
tshow:
 @echo "######################################################################################################"
 @echo "################# optimize settings: $(InfoTextLib), $(InfoTextSrc)"
 @echo "######################################################################################################"

编译该库:


make clean
make

就会在lib目录下生成libstm32.a,这个就是编译好的静态库了.

  建立工程编译ld文件

这个ld文件,为在编译时告诉编译器把代码放到什么地址,根据芯片的内存以及flash容量不同有所调整

在工程根目录下新建linker.ld文件

代码较长,请到我的资源里面下载,或者查看参考pdf里面的:

 http://download.csdn.net/detail/canyue102/6778837

也可到git上下载整个工程: stm32_development_on_linux

这里说明需要修改的地方,根据芯片型号不同,选择相应的RAM FLASH大小


MEMORY {
 /*Adust LENGTH to RAMsize of target MCU:*/
 /*STM32F103RBT --> 20K*/
 /*RAM (RWX) : ORIGIN = 0x20000000 , LENGTH = 20K*/
 /*STM32F103RET --> 64K*/
 /*STM32F103ZET --> 64K*/
 RAM (RWX) : ORIGIN = 0x20000000 , LENGTH = 64K
 EXTSRAM (RWX) : ORIGIN = 0x68000000 , LENGTH = 0
 /*Adust LENGTH to (FLASHsize - FeePROMsize) of target MCU:*/
 /*STM32F103RBT --> 126K*/
 FLASH (RX) : ORIGIN = 0x08000000 , LENGTH = 126K
 /*STM32F103RET --> 508K*/
 /*FLASH (RX) : ORIGIN = 0x08000000 , LENGTH = 508K*/
 /*STM32F103ZET --> 508K*/
 FLASH (RX) : ORIGIN = 0x08000000 , LENGTH = 508K
 /*Adust ORIGIN to (0x08000000 + (FLASHsize-FeePROMsize)) of target MCU*/
 /*and adust LENGTH to FeePROMsize allocated:*/
 /*STM32F103RBT --> 0x08000000+126K, 2K*/
 EEMUL (RWX) : ORIGIN = 0x08000000+126K, LENGTH = 2K
 /*STM32F103RET --> 0x08000000+508K, 4K*/
 /*EEMUL (RWX) : ORIGIN = 0x08000000+508K, LENGTH = 4K*/
}

 在工程根目录下新建Makefile文件:


# general Makefile

include Makefile.common
LDFLAGS=$(COMMONFLAGS) -fno-exceptions -ffunction-sections -fdata-sections -L$(LIBDIR) -nostartfiles -Wl,--gc-sections,-Tlinker.ld

LDLIBS+=-lm
LDLIBS+=-lstm32

STARTUP=startup.c

all: libs src
 $(CC) -o $(PROGRAM).elf $(LDFLAGS) \
 -Wl,--whole-archive \
 src/app.a \
 -Wl,--no-whole-archive \
 $(LDLIBS)
 $(OBJCOPY) -O ihex $(PROGRAM).elf $(PROGRAM).hex
 $(OBJCOPY) -O binary $(PROGRAM).elf $(PROGRAM).bin
#Extract info contained in ELF to readable text-files:
 arm-none-eabi-readelf -a $(PROGRAM).elf > $(PROGRAM).info_elf
 arm-none-eabi-size -d -B -t $(PROGRAM).elf > $(PROGRAM).info_size
 arm-none-eabi-objdump -S $(PROGRAM).elf > $(PROGRAM).info_code
 arm-none-eabi-nm -t d -S --size-sort -s $(PROGRAM).elf > $(PROGRAM).info_symbol

.PHONY: libs src clean tshow

libs:
 $(MAKE) -C libs $@
src:
 $(MAKE) -C src $@
clean:
 $(MAKE) -C src $@
 $(MAKE) -C libs $@
 rm -f $(PROGRAM).elf $(PROGRAM).hex $(PROGRAM).bin $(PROGRAM).info_elf $(PROGRAM).info_size
 rm -f $(PROGRAM).info_code
 rm -f $(PROGRAM).info_symbol
tshow:
 @echo "######################################################################################################"
 @echo "################# optimize settings: $(InfoTextLib), $(InfoTextSrc)"
 @echo "######################################################################################################"

差不多就好了,在src里面添加测试源码

主要是startup.c 以及main.c,这里就不在说明了,可以查看该参考资料的pdf或者到我的资源下载

  http://download.csdn.net/detail/canyue102/6778885

src目录下新建文件Makefile:


# src Makefile

include ../Makefile.common

OBJS+=startup.o
OBJS+=main.o

all: src

src: app.a

app.a: $(OBJS)
$(AR) cr app.a $(OBJS)
.PHONY: src clean tshow

clean:
rm -f app.a $(OBJS)
tshow:
@echo "######################################################################################################"
@echo "################# optimize settings: $(InfoTextLib), $(InfoTextSrc)"
@echo "######################################################################################################"

然后进入工程主目录,下make就好了.


make clean
make OptLIB=0 OptSRC=0 all tshow

然后,就完成了,关于ubuntu下烧录程序到stm32下,请见下一篇博客

《ubuntu linux下建立stm32开发环境: GCC安装以及工程Makefile建立》上有42条评论

  1. 你好,make clean的是时候有错误啊,
    make -C src clean
    make[1]: Entering directory ‘/home/bitcraze/Desktop/stm32_project/src’
    make[1]: *** No rule to make target ‘clean’. Stop.
    make[1]: Leaving directory ‘/home/bitcraze/Desktop/stm32_project/src’
    Makefile:38: recipe for target ‘clean’ failed
    make: *** [clean] Error 2

  2. 您好,根据您的教程库编译成功了,只是到了最后一步总是提示进入src目录后没有匹配的规则但是libs目录是正常的,提示内容是这样的:
    命令:
    make clean
    提示:
    make[1]: 正在进入目录 `/home/san/stm_project/src’
    make[1]: *** 没有规则可以创建目标“clean”。 停止。
    make[1]:正在离开目录 `/home/san/stm_project/src’
    make: *** [clean] 错误 2

    命令:
    make
    提示:
    make -C libs libs
    make[1]: 正在进入目录 `/home/san/stm_project/libs’
    make[1]: 没有什么可以做的为 `libs’。
    make[1]:正在离开目录 `/home/san/stm_project/libs’
    make -C src src
    make[1]: 正在进入目录 `/home/san/stm_project/src’
    make[1]: *** 没有规则可以创建目标“src”。 停止。
    make[1]:正在离开目录 `/home/san/stm_project/src’
    make: *** [src] 错误 2

    这个应该是在Makefile.common里出的问题吧?但是lib看起来是正常的.

      1. source Makefile:
        # src Makefile
        include ../Makefile.common
        OBJS+=startup.o
        OBJS+=main.o
        all: src
        src: app.a
        app.a: $(OBJS)
        $(AR) cr app.a $(OBJS)
        .PHONY: src clean tshow
        clean:
        rm -f app.a $(OBJS)
        tshow:
        @echo “######################################################################################################”
        @echo “######## optimize settings: $(InfoTextLib), $(InfoTextSrc)”
        @echo “######################################################################################################”

        1. 麻烦把这个加上,还有就是我刚开始看教程的时候找不到您说的pdf是什么,参考资料也没有标注是pdf,麻烦明显标注一下,谢谢.

  3. 你好,因为没有csdn的积分,不能下载stm32在ubuntu linux下开发测试源文件和linker.ld,能不能通过邮箱发给我,谢谢

  4. 请问,STM32_USB-FS-Device_Lib_V4.0.0这个库对stm32F407系列支持吗,或者哪里可以下到407的库?多谢

  5. 你好,我下了你在github的stm32_development_on_linux,解压后进入stm32_development_on_linux-master目录,直接make,但编译出错:
    make -C libs libs
    make[1]: Entering directory ‘/home/me/stm32_development_on_linux-master/libs’
    Building libstm32.a …arm-none-eabi-gcc: error trying to exec ‘cc1’: execvp: No such file or directory
    Makefile:11: recipe for target ‘libstm32.a’ failed
    make[1]: *** [libstm32.a] Error 1
    make[1]: Leaving directory ‘/home/me/stm32_development_on_linux-master/libs’
    Makefile:28: recipe for target ‘libs’ failed
    make: *** [libs] Error 2
    请问下这是什么错误,谢谢

  6. 您好,根据您的教材,编译libstm32.a时出现了如下错误

    Building libstm32.a …In file included from /home/lolo/Code/stm32/stm_prj_template/libs/CMSIS/Include/core_cm3.h:120:0,
    from /home/lolo/Code/stm32/stm_prj_template/libs/CMSIS/Device/ST/STM32F10x/Include/stm32f10x.h:488,
    from system_stm32f10x.c:71:
    /usr/lib/gcc/arm-none-eabi/4.9.2/include/stdint.h:9:26: fatal error: stdint.h: No such file or directory
    # include_next
    ^
    compilation terminated.
    Makefile:12: recipe for target ‘libstm32.a’ failed
    make: *** [libstm32.a] Error 1

    stdint.h里的内容是这样的

    #ifndef _GCC_WRAP_STDINT_H
    #if __STDC_HOSTED__
    # if defined __cplusplus && __cplusplus >= 201103L
    # undef __STDC_LIMIT_MACROS
    # define __STDC_LIMIT_MACROS
    # undef __STDC_CONSTANT_MACROS
    # define __STDC_CONSTANT_MACROS
    # endif
    # include_next
    #else
    # include “stdint-gcc.h”
    #endif
    #define _GCC_WRAP_STDINT_H
    #endif

    该如何解决?

  7. 博主,这样编译出的bin文件很大呀,我的在mdk下编译的是4.7K,这里编译的是55K。怎么搞呀

  8. make报错,貌似那个路径是根目录下的,多了个‘/’
    ……
    usage: readlink [-n] [file …]
    readlink: illegal option — f
    usage: readlink [-n] [file …]
    -n Building libstm32.a …
    /bin/sh: line 0: cd: /libs/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/CMSIS/Device/ST/STM32F10x/Source/Templates: No such file or directory
    make: *** [libstm32.a] Error 1

    1. 建议看一下你的芯片手册里面写的RAM的具体大小是多少,如果linker.ld里面配置的RAM空间超过了真实大小的话,肯定是跑步起来的。

      原版的那个linker.ld程序一跑起来就挂,不知道什么原因,我看了下写法应该是是没错的。我吧他的数据段的链接脚本改了一下,现在可以正常在stm32f103c8上面跑起来了。

      .data : ALIGN (8) {
      _sdata = . ; /* exported for the startup function */
      . = ALIGN(4);
      KEEP(*(.jcr))
      *(.got.plt) *(.got)
      *(.shdata)
      *(.data .data.*)
      . = ALIGN (8);
      *(.ram)
      *(.ramfunc*)
      . = ALIGN(4);
      _edata = . ; /* exported for the startup function */
      } >RAM

  9. hulai@ubuntu:~/Desktop/stm32_project/libs$ make clean
    rm -f /home/hulai/Desktop/stm32_project/libs/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/CMSIS/Device/ST/STM32F10x/Source/Templates/system_stm32f10x.o
    rm -f /home/hulai/Desktop/stm32_project/libs/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F10x_StdPeriph_Driver/src/*.o
    rm -f /home/hulai/Desktop/stm32_project/libs/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32_USB-FS-Device_Driver/src/*.o
    rm -f libstm32.a
    hulai@ubuntu:~/Desktop/stm32_project/libs$ make
    Building libstm32.a …/bin/sh: 1: : not found
    make: *** [libstm32.a] Error 127

      1. Building libstm32.a …/bin/sh: 1: : not found
        make: *** [libstm32.a] Error 127
        请问和环境具体有什么样的关系呢?

  10. 博主您好,我在研究Makefile文件的时候,一直没有找到您对启动文件的支持。可能是我没找到,能帮我指一下位置么?

    1. 不好意思打扰您了,刚刚去github里找到了,是在src里,但还有一个疑问,这份代码适合所有版本么?

  11. 请问“把该编译器添加到你的环境中”这句话是什么意思?所谓的环境指的是什么?

  12. 你好,我按照您的步骤配置了,其他都好了,就是我用的芯片和您的不一样,然后写入的时候stlink有反应但板子没反应,您说要改RAM,flash等等,但我不知道怎么改,因为那个Flash(RX)连着设置了两次,我不知道到底填什么,它的RAM是256kb,SRAM是48kb,应该怎么设置呢?可以的话麻烦您稍微详细讲一下,我是新手,麻烦您了。

  13. 您好,看了你的文章感觉很好.我也在弄但是会遇到各种各样的问题,可以加一下好友吗?

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

Time limit is exhausted. Please reload the CAPTCHA.

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据