专栏首页独行猫a的沉淀积累总结用GCC开发STM32,正点原子开发板的一个库函数版本例程示例

用GCC开发STM32,正点原子开发板的一个库函数版本例程示例

GCC环境搭建.

首先下载交叉编译环境GCC,这个网上有很多,百度一下就能找到下载。比如 Sourcery G++ for ARM EABI

我的CSDN资源里,有相关下载。

熟悉下Makefile

强力推荐熟悉网络牛人李云的51cto博客,有一篇驾驭Makefile的文章,另外一份参考资料也尤为重要《GNUmake中文手册-v3.80.pdf》,这都是先辈们开凿好的前路,对于后辈的我们只要沿路走就可以了。

熟悉Makefile主要还是实践,按照李云博客介绍的方法,多使用echo,或者使用make的调试命令make –D > 1.txt,这样可以熟悉其中的依赖关系和建立顺序。说的直白点就是建立对应依赖关系。

在熟悉的时候,可以一边对照实际工程编写对应的Makefile。

以下是简要学习Makefile的笔记:

1. %.a: 匹配所有以.a结尾的所有文件名

   |--> 类似于通常意义的*.

2. $(addprefixsrc/,foo bar) -->

   返回值为"src/foosrc/bar"。

3. vpath %.h../headers

   Makefile中出现的.h文件:如果不能再当前目录中找到,则到目录"../headers"下寻找.

vpath与VPATH的区别在于后者指定全局的搜索路径

4. $(MAKE) -C$(STD_PERIPH_LIB)

   make的递归执行-->4.6GNUmake中文手册-v3.8

   当前目录下存在外设库文件,在编译的时候先对子目录进行编译.

   它等价于命令

   lib:

         cd $(STD_PERIPH_LIB) && $(MAKE)

5. $@:代表规则中的目标文件名:可以使用@-->at 代表目标的意思

   $%:规则的目标文件是一个静态库文件时,代表静态库的一个成员名.

   $<:规则的第一个依赖文件名.

   $^:规则的所有依赖文件列表.

   $(*D): 代表"茎"中的目录部分

   $(*F): 代表"茎"中的文件名部分

6. find ./ -name'*~' | xargs rm -f

   当你尝试用rm 删除太多的文件,你可能得到一个错误信息:

   /bin/rm Argument list too long. 用xargs 去避免这个问题

7. 将make调试信息保存到txt文档

   make -d > 1.txt

8. main.c 中#include"defs.h"

   命令 gcc -M main.c

   out: main.o:main.c defs.h

   若不需要依赖关系中不考虑标准头文件时

   使用gcc -MM main.c

9.  := 与 += 区别

   := --> 立即展开

   += --> 立即展开或延迟展开

   对于所有条件语句均采用立即展开

10. 将make输出的错误信息输出到文件1.txt

   make 2>1.txt

11. 从Shell获得当前文件夹位置

   ROOT=$(shell pwd)

12. 包含依赖文件时,不要放在所有目标的前面,如下所示

其中原因就是make依然会将dep文件作为目标,从而后面的目标无法得到运行。

四、熟悉gcc编译

Gcc编译学习是一个长期的过程,主要参考文档见安装目录下的Documation中的所有pdf和readme.txt。下面是简短的学习笔记。

1.      参数解释:

-g(level): 在本地操作系统产生指定格式的调试消息(stabs,COFF,XCOFF,DWARF 2)

-ggdb(level): 产生gdb格式的调试信息

-gstabs(level):产生stabs格式的调试信息,不包括GDB扩展.-->BSD.

  (level)-->默认级别为2

  0:不产生调试信息

  1:产生最少的调试信息

  3:包括额外的信息,包括在程序中出现的宏定义等.

  -gstabs+,-gcoff,-gxcoff,-gxcoff+,-gdwarf-version,-gvms

