1.1 安装GCC
1、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的文件夹
2、设置环境变量
把该编译器添加到你的环境中:
# sudo gedit ~/.bashrc 最后一行添加
export PATH=$PATH:/your_stm_gcc_dir/gcc-arm-none-eabi-4_8-2013q4/bin
3、测试
# arm-none-eabi-gcc -v
1.2 建立工程
1、下载官方的库
2、将文件分类放在文件下,然后写makefile进行编译
1.3 Makefile解析
makefile是所有的重点,由于我对makefile并不是很熟料,我在这里参考过很多github相关的makefile,在这里整理出一份我比较喜欢,简洁明了、通用性移植性强的:
注意使用官方库的时候,选择的启动文件不一样,keil的是arm编译,我们使用的gcc编译。
1.4 gcc参数解析
编译过程:预处理-编译-汇编-链接
注:当静态库和动态库同名时, gcc命令将优先使用动态库。
注:链接库的参数不能放到-o参数后面,否则可能会报错。
下载列部分常用的gcc参数,makefile看不太懂的可以参考下面的参数列表
选项 | 含义 |
--help | 显示 gcc 帮助说明。‘target-help’是显示目标机器特定的命令行选项。 |
--version | 显示 gcc 版本号和版权信息 。 |
-o outfile | 输出到指定的文件。 |
-xlanguage | 指明使用的编程语言。允许的语言包括:c c++ assembler none 。 ‘none’意味着恢复默认行为,即根据文件的扩展名猜测源文件的语言。 |
-v | 打印较多信息,显示编译器调用的程序。 |
-### | 与 -v 类似,但选项被引号括住,并且不执行命令。 |
-E | 仅作预处理,不进行编译、汇编和链接。如上图所示。 |
-S | 仅编译到汇编语言,不进行汇编和链接。如上图所示。 |
-c | 编译、汇编到目标代码,不进行链接。 |
-pipe | 使用管道代替临时文件。 |
-combine | 将多个源文件一次性传递给汇编器。 |
-l library(小写L) | 进行链接时搜索名为library的库。 |
-Idir(大写i) | 把dir加入到搜索头文件的路径列表中。 |
-Ldir | 把dir加入到搜索库文件的路径列表中。 |
-Dname | 预定义一个名为name的宏,值为1。 |
-Dname=definition | 预定义名为name,值为definition的宏。 |
-ggdb | 为调试器 gdb 生成调试信息。level可以为1,2,3,默认值为2。 |
-g | 生成操作系统本地格式的调试信息。-g 和 -ggdb 并不太相同, -g 会生成 gdb 之外的信息。level取值同上。 |
-s | 去除可执行文件中的符号表和重定位信息。用于减小可执行文件的大小。 |
-M | 告诉预处理器输出一个适合make的规则,用于描述各目标文件的依赖关系。对于每个源文件,预处理器输出 一个make规则,该规则的目标项(target)是源文件对应的目标文件名,依赖项(dependency)是源文件中 `#include引用的所有文件。生成的规则可以是单行,但如果太长,就用`/'-换行符续成多行。规则 显示在标准输出,不产生预处理过的C程序。 |
-C | 告诉预处理器不要丢弃注释。配合`-E'选项使用。 |
-P | 告诉预处理器不要产生`#line'命令。配合`-E'选项使用。 |
-static | 在支持动态链接的系统上,阻止连接共享库。该选项在其它系统上无效。 |
-nostdlib | 不连接系统标准启动文件和标准库文件,只把指定的文件传递给连接器。 |
Warnings |
|
-Wall | 会打开一些很有用的警告选项,建议编译时加此选项。 |
-W | 打印一些额外的警告信息。 |
-w | 禁止显示所有警告信息。 |
-Wshadow | 当一个局部变量遮盖住了另一个局部变量,或者全局变量时,给出警告。很有用的选项,建议打开。 -Wall 并不会打开此项。 |
-Wpointer-arith | 对函数指针或者void *类型的指针进行算术操作时给出警告。也很有用。 -Wall 并不会打开此项。 |
-Wcast-qual | 当强制转化丢掉了类型修饰符时给出警告。 -Wall 并不会打开此项。 |
-Waggregate-return | 如果定义或调用了返回结构体或联合体的函数,编译器就发出警告。 |
-Winline | 无论是声明为 inline 或者是指定了-finline-functions 选项,如果某函数不能内联,编译器都将发出警告。如果你的代码含有很多 inline 函数的话,这是很有用的选项。 |
-Werror | 把警告当作错误。出现任何警告就放弃编译。 |
-Wunreachable-code | 如果编译器探测到永远不会执行到的代码,就给出警告。也是比较有用的选项。 |
-Wcast-align | 一旦某个指针类型强制转换导致目标所需的地址对齐增加时,编译器就发出警告。 |
-Wundef | 当一个没有定义的符号出现在 #if 中时,给出警告。 |
-Wredundant-decls | 如果在同一个可见域内某定义多次声明,编译器就发出警告,即使这些重复声明有效并且毫无差别。 |
Optimization |
|
-O0 | 禁止编译器进行优化。默认为此项。 |
-O | 尝试优化编译时间和可执行文件大小。 |
-O2 | 更多的优化,会尝试几乎全部的优化功能,但不会进行“空间换时间”的优化方法。 |
-O3 | 在 -O2 的基础上再打开一些优化选项:-finline-functions, -funswitch-loops 和 -fgcse-after-reload 。 |
-Os | 对生成文件大小进行优化。它会打开 -O2 开的全部选项,除了会那些增加文件大小的。 |
-finline-functions | 把所有简单的函数内联进调用者。编译器会探索式地决定哪些函数足够简单,值得做这种内联。 |
-fstrict-aliasing | 施加最强的别名规则(aliasing rules)。 |
ARM |
|
-mthumb | 指令集 |
-mcpu=cortex-m3 |
|
-T | 指定链接文件 |
1.5 ld链接文件解析
主要设置系统flash/arm的起始地址和大小,还有堆栈的结束地址
这个也是跟keil有所不一样的,keil使用的是链接文件和启动文件时一起的,但是在makefile使用gcc编译时,启动文件时是定义向量并初始化,并没有定义堆栈的大小和地址等,而是在链接文件中定义,这里主要声明了堆栈的地址、flash和ram的大小,其他的相对并不太需要修改。
1.6 串口下载程序
1、stm32flash
https://sourceforge.net/p/stm32flash/wiki/Home/
https://github.com/ARMinARM/stm32flash
下载之后make编译,插上串口,设置一下usb的权限为666,即可使用串口下载程序。
下载是github的简单使用说明:
好了,eclipse的安装比较单一,在这里就不详述了,到此搞定。但是发现有一些问题:
1、gcc编译出来的目标文件在同等优化等级的情况下会大%30左右,这个很让然头痛。
2、在使用优化的时候发现以前在keil下写的一些代码出现了bug,特别是关于Volatile的疏忽,才发现keil是会自动完善这些代码bug,这里是小弟写的代码风格不严谨,惭愧惭愧。
3、flash下载的速度实在跟stlink等工具没法比,下载得据需搞搞stlink的下载才行。