你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32使用Arm Compiler v6工具链编译程序

[复制链接]
smallcsduck 发布时间:2018-3-21 03:57
本帖最后由 smallcsduck 于 2018-3-21 04:09 编辑 ) k3 y; o" V' Q- e

# P# b1 t+ m0 a/ Z6 S      现在主流的Cortex-M开发环境和中间件代码都是基于GNU和Arm Compiler v5工具链的写的。其实ArmCompiler v6工具链已经出来很久了。对比ArmCompiler v5工具链,Arm Compiler v6做了很多改进。这个文章就来研究下怎么快捷的把ArmCompiler v5的代码迁移到Arm Compiler v6上。为什么要用Arm Compiler v6的工具链呢?Keil网站上有一张图解释了这个问题。2 h9 v4 L# o& r3 b; o
图片1.png & [; R% U- ~  V, X; I
        毕竟是ARM的官方工具链,对构架理解比较深,优化的好一点吧。
( C6 ?5 m# n& [( `8 I& P3 O        先介绍下Arm Compiler v6编译器。3 S2 i0 W; Q, D4 `( I
        Arm Compiler 6是一个基于LLVM的工具链,那LLVM是什么呢?简单来说LLVM是把语法分析和机器码生成分开成两个独立部分。这样移植编译器到新构架就很容易了,你只要修改机器码生成部分,语法分析不用改。GCC的编译器这两部分是混在一起的。LLVM与GCC比较优点很多。比如错误信息详细啊,编译快啊等等。感兴趣的可以自行查一下。' E: `" }! g; w, C+ }
        一般来讲LLVM的语法分析部分是从GCC继承过来的。所以吗,语法规则和GCC是差不多的。说了这么多其实就像告诉你一件事,Arm Compiler 6的C和汇编的语法和GCC是差不多的。(是不是完全相同?我没看到在文档里有写,也没有验证,脑补算是一样的。)! M6 t) }! O- T( a! W
        现有的很多中间件,像HAL库、FREERTOS都没有为Arm Compiler 6做过适配的版本。但是都有GNU工具链的适配代码。那是不是可以直接用Arm Compiler 6编译GNU工具链的代码呢?那肯定是不行的。因为Arm Compiler 6和GNU工具链还是有不同的。9 s, Z* \9 p4 o7 U$ i+ ?9 Z
        首先是链接器不同,Arm Compiler 6用的是和Arm Compiler 5一样的armlink链接器,和GNU工具链的LD是不一样的,链接脚本也是不一样的。
% `; `' }& p3 [2 i此外Arm Compiler 6和GNU编工具链用的运行时库是不一样的。Arm Compiler 6的运行时库除了提供标准C库的那些功能,还添加了Semihosting模式,支持Scatter-loading和初始化HEAP、STACK的代码。GNU的运行时库是没有上面三个功能的,需要自己用汇编写(这一点是我脑补的)。8 |# x; E0 P1 J& _# l& Y& w
        另外,Arm Compiler 6里面有两种汇编语言的编译器,一种是使用GNU汇编格式的armclang,一种是使用ARM汇编格式的armasm。也就是说以前Arm Compiler 5的汇编启动文件还是可以用的。但是C的内联汇编必须使用GNU内联格式。
' P0 C2 O" i( r5 i4 a+ C ) z5 J  L6 B0 a' v- i/ \1 B  z
: O+ \5 e9 j* x$ q
        下面实际使用Arm Compiler 6工具链编译一下使用HAL库的程序。9 b2 c3 O/ u: z. g$ P3 S7 Q8 C3 K
        看过上面说的,要把GUN工具链的项目或者老的Arm Compiler 5项目迁移到Arm Compiler 6工具链需要修改的地方就很明显了。Arm Compiler 6帮助文档里专门有一个从Arm Compiler 5往Arm Compiler 6迁移的文档。可以参考。$ Z! T) U# x; i6 s2 n+ l
