0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux下开发STM32 使用gcc-arm-none-eabi工具链编译生成bin、hex文件

黄工的嵌入式技术圈 来源:黄工的嵌入式技术圈 作者:黄工的嵌入式技术 2020-02-28 15:08 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

1.为什么不是gcc

在开发stm32的时候,编译工具链要使用gcc-arm-none-eabi,为什么不是gcc呢?这就要说到linux下的交叉编译了,因为我们要在PC机上编译出可以运行在ARM上的程序,使用gcc编译出的是在PC上运行的程序,所以我们要使用gcc-arm-none-eabi进行交叉编译~

2.gcc-arm-none-eabi toolchain 介绍及安装

gcc-arm-none-eabi是一个开源的ARM开发工具链,适用于Arm Cortex-M和Coretex-A系列处理器,包括GNU编译器(GCC),以及GDB,可用于Windows,Linux,MacOS上的交叉编译。
gcc-arm-none-eabi在ubuntu软件源仓库中就有,但是版本比较陈旧:

在此我们从[ARM官方下载链接](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads)选择合适的版本下载(这里我选择Linux64):

解压下来是tar.ba2格式包,使用命令tar -jxf <要解压的文件>解压到我们要安装的目录:

为了以后使用方便,将文件夹重命名:

它下面的bin目录就是我们要使用的编译工具链:

share目录的doc下包含了大量的使用帮助文档,可以先略读一二,特别是readme.txt:

接下来我们要将bin目录添加到环境变量,这样可以直接在命令行输入要使用的工具名,然后系统就可以找到该工具,在此我们仅为当前用户添加环境变量,使用vim ~/.bashrc编辑当前用户配置文件,在最后添加export PATH=$PATH:/home/mculover666/gcc-arm-none-eabi/bin:

然后使用命令source ~/.bashrc更新系统路径,使添加的环境变量立即生效:

然后输入命令arm-none,然后按三下Tab(一定不要输入全部),检查系统是否可以自动补全:

如果系统可以提示,说明环境变量配置成功,可以开心的使用arm-none-eabi工具链啦~

3.从裸机工程开始

3.1.硬件说明

这里我使用的是野火霸道开发板,板载芯片为STM32F103ZET6,下载器使用e-link,这个下载器使用CMSIS-DAP下载程序,同时并带有一个串口,非常好用~

板载RGB-LED的原理图如图所示:

3.2.新建空的裸机工程

首先新建一个文件夹mkdir 00-template-reg用来存放整个工程,然后整个工程包含三个文件:

startup_stm32f10x_hd.s:从固件库中拷贝,注意不是arm文件夹下的,因为truestudio使用的是gcc编译器,所以我们选择truestudio文件夹下的启动文件;

stm32f10x.h:空文件;

main.c:代码如下:

#include"stm32f10x.h" intmain() { /*开启GPIOB时钟*/ *(unsignedint*)(0x40021000+0x18)|=1<<3;     /* 配置PB0为推挽输出 */     *(unsigned int*)(0x40010c00+0x00) |= 1<<(4*0);     /* PB0输出低电平,点亮绿色LED */     *(unsigned int*)(0x40010c00+0x0c) &= ~(1<<0);     while(1); } void SystemInit(void) { }

4.编译

接下来就是激动人心的编译步骤了~编译的时候有两种文件,一种是汇编启动文件,一种是c源文件,接下来分别编译:
首先需要说明一些编译任何一个文件都需要带上的参数:

参数 说明
-mthumb 表明使用的指令集(必需)
-mcpu=cortex-m3 表明芯片内核(必需)
-g 产生调试信息

4.1.启动文件编译

启动文件一般是由汇编写成,此处需要注意的是,汇编文件的格式有.S和.s之分:

大写S:表明文件中含有预处理指令(比如#define),需要先进行处理;

小写s:表明文件不需要处理,可以直接编译;

之前我们添加的启动文件是小写.s,所以直接进行编译,另外说一下,如果使用的是.S文件,那么需要带上-x assembler-with-cpp参数。

接下来说明一些汇编文件gcc编译器使用的参数:

参数 说明
-x assembler-with-cpp 先对文件进行预处理
-Wa,option 向汇编器Assembler传递参数

注:可以向汇编器传递的参数:

参数 说明
-W或--no-warn 关闭所有告警
--fatal-warnings 将所有的警告提示为错误
--warn 正常提示告警信息

所以,接下来我们可以使用如下的参数组合来编译启动文件(不进行预处理,并且正常提示告警信息):

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

4.2.C文件编译

因为main.c中没有特殊的东西,只是两个函数,所以简单的编译一下就可以了:

参数 描述
-Wall 允许输出所有警告

arm-none-eabi-gcc-c-mthumb-mcpu=cortex-m3-g-Wall-omain.omain.c

5.链接

链接重要的部分有两点:链接文件和传递给链接器的参数。
链接文件在固件库中给的示例工程中有,在下面这个目录:


其中stm32_flash.ld是针对于STM32F103ZE的链接文件,如果是别的芯片,需要进行修改,将它复制到我们的工程中去:


然后就要让链接器开始根据stm32_flash.ld这个文件对startup_stm32f10x_hd.o和main.o这两个文件开始链接,生成包含了调试信息的elf文件,同时,我们还需要给链接器传递一些参数:

参数 描述
-T 指定链接文件

arm-none-eabi-gcc-otest.elfmain.ostartup_stm32f10x_hd.o-mthumb-mcpu=cortex-m3-Tstm32_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

6.生成bin文件和hex文件

利用arm-none-eabi-objcopy工具可以将elf文件转化为适合于单片机的bin文件和hex文件,其中参数-O(大写o)用于指定输出文件的格式(默认是bin格式)

arm-none-eabi-objcopytest.elftest.bin arm-none-eabi-objcopytest.elf-Oihextest.hex

7.编写一个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=-Tstm32_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.omain.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即可清除掉所有编译产生的文件。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    88

    文章

    11631

    浏览量

    218024
  • STM32
    +关注

    关注

    2305

    文章

    11123

    浏览量

    371219
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    GCC开发工程的模版

    = arm-none-eabi- # 启用下一项以指定GCC目录 GCC_PATH = /Applications/ARM/bin/ 12
    发表于 11-28 08:15

    【OK3506-S12Mini试用评测】编译你的第一个内核模块

    -x86/arm/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf/bin/ 工具
    发表于 10-24 21:00

    gcc工具无法汇编硬件浮点指令fsqrt问题

    团队在项目推进过程中发现,Linux环境,math库中的sqrt()函数无论是在浮点数的gcc工具中还是整数的
    发表于 10-20 06:19

    cubemx生成的main.c报错怎么解决?

    之前可以编译成功,但是开启软件i2c后编译报错。我使用git将工程还原后重新编译仍然报错,不知道是哪里出了问题,因为main.c文件我没有修改过。报错信息如下:
    发表于 09-28 09:00

    micropython配置报错怎么解决?

    LINK rt-thread.elf c:/env-windows/tools/gnu_gcc/arm_gcc/mingw/bin/../lib/gcc/
    发表于 09-17 07:13

    为什么RT Thread Studio 链接器无法正确读取链接文件

    大家好,我用RT Thread Studio 创建工程,然后下载相应的编译器,编译源代码,源码编译成功,但是最后链接时出现问题: 。。。。 arm-none-eabi-gcc \&q
    发表于 09-02 08:22

    求助,关于NanoEdge AI Studio生成的库交叉编译器版本疑问求解

    20231009\", 那么问题来了,怎么在NanoEdge AI Studio设定交叉编译器呢,比如设置为armcc、armclang、iccram,因为我需要将库加到keil或者iar工程里面。 看样子这个软件生成的库是arm-g
    发表于 08-08 07:25

    STM32CubeIDE报错编译STM32MP135(Projects\\STM32MP135C-DK\\External_Loader)的原因?

    /com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.13.3.rel1.win32_1.0.0.202411081344/tools/bin/../lib/gcc
    发表于 07-11 06:19

    【沁恒CH585开发板免费试用体验】CH585开发环境搭建(二)

    Windows 应用开发的 GNU 工具开发环境),它的编译产物一般是原生 Windows 应用,虽然它本身不一定非要运行在 Wind
    发表于 07-03 23:12

    CW32L010 MCU在VSCode+GCC+EIDE+JLink的使用示例

    、安装Embedded IDE、Cortex-Debug等插件。 2、下载安装gcc-arm-none-eabi工具。 3、运行VSCode,打开CW32L010 MCU的GCC示例
    的头像 发表于 07-01 14:52 816次阅读
    CW32L010 MCU在VSCode+<b class='flag-5'>GCC</b>+EIDE+JLink<b class='flag-5'>下</b>的使用示例

    在IAR Arm开发工具中--function_sections编译选项的使用

    本文主要介绍在IAR Arm开发工具中不修改源代码的情况使用‑‑function_sections编译选项把函数放到单独的section
    的头像 发表于 06-13 13:53 1522次阅读
    在IAR <b class='flag-5'>Arm</b><b class='flag-5'>开发工具</b><b class='flag-5'>链</b>中--function_sections<b class='flag-5'>编译</b>选项的使用

    可以在MCUXpressoIDE中哪些位置管理工具

    使用 arm-none-eabi-gcc,它应该是相同的,与 13.2 版相同。我不知道为什么我会收到这么多这样的错误
    发表于 04-10 07:37

    为什么会报错Could not determine GDB version using command: arm-none-eabi-gdb --version?

    我已经重启电脑了,没用; 重装软件没有,没有; 将ST_link_server卸载重装也没有; 将arm-none-eabi-gdb加入windows 11系统环境变量,也没用; 将软件的GDB
    发表于 03-12 08:08

    ubuntu24.04上安装gcc工具出现报错怎么解决?

    虚拟机安装的ubuntu24.04.1,默认gcc版本13,从芯来官网下载了对应的gcc版本的工具,到最后编译报错: riscv64-un
    发表于 03-07 12:39

    stm32cubeide编译的时候报错,无法生成hex文件怎么解决?

    stm32cubeide编译的时候报错,并且无法生成hex文件怎么办急急急!
    发表于 03-07 08:17