-c

   只激活预处理,编译和汇编,生成obj文件.还需要通过ld链接器对所有

   .o文件进行链接才能生成执行文件.

   -S

   只激活预处理和编译把文件汇编到汇编代码,相当于将程序生成.s文件.

   -E

   只进行预处理

   -o

   定制目标名称,缺省情况下生成a.out文件. gcc -ohello.exe test.c

   -D(macro)

   相当于#define  macro    1比如DDEBUG相当于将DEBUG的宏定义为1

   -C

   在预处理的时候不删除注释信息.

   -M

   生成文件的关联信息,就可以知道源代码依赖了那些头文件.

   -MM

   同上,忽略#include造成的依赖关系

   -MD

   和-M相当,但是输出导入到.d文件中. gcc -MDtest.c 输出依赖关系

   放在test.d文件里

   -MF file

   生成指定的默认依赖文件.

   -MMD

   和-MM相当,忽略#include造成的依赖关系

   -l(library)

   用于指定编译的时候使用的库. gcc-lgtk test.c 则程序使用gtk库进

   行编译.不过需要注意的是gcc库一般以lib(name).a来命名库文件,使用

   -l参数导入库文件的时候,直接使用-lname来引入,lib被省略.

   -L(dir)

   指定库文件所在的文件夹

   -T script

   指定空间分配文件

下面是编译 正点原子 stm32f103开发板的一个库函数版本的流水灯的例程的makefile,需要注意几点得是:

要把startup_stm32f10x_hd.s替换为gcc_ride7里面的startup_stm32f10x_hd.s,keil里面的汇编文件不能用于gcc

链接脚本文件也特别重要。要找能用于gcc下面的链接脚本根据需要修改。CSDN资源里有完整的编译通过的例子。把libc.a和libgcc.a拷贝出来放到工程的Lib文件夹里

#**************************************************************************** # Cross complie path #**************************************************************************** PRJ := ${PWD} GCC_PATH=c:\tools\arm2013.05 CROSS_COMPILE=$(GCC_PATH)\bin\arm-none-eabi- CC     := $(CROSS_COMPILE)gcc CXX    := $(CROSS_COMPILE)g++ AS   := $(CROSS_COMPILE)as AR     := $(CROSS_COMPILE)ar rc LD     := $(CROSS_COMPILE)ld RANLIB := $(CROSS_COMPILE)ranlib OBJDUMP:= $(CROSS_COMPILE)objdump OBJCOPY:= $(CROSS_COMPILE)objcopy STRIP  := $(CROSS_COMPILE)strip BINARY = main CFLAGS= -O0  -g -mcpu=cortex-m3 -mthumb -nostartfiles  -D STM32F10X_HD -D USE_STDPERIPH_DRIVER  ASFLAG= -g -mcpu=cortex-m3 -mthumb  LDSCRIPT = stm32f103VET6.ld LDFLAGS =   -Llib -T $(LDSCRIPT)  #**************************************************************************** # Targets of the build #**************************************************************************** TARGET   := .\Output\A303_GJXF all: prebuild $(TARGET).elf SRC_C=$(shell gfind . -name "*.c") SRC_S=$(shell gfind . -name "*.s") OBJ_C=$(patsubst %.c, %.o, $(SRC_C)) OBJ_S=$(patsubst %.s, %.o, $(SRC_S)) OBJS := $(OBJ_C) $(OBJ_S) #**************************************************************************** # Libs #**************************************************************************** LIB_C         := $(GCC_PATH)\arm-none-eabi\lib\libc.a LIB_GCC       := $(GCC_PATH)\lib\gcc\arm-none-eabi\4.7.3\libgcc.a LIBS = $(LIB_C) $(LIB_GCC) INCS = -I HARDWARE\LED -I SYSTEM\delay -I SYSTEM\sys -I SYSTEM\usart -I USER -I STM32F10x_FWLib\inc -I CORE   # OBJS = stm32f10x_gpio.o stm32f10x_rcc.o isr.o # OBJS += $(BINARY).o  # OBJS += core_cm3.o # OBJS += system_stm32f10x.o #**************************************************************************** # TARGET #**************************************************************************** prebuild: @echo Building app... $(TARGET).elf : $(OBJS) $(LIBS) @echo (LD) $@: $^ -${LD}  -o $@ $^ ${LDFLAGS}  @echo Generating bin... @$(OBJCOPY) -O binary $(TARGET).elf $(TARGET).bin @echo Generating hex... @$(OBJCOPY) -O ihex $@ $(TARGET).hex @echo Generating asm... @$(OBJDUMP) -D -S $@ > $(TARGET).asm @echo OK! %.o : %.c ${CC} -c ${CFLAGS} ${INCS} -o $@ $< %.o : %.s $(AS) $(ASFLAG) -o $@ $< clean: @echo The following files: rm  -f  $(TARGET) *.o gfind . -name "*.[od]" |xargs rm @echo Removed!