把Arm Compiler 5的项目往Arm Compiler 6迁移很简单。用STM32CubeMX创建一个MDK项目。默认是Arm Compiler 5的编译器。直接用Arm Compiler 6编译肯定很多错误。成功迁移其实只需要简单的两步。
7 y4 z4 F5 o& b7 S& P        1、你打开一个MDK项目。然后在Target选项卡里选择Arm Compiler 6。) n$ P5 B" L- k
图片2.png
; u' @" a$ v" I9 N# {        2、在C/C++选项卡里添加一个定义__CNUC__- a. u- V4 m+ o2 D1 A" a' l: q- K& l
图片3.png
% C4 I! {% |, a
* M, D8 m' t: C* _2 u        然后点编译就可以了。没有任何错误和警告,顺利通过编译。$ ~  Y' ?4 q! ^3 ?' u- E- h) P
        这个添加的定义导致编译时候的同时引用了CMSIS的GNU实现接口(cmsis_gcc.h)和Arm Compiler 6的实现接口(cmsis_armcc_V6.h),可能会出现问题。那我们严谨一点,不搞这种投机取巧的办法。- h. @1 V) G- R) R- w0 k+ L
Arm Compiler 6和Arm Compiler 5的C语言区别主要在扩展的C语言属性关键字上。就是__weak,__packed这类关键字。那我们预处理定义里面自己添加转换规则就行了。使用-D这个选项。比如-D__weak="__attribute__((weak))" -D__packed="__attribute__((__packed__))" -D__NOINLINE="__attribute__ ( (noinline) )"
& y/ c+ k3 v3 V  w8 ?/ s2 Y       根据编译的时候出现的错误,按照迁移手册上说明,定义一个预编译的转换规则就行。
( g5 |6 F- H( K- a+ V" [ 图片4.png + f# O2 O# A1 N# _# c+ t; T
        前面的添加转换规则对于纯C程序肯定是完全够用了。但是碰到有内链ARM汇编的代码怎么办呢?没办法。只有按照GNU的格式改吧。
& H, h. k3 C5 l* k        不过这个时候你可以找一下有没有GNU版本的源码直接用GNU工具链的源码就可以了。* ^$ r7 E: S! t7 I% ~# Y0 x2 d5 ]
        比如FreeRTOS源码里面很关键的两个文件:port.c和portmacro.h。这两个文件里面都有大量的内链汇编。不同构架不同编译器的代码是不一样的。要用Arm Compiler 6工具链编译,你直接用GNU工具链版本的代码就可以了。另外STM32CubeMX是用了CMSIS-RTOS的接口。所以要改一下cmsis_os.c文件。% D4 b- _) ~* t% e
[size=1em]
图片5.png 4 K6 i3 H3 ?9 ~! K
" ?+ Y3 s2 a$ d
        最后,对于预编译的库怎么选择呢?比如emwin,针对不同的工具链提供了不同的库版本。但是没有提供Arm Compiler 6工具链的版本,那你直接用GNU的版本的预编译库就行了。
     一点小小的研究,如果有错误的地方,请回复指出。
  o, e1 ~* m+ y4 e) {

1 t! q& z: Y$ ]5 N8 C4 Y. Z; }

$ I+ X) ~6 y# p0 A

转载请注明出处http://smallcsduck.blog.163.com

' K2 `# H9 ^& b; s6 G8 N5 N
; h' `% E: {; x( J: ~$ t" m" z- ]

8 m; z  g  L6 n, h

评分

参与人数 1 ST金币 +2 收起 理由
MrJiu + 2 赞一个!

查看全部评分

赞 收藏 4 评论6 发布时间:2018-3-21 03:57

举报

6个回答
MrJiu 回答时间:2018-3-21 10:17:53
不错的说。。。
七哥 回答时间:2018-3-21 10:41:43
厉害,看了半天没搞懂,以前都没关注过这些。不明觉厉
x5y4z3 回答时间:2018-3-21 11:19:54
早期 Keil for ARM 的 Compiler 中,除了自家的 RV (MDK) 外,还支持 GUN 及 CARM 呢!$ T4 Q0 W+ |, u$ O# e5 g
anobodykey 回答时间:2018-3-21 11:26:20
感谢楼主分享
Inc_brza 回答时间:2018-3-21 12:01:50
跟旧工程有好多冲突,暂时没用
maxtch 回答时间:2018-3-21 16:01:59
语法分析部分 LLVM/clang 和 GCC 已经 99.9% 一致了。除了极个别驱动程序以外,LLVM/clang 可以编译完整的 amd64、armv7 和 aarch64 版本的 Linux 内核。

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版