使用LLVM-embedded-toolchain-for-Arm-17.0.1开发STM32

发布者:BlissfulBliss最新更新时间:2024-05-08 来源: elecfans关键字:开发  STM32 手机看文章 扫描二维码
随时随地手机看文章

LLVM-embedded-toolchain-for-Arm 是一个 ARM 公司开源的适用于 32 位ARM芯片的工具链,支持多种ARM指令集架构,包括最新的 CM85 内核。由于是基于 LLVM 和 picolibc构建出的工具链,因此在代码体积和执行效率上都很有竞争力,甚至可以和商用闭源的工具链进行 PK。

支持的架构
Armv6-M
Armv7-M
Armv7E-M
Armv8-M Mainline
Armv8.1-M Mainline
Armv4T (experimental)
Armv5TE (experimental)
Armv6 (experimental, using the Armv5TE library variant)
AArch64 armv8.0 (experimental)


这篇文章教大家,如何在 RT-Thread 上,使用最新发布的 LLVM-embedded-toolchain-for-Arm-17.0.1 版本开发stm32,以星火1号为例。

适配LLVM工具链

由于RT-Thread内核和构建工具已经支持了这款工具链,因此只需要修改我们当前使用的BSP即可。

主要工作就是修改rtconfig.py 添加llvm-arm的编译参数
由于目前RT-Thread主仓库已经有两个BSP支持了这个工具链,我们可以参考现有的。

打开星火1号对应的BSP,目录为:bsp/stm32/stm32f407-rt-spark。然后使用文本编辑工具(如:VSCode)打开rtconfig.py文件。

1.在CROSS_TOOL配置的地方添加 llvm-arm 相关信息:

cross_tool provides the cross compiler

EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR

if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc'
EXEC_PATH = r'C:UsersXXYYZZ'
elif CROSS_TOOL == 'keil':
PLATFORM = 'armcc'
EXEC_PATH = r'C:/Keil_v5'
elif CROSS_TOOL == 'iar':
PLATFORM = 'iccarm'
EXEC_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.3'
elif CROSS_TOOL == 'llvm-arm': # 新添加的部分
PLATFORM = 'llvm-arm'
EXEC_PATH = r'D:ProgremLLVMEmbeddedToolchainForArm-17.0.1-Windows-x86_64bin'

2.完善具体的编译参数

if PLATFORM == 'gcc':

toolchains ...

elif PLATFORM == 'armcc':

toolchains ...

elif PLATFORM == 'armclang':

toolchains ...

elif PLATFORM == 'iccarm':

toolchains ...

elif PLATFORM == 'llvm-arm': # 新添加的部分

toolchains

PREFIX = 'llvm-'
CC = 'clang'
AS = 'clang'
AR = PREFIX + 'ar'
CXX = 'clang++'
LINK = 'clang'
TARGET_EXT = 'elf'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' --target=arm-none-eabihf -mfloat-abi=hard -march=armv7em -mfpu=fpv4-sp-d16'
DEVICE += ' -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti'
CFLAGS = DEVICE
AFLAGS = ' -c' + DEVICE + ' -Wa,-mimplicit-it=thumb ' ## -x assembler-with-cpp
LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rt-thread.map,-u,Reset_Handler -lcrt0 -T board/linker_scripts/link.lds'
CPATH = ''
LPATH = ''
if BUILD == 'debug':
CFLAGS += ' -O0 -gdwarf-2 -g'
AFLAGS += ' -gdwarf-2'
else:
CFLAGS += ' -O2'
CXXFLAGS = CFLAGS
POST_ACTION = OBJCPY + ' -O binary **TARGET rtthread.binn' + SIZE + ' **TARGET n'

编译工程

使用 env 工具打开当前 bsp,设定要使用的工具链和对应的路径。

set RTT_CC=llvm-arm
set RTT_EXEC_PATH=D:ProgremLLVMEmbeddedToolchainForArm-17.0.1-Windows-x86_64bin

然后运行 scons 命令,执行编译

scons

发现编译报错了,看起来是原来的链接脚本不太规范,llvm检测比较严格。

1.jpg?imageView2/2/w/1000

我们打开对应的文件,在 = 后面加一个空格,再次编译。

又出现了一个错误。

1.jpg?imageView2/2/w/1000

这次是提示 .eh_frame 和 .data 两个段的地址发生了冲突。对比了下stm32l475-atk-pandora 和星火1号bsp的链接脚本文件。