#====================end

/* Default linker script for STM32F10x_1024K_1024K Copyright RAISONANCE S.A.S. 2008 */ /* include the common STM32F10x sub-script */ /* Common part of the linker scripts for STM32 devices*/ /* default stack sizes.  These are used by the startup in order to allocate stacks for the different modes. */ __Stack_Size = 512 ; PROVIDE ( _Stack_Size = __Stack_Size ) ; __Stack_Init = _estack  - __Stack_Size ; /*"PROVIDE" allows to easily override these values from an object file or the commmand line.*/ PROVIDE ( _Stack_Init = __Stack_Init ) ; /* There will be a link error if there is not this amount of RAM free at the end. */ _Minimum_Stack_Size = 0x100 ; /* include the memory spaces definitions sub-script */ /* Linker subscript for STM32F10x definitions with 1024K Flash and 1024K External SRAM */ /* Memory Spaces Definitions */ MEMORY {   RAM (xrw) : ORIGIN = 0x60000000, LENGTH = 512K   FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K   FLASHB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0   EXTMEMB0 (rx) : ORIGIN = 0x00000000, LENGTH = 0   EXTMEMB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0   EXTMEMB2 (rx) : ORIGIN = 0x00000000, LENGTH = 0   EXTMEMB3 (rx) : ORIGIN = 0x00000000, LENGTH = 0 } /* higher address of the user mode stack */ _estack = 0x60080000; /* include the sections management sub-script for FLASH mode */ /* Sections Definitions */ SECTIONS {     /* for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, which goes to FLASH */     .isr_vector :     {         . = ALIGN(4);         KEEP(*(.isr_vector))            /* Startup code */         . = ALIGN(4);     } >FLASH     /* for some STRx devices, the beginning of the startup code is stored in the .flashtext section, which goes to FLASH */     .flashtext :     {         . = ALIGN(4);         *(.flashtext)            /* Startup code */         . = ALIGN(4);     } >FLASH     /* the program code is stored in the .text section, which goes to Flash */     .text :     {         . = ALIGN(4);         *(.text)                   /* remaining code */         *(.text.*)                   /* remaining code */         *(.rodata)                 /* read-only data (constants) */         *(.rodata*)         *(.glue_7)         *(.glue_7t)         . = ALIGN(4);          _etext = .;         /* This is used by the startup in order to initialize the .data secion */         _sidata = _etext;     } >FLASH     /* This is the initialized data section     The program executes knowing that the data is in the RAM     but the loader puts the initial values in the FLASH (inidata).     It is one task of the startup to copy the initial values from FLASH to RAM. */     .data  : AT ( _sidata )     {         . = ALIGN(4);         /* This is used by the startup in order to initialize the .data secion */         _sdata = . ;         *(.data)         *(.data.*)         . = ALIGN(4);         /* This is used by the startup in order to initialize the .data secion */         _edata = . ;     } >RAM     /* This is the uninitialized data section */     .bss :     {         . = ALIGN(4);         /* This is used by the startup in order to initialize the .bss secion */         _sbss = .;         *(.bss)         *(COMMON)         . = ALIGN(4);         /* This is used by the startup in order to initialize the .bss secion */         _ebss = . ;     } >RAM     PROVIDE ( end = _ebss );     PROVIDE ( _end = _ebss );     /* This is the user stack section      This is just to check that there is enough RAM left for the User mode stack     It should generate an error if it's full.      */     ._usrstack :     {         . = ALIGN(4);         _susrstack = . ;         . = . + _Minimum_Stack_Size ;         . = ALIGN(4);         _eusrstack = . ;     } >RAM     /* this is the FLASH Bank1 */     /* the C or assembly source must explicitly place the code or data there     using the "section" attribute */     .b1text :     {         *(.b1text)                   /* remaining code */         *(.b1rodata)                 /* read-only data (constants) */         *(.b1rodata*)     } >FLASHB1     /* this is the EXTMEM */     /* the C or assembly source must explicitly place the code or data there     using the "section" attribute */     /* EXTMEM Bank0 */     .eb0text :     {         *(.eb0text)                   /* remaining code */         *(.eb0rodata)                 /* read-only data (constants) */         *(.eb0rodata*)     } >EXTMEMB0     /* EXTMEM Bank1 */     .eb1text :     {         *(.eb1text)                   /* remaining code */         *(.eb1rodata)                 /* read-only data (constants) */         *(.eb1rodata*)     } >EXTMEMB1     /* EXTMEM Bank2 */     .eb2text :     {         *(.eb2text)                   /* remaining code */         *(.eb2rodata)                 /* read-only data (constants) */         *(.eb2rodata*)     } >EXTMEMB2     /* EXTMEM Bank0 */     .eb3text :     {         *(.eb3text)                   /* remaining code */         *(.eb3rodata)                 /* read-only data (constants) */         *(.eb3rodata*)     } >EXTMEMB3     /* after that it's only debugging information. */     /* remove the debugging information from the standard libraries */     DISCARD :     {      libc.a ( * )      libm.a ( * )      libgcc.a ( * )      }     /* Stabs debugging sections.  */     .stab          0 : { *(.stab) }     .stabstr       0 : { *(.stabstr) }     .stab.excl     0 : { *(.stab.excl) }     .stab.exclstr  0 : { *(.stab.exclstr) }     .stab.index    0 : { *(.stab.index) }     .stab.indexstr 0 : { *(.stab.indexstr) }     .comment       0 : { *(.comment) }     /* DWARF debug sections.        Symbols in the DWARF debugging sections are relative to the beginning        of the section so we begin them at 0.  */     /* DWARF 1 */     .debug          0 : { *(.debug) }     .line           0 : { *(.line) }     /* GNU DWARF 1 extensions */     .debug_srcinfo  0 : { *(.debug_srcinfo) }     .debug_sfnames  0 : { *(.debug_sfnames) }     /* DWARF 1.1 and DWARF 2 */     .debug_aranges  0 : { *(.debug_aranges) }     .debug_pubnames 0 : { *(.debug_pubnames) }     /* DWARF 2 */     .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }     .debug_abbrev   0 : { *(.debug_abbrev) }     .debug_line     0 : { *(.debug_line) }     .debug_frame    0 : { *(.debug_frame) }     .debug_str      0 : { *(.debug_str) }     .debug_loc      0 : { *(.debug_loc) }     .debug_macinfo  0 : { *(.debug_macinfo) }     /* SGI/MIPS DWARF 2 extensions */     .debug_weaknames 0 : { *(.debug_weaknames) }     .debug_funcnames 0 : { *(.debug_funcnames) }     .debug_typenames 0 : { *(.debug_typenames) }     .debug_varnames  0 : { *(.debug_varnames) } }

参考文档:GCC参数详解

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 让终端支持播放mp3,移植mp3解码库libmad和madplay到嵌入式linux

    MAD (libmad)是一个开源的高精度 MPEG 音频解码库,支持 MPEG-1(Layer I, Layer II 和 LayerIII(也就是 MP3)...

    特立独行的猫a
  • 若一开始代码架构不清晰,就是前人挖坑,后面所有人掉坑里

    原文链接: https://developer.android.google.cn/jetpack/docs/guide

    特立独行的猫a
  • log4go源码分析(一)

    一直想研究分享几个开源项目提高提高,但由于工作忙一直没时间。今天把业余时间总结的log4go源码分析的第一篇记录下来。

    特立独行的猫a
  • linux kernel Documentation filesystems overlayfs

    Please see MAINTAINERS file for where to send questions.

    heidsoft
  • 【PAT甲级】World Cup Betting

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    喜欢ctrl的cxk
  • POJ-1644 To Bet or Not To Bet(概率DP)

    To Bet or Not To Bet Time Limit: 1000MS Memory Limit: 10000K Total Subm...

    ShenduCC
  • PAT 1011 World Cup Betting (20分) 比较大小难度级别

    With the 2010 FIFA World Cup running, football fans the world over were becoming...

    vivi
  • Codeforces Round #434 (Div. 2, based on Technocup 2018 Elimination Round 1)&&Codeforces 861B Which

    B. Which floor? time limit per test:1 second memory limit per test:256 megabytes...

    Angel_Kitty
  • 相机标定--A Flexible New Technique for Camera Calibration

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.n...

    用户1148525
  • CopyLocal 之痛

    今天,我机子上好好的一个vs 2008的项目,拷到同事的机子上后,竟然不能运行,报“未能加载程序集”的错误。一看才知道,所有的程序集引用(除了Syst...

    明年我18

扫码关注云+社区

领取腾讯云代金券