嵌入式开发中,许多新手常会碰到这样的困惑:明明是在Linux环境下用C语言编程,但在开发stm32时,为何编译工具链要用gcc-arm-none-eabi,而非看起来更熟悉的gcc?这正是我们今天要深入探讨的问题所在。
Linux下的交叉编译需求
嵌入式开发领域,我们的目标是让程序在PC上编译后,能在ARM架构上运行。然而,若采用gcc编译,生成的程序却只能在PC上运行,这显然不符合我们的初衷。比如在某个开发项目中,目标设备是ARM架构的小型设备,比如智能手表等,它们的运行环境与PC截然不同。这就需要使用特定的工具进行交叉编译,以适应不同架构的需求。这也是与传统编译相比,实现跨平台运行的关键所在。
嵌入式系统通常资源有限,与配置较高的PC相比差距很大。若直接用gcc编译的程序想在ARM设备上运行,首先在性能上就无法达标,还可能遇到兼容性问题。因此,必须使用专门的工具链来应对这些挑战。
gcc-arm-none-eabi工具链简介
gcc-arm-none-eabi是一款开源的ARM开发工具,非常实用。它主要适用于Arm-M和-A系列处理器。其功能非常全面,不仅包括GNU编译器(GCC),还有GDB。这套工具链在Linux和MacOS上的交叉编译活动中有着广泛的应用。例如,在企业开发基于ARM-M的工业控制小型设备时,这套工具链就能发挥重要作用。
这个工具链是以tar.ba2格式的包来存储的。我们得用tar-jxf这个命令来解压它,目标目录是我们打算安装的地方。解压后,bin目录里存放的就是我们后续编译时需要用到的工具链。看似简单的这一步,却是开启后续开发流程的关键。
环境变量的配置
为了方便地运用这个工具链,环境变量的设置是关键。当需要为当前用户设置环境变量时,我们会用vim编辑当前用户的配置文件。在文件末尾加上这一行:PATH=$PATH:/home//gcc-arm-none-eabi/bin。在开发日常工作中,若不配置环境变量,系统就无法识别我们所需的工具。
配置一旦成功,系统便会提示,那时便可轻松使用arm-none-eabi工具链。配置成功后,其便利性在开发过程中将不断显现。若每次使用工具都要费心寻找其具体位置,那确实会带来不少麻烦。
开发板及下载器相关
采用的是野火霸道开发板,板子上搭载的是某些特定的芯片(具体型号可依据实际情况确定)。下载器选用的是e-link,功能十分齐全。它通过CMSIS-DAP进行程序下载,并且还配备了一个串口。在硬件调试或数据交换时,这一点尤为便利,比如在进行温度监测设备开发时,串口便可以用来传输温度数据等。
在整个开发过程中,开发板与下载器扮演着士兵手中武器的角色。它们的性能优劣,直接关系到开发效率的高低以及产品的最终效果。
编译参数相关
编译文件时必须指定相应参数。通常,文件的编制采用汇编语言,在此特别提醒,汇编文件存在格式差异,分为.S和.s两种。过去,我们用小写.s格式的启动文件即可直接编译。但若使用大写.S格式的文件,则需额外添加参数-x-with-cpp。
汇编文件的gcc编译器对参数有严格规定。这些参数的正确性往往在编译过程中起着决定性的作用。因为不同的参数会直接影响到编译结果的优劣。比如,在时间敏感或空间敏感的编译场景中,参数的不同可能会导致程序功能缺失或运行效率降低。
链接相关
#include "stm32f10x.h"
int main()
{
/* 开启GPIOB时钟 */
*(unsigned int*)(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)
{
}
ld文件是链接文件,它在使用不同芯片时可能需要被修改。修改后,需要将它复制到工程里。链接器会依据这个ld文件来链接.o和main.o这两个文件,最终产出含有调试信息的elf文件。同时,在这一过程中,还需向链接器提供一些必要的参数。
之后,通过使用arm-none-eabi-工具,我们可以将elf文件转换成适用于单片机的bin文件和hex文件。在这个转换过程中,参数-O(大写O)是用来设定输出文件格式的,它的默认值是bin格式。这些步骤在嵌入式开发的全过程中,就像链条上的一个个小环节,彼此紧密相连。任何一个环节出现问题,都可能对最终的成品造成影响。
在进行嵌入式开发的过程中,你是否在编译阶段遭遇过一些难题?不妨点赞、转发,并在评论区留下你的想法。