发现星火1号的链接脚本缺少了.eh_frame 段的定义。

1.jpg?imageView2/2/w/1000

我们添加是缺少的定义,继续编译。编译成功!

1.jpg?imageView2/2/w/1000

然后拖入到星火1号的 U 盘,咦!没下载成功,提示下载失败了。。。

1.jpg?imageView2/2/w/1000

然后,尝试了下使用gcc编译出来的bin文件,咦!下载成功了。这说明我们LLVM的工具链编译出来的文件缺少有问题!

使用比较工具,比较这两个bin文件,一打开就发现了不对劲的地方。LLVM编译出来的bin文件,前面缺少了一块。

1.jpg?imageView2/2/w/1000

仔细一看,这不是前面的中断向量表吗,原来是LLVM编译的工具少了这一部分,这样就好办了,问题肯定出来启动文件这里。看了下控制启动文件是否参与编译的脚本,发现,确实缺少了针对llvm-arm这个工具链的处理。

1.jpg?imageView2/2/w/1000

添加上之后,继续编译,成功了,果然固件大小也变大了很大,达到了和gcc一样的量级。

1.jpg?imageView2/2/w/1000

这次下载成功了,而且程序也正常的运行起来了!

1.jpg?imageView2/2/w/1000

代码优化对比

比较一下代码体积(text段大小)

1.jpg?imageView2/2/w/1000


关键字:开发  STM32 引用地址:使用LLVM-embedded-toolchain-for-Arm-17.0.1开发STM32

上一篇:STM32库函数与寄存器开发区别
下一篇:基于STM32F429芯片的单片机芯片内存映射图

推荐阅读最新更新时间:2026-03-24 12:00

STM32高级开发(1)-开源是什么
开源的历史及简介 在上个世纪计算机发展的早期阶段,软件几乎都是开放的,任何人使用软件的同时都可以查看软件的源代码,或者根据自己的需要去修改它。在程序员的社团中大家互相分享软件,共同提高知识水平。这种自由的风气给大家带来了欢乐,也带来了进步。 但不久之后,以微软为主的一些商业公司就破坏了这种风气。这些商业公司从自由的计算机社团里雇佣了大量的技术高手,开发带有知识产权保护的专有软件。他们在分发软件的时候也不再附带源代码。从此,专有软件的时代到来了。直到现在,专有软件不公开源代码仍是默认的行业潜规则。 即使这样,崇尚自由的斗士们也没有妥协。他们认为,数字时代本应是自由的,任何人都可以自由的获取软件资源及其源代码,而不应该被少数
[单片机]
<font color='red'>STM32</font>高级<font color='red'>开发</font>(<font color='red'>1</font>)-开源是什么
在Mac OS X中使用VIM开发STM321
在先前的博文⎣在Mac OS X中搭建STM32开发环境⎤中,我们在Mac中DIY出了最简单的交叉编译和下载环境。但是,只有交叉编译和下载环境是不够的,方便起见,我们需要一个像Keil或者IAR for ARM一样的集编辑源代码、调试与一体的开发环境。当然我们可以选择eclipse,BUT,既然都已经走到这一步了,我们为什么不来一个彻彻底底的DIY呢? 所以,我又看到了VIM这款一直以来低调奢华的编辑器,由于其跨平台的特性,我计划一劳永逸的搞定它!从此不必再纠结用什么IDE更好了,收费的、摸不着头脑的、配置纠结的都特么滚犊子,简直受够了!VIM配置好了以后,可以装进U盘带走,走到哪写到哪,你是不是也激动了?走起
[单片机]
在Mac OS X中使用VIM<font color='red'>开发</font><font color='red'>STM32</font>(<font color='red'>1</font>)
Ubuntu下安装Stm32的Eclipse的开发环境(1)
在最起初的时候,我刚刚接触linux上单片机的开发,最喜欢的就是 eclipse + arm-plug-in + arm-none-eabi 的开发环境,因为这是在Linux上最接近于windows下keil、IAR等IDE的开发方式,然而那是由于对eclipse亦或是makefile等编译过程中的工具的不甚了解,很多时候会遇到一些莫名的错误,也导致了那是觉得这样的环境很鬼畜,现在看来多是一些很浅显的问题,直到最近我再一次的尝试了eclipse开发环境的搭建和使用,我才很顺利的完成了程序的配置。现在也把这个方法推荐给大家,不过在使用这个方式前,还是建议大家先把之前的文章内容看懂了,否则很多时候遇到问题都会不知道怎么解决。 安装
[单片机]
STM32开发笔记7: ST-LINK/V2-1驱动程序的安装
单片机型号:ST-LINK 插入ST-LINK/V2-1仿真器后,会提示驱动硬件的安装,除了大容量存储器外,虚拟串口和调试端口都需要安装驱动程序。 这个驱动程序存在于相应的IDE开发环境中,例如Keil软件,我们只需要将驱动程序的路径指定到相应的目录,即可进行正确的安装。 安装后的设备管理器如下图所示。 这样就完成了驱动程序的安装,我使用的开发板是STM32F030R8,与计算机正确连接后,LD1常亮,LD3常亮,LD2闪亮。
[单片机]
<font color='red'>STM32</font><font color='red'>开发</font>笔记7: ST-LINK/V2-<font color='red'>1</font>驱动程序的安装
stm32开发开发笔记(1)-开发板主控芯片总体映像
国内一行业知名人士要用stm32来开发一个产品,准备将这个产品的开发的过程记录下来。 手里有与一个某宝上淘来的stm32开发板,控制器IC的型号为stm32f103vet6 ,由于ST公司推出的产品众多, 而且每个产品的名字都比较长,不是很容易记忆,作为开发者也没有必要去记住每个型号的特征。 所以我去ST的官网上查询到以下的信息。 显然 根据名字,我们的产品的主控制器型号就是stm32F1系列中一个。 当然,有F1系列,当然就有F0系列,F2系列,F3系列,F4系列,不行你看 可以看到,st公司的产品线极为丰富。根据名字的不同,对应的是不同的内核架构。 因为我们使用的stm103vet6是F1 系列,我们就
[单片机]
<font color='red'>stm32</font><font color='red'>开发</font>板<font color='red'>开发</font>笔记(<font color='red'>1</font>)-<font color='red'>开发</font>板主控芯片总体映像
STM32的串口接收环形缓存区实现_1
在我们使用STM32串口进行发送连续大量的数据包的时候,如果接收程序处理不及时,可能导致数据包错位,为了解决这种问题,我们通常的处理是在串口中断状态机中,待事件执行完成后添加接收标志位判断,这里大家可以观看up江协科技的视频【STM32入门教程-2023版 细致讲解 中文字幕】 网页链接 这里对该方法不进行过多赘述,本期所引入的是另一种处理串口接收数据的数量太大的,亦或者当数据接收太快时的解决办法,串口环形缓存区(Ring Buffer) ①这里,我们首先要介绍一些数据结构中的前置知识 按照分类,常见的队列结构可分为两种:普通队列和循环队列 在计算机中,每个信息都是存储在存储单元中的,譬如,上图的一些小方格就是一个个存储单
[单片机]
<font color='red'>STM32</font>的串口接收环形缓存区实现_<font color='red'>1</font>
STM32中APB1与APB2差异的详细解析
STM32微控制器中的APB1和APB2的区别 STM32微控制器中的APB1和APB2是两种不同的外设总线,主要区别在于时钟速度、连接的外设以及用途。以下是它们的详细对比: 1. 时钟速度 APB1 (Advanced Peripheral Bus 1): 低速总线,时钟频率通常为系统时钟的一半(例如,系统时钟为72MHz时,APB1为36MHz)。 适用于对速度要求不高的外设。 APB2 (Advanced Peripheral Bus 2): 高速总线,时钟频率通常与系统时钟相同(例如,系统时钟为72MHz时,APB2也为72MHz)。 适用于需要高速操作的外设。 2. 连接的外设 APB1:
[单片机]
stm32单片机在Keil环境下定义的变量都存储到哪去了?(以STM32f1系列为例)
stm32f1系列单片机,在keil5环境下编译后显示四个储存区域,分别是 Code, RO-data,RW-data,ZI-data Code为程序代码部分 RO-data 表示 程序定义的常量const RW-data 表示 已初始化的全局变量 ZI-data 表示 未初始化的全局变量 储存区域如下: Code, RO-data,RW-data ............flash RW-data, ZIdata...................RAM 不过初始化时RW-data从flash拷贝到RAM 所以相当于Code, RO-data占用flash的空间;RW-data, ZIdata占用RAM的空间。 如图所示的是
[单片机]
<font color='red'>stm32</font>单片机在Keil环境下定义的变量都存储到哪去了?(以STM32f<font color='red'>1</font>系列为例)
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved