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

使用Arm Compiler 6编译stm32程序(4月12号版)

[复制链接]
smallcsduck 发布时间:2018-4-12 03:13
本帖最后由 smallcsduck 于 2018-4-12 05:07 编辑
* G* d  @! Z3 Y3 i. y% \* w, m  [: b3 q0 n# T# n! z
使用Arm Compiler 6编译stm32程序(4月12号版)
      前面写过一篇把程序迁移到Arm Compiler 6的教程,但是经过实践,发现还有一些错误。而且MDK更新到5.25和Arm Compiler 6.9后,又出现了一些新的特性。所以又重新写了一下,这次都是经过实际程序验证的,应该是没有问题了。Demo工程代码放在http://github.com/babycheng/STM32F767IGDemo.gitClone下来以后直接编译(我用的板子是apollo的767的开发板,4.12试运行不知道哪里有问题,但是编译是可以通过的,后面再解决)。实际项目结构如下图。

+ R& n# o) T9 K% S  x
11.png
# o: _! B# O3 u6 r
     下面是使用Arm Compiler 6工具链需要设置的步骤:
     首先是STM32的HAL库的迁移。
     1.选择Arm Compiler 6.9编译器
1.png
8 [0 T/ b& y4 L# A  h
      2.修改C/C++选项卡,改红框里的选项。这个选项是MDK5.25刚加入的,如果你是老版本MDK,在下面的Misc Controls框里加-std=gnu11选项,是一样的效果。
2.png
     3.在Include Paths里添加如下图的头文件目录,具体的目录根据你的MDK安装目录修改,这个目录需要放在最前面,确保这个CMSIS头文件最先被搜索到。
3.png
      完成这三步,HAL库就可以用Arm Compiler 6.9编译了,编译结果没有错误没有警告。
      这里要解释一下。其实ARM在推出Arm Compiler 6的时候,已经考虑到了原有代码从Arm Compiler 5编译器迁移到Arm Compiler 6编译器的问题。在CMSIS接口里进行了预处理,原有代码只需要包含最新的CMSIS接口头文件就可以使用Arm Compiler 6了。MDK5.25附带了最新的5.3版的CMSIS接口。如果你是用STM32cubeMX自动创建的工程,那引用的是CubeMX自带的4.3版本CMSIS接口文件,这个版本的CMSIS接口是没有迁移预处理的,你需要自己添加。所以最方便的迁移办法就是添加最新版的CMSIS接口,并且要放在搜索目录最前面,编译器使用第一个被找到的头文件。那怎么看自己的代码在编译的时候是不是使用了最新版的CMSIS接口呢?你查看一下编译文件引用了哪个文件就可以了。
5.png
     如上图,如果是用了cmsis_armclang.h那就是最新版的CMSIS接口。如果是cmsis_armcc_V6.h,那就是用的老版本接口。
     然后再是FreeRTOS的迁移。
    1.把port.c和portmacro.h这两个文件用GCC编译器的相应版本就可以了。其他的FreeRTOS代码不用改。
    .STM32CubeMX创建的工程使用了CMSIS-OS v1的接口,因为ARM现在主推CMSIS-OSv2版接口,v1版的接口不更新了,所以需要做如下图修改。如果你自己使用了最新版的CMSIS-OS v2接口是不需要修改的。
4.png
   
      其实对于没有为Arm Compiler 6做适配的代码,用Arm Compiler 6编译很多错误的原因都是没有引用正确的cmsis_armclang.h头文件。使用如上图的代码,添加正确的头文件以后,代码不用修改就可以正确通过编译。
     这个用GCC代码的方法适用于c代码里面有内链汇编的。Arm Compiler 6要求内链汇编是GNU的格式。所以以前的Arm Compiler 5代码是不能通过编译的。解决办法就是直接用GNU版本的代码。如果你没有GNU版本的代码,那就只能自己改啦。
     纯汇编或者纯c语言的代码文件,基本上是不用改的,Arm Compiler 6支持Arm Compiler 5的代码。
+ k2 S; F! u; r8 I% M0 V
     最后是STemwin的迁移。
     以前写的文章在这个问题上叙述有误。我没有进行验证,想当然的认为是使用GCC版的预编译库就可以了。其实我经过试验后发现,还是得用keil版本的预编译库才行。如下图。
7.png
      上面总结就是如果是使用预编译库,那还是使用keil版本的预编译库,GCC版本的预编译库是不能通过编译的。
      最后是前一篇文章里的关于Arm Compiler 6编译器的描述。

4 d. L5 `# T- p+ `: O: C# ^  _# J
1 W2 y' C: D2 s3 `
      现在主流的Cortex-M开发环境和中间件代码都是基于GNU和Arm Compiler v5工具链的写的。其实Arm Compiler v6工具链已经出来很久了。对比Arm Compiler v5工具链,Arm Compiler v6做了很多改进。为什么要用Arm Compiler v6的工具链呢?Keil网站上有一张图解释了这个问题。
8.png
       毕竟是ARM的官方工具链,对构架理解比较深,优化的好一点吧。
       Arm Compiler 6是一个基于LLVM的工具链,那LLVM是什么呢?简单来说LLVM是把工具链的语法分析和机器码生成分开成两个独立部分。这样移植工具链到新构架就很容易了,你只要修改机器码生成部分,语法分析部分不用改。GCC的工具链这两部分是混在一起的,移植起来比较困难。LLVM与GCC比较优点很多,比如错误信息显示详细啊,编译快啊等等。感兴趣的可以百度一下。
       一般来讲LLVM的语法分析部分是从GCC继承过来的。所以吗,语法规则和GCC是差不多的。说了这么多其实就想告诉你一件事,Arm Compiler 6的C和汇编的语法和GCC是差不多的。(是不是完全相同?我没看到在文档里有写,也没有验证,脑补算是一样的。)
       现有的很多中间件,像HAL库、FREERTOS都没有为Arm Compiler 6做过适配的版本。但是都有GNU工具链的适配代码。那是不是可以直接用Arm Compiler 6编译GNU工具链的代码呢?那肯定是不行的。因为Arm Compiler 6和GNU工具链还是有不同的。
       首先是链接器不同,Arm Compiler 6用的是和Arm Compiler 5一样的armlink链接器,和GNU工具链的LD是不一样的,链接脚本也是不一样的。
       此外Arm Compiler 6和GNU编工具链用的运行时库是不一样的。Arm Compiler 6的运行时库除了提供标准C库的那些功能,还添加了Semihosting模式,支持Scatter-loading和初始化HEAP、STACK的代码。GNU的运行时库是没有上面三个功能的,需要自己用汇编写(这一点是我脑补的)。
       另外,Arm Compiler 6里面有两种汇编语言的编译器,一种是使用GNU汇编格式的armclang,一种是使用ARM汇编格式的armasm。也就是说以前Arm Compiler 5的汇编启动文件还是可以用的。但是C的内联汇编必须使用GNU内联格式。
   本人水平有限,以上如有错误之处,敬请指出
8 \, I3 R% {! _( i! J
        转载请注明出处http://smallcsduck.blog.163.com

: c5 d* }' h5 w) J6 f+ h- [" P3 G
1 q) X, l, c6 I- X; J# ^/ n& E

' I/ L' t* U* J: F: I" Y7 `2 v% q
6.png

点评

大神厉害了~ 谢谢分享  发表于 2019-4-14 09:42

评分

参与人数 2 ST金币 +18 收起 理由
wofei1314 + 12 很给力!
MrJiu + 6 很给力!

查看全部评分

收藏 6 评论12 发布时间:2018-4-12 03:13

举报

12个回答
STMWoodData 回答时间:2018-4-12 10:12:09
提示: 作者被禁止或删除 内容自动屏蔽
zero99 回答时间:2018-4-17 14:47:58
感谢分享,请汇总到4月技术原创! O, L9 r2 W- g: |0 l! h
https://www.stmcu.org.cn/module/forum/thread-615497-1-1.html
bolo 回答时间:2018-5-8 15:36:30
很详细,非常感谢
Serval 回答时间:2018-5-20 11:02:42
“C的内联汇编必须使用GNU内联格式”,看起来事项拉拢做嵌入式Linux的人,不过这样原来很多代码都要重写,没有升级动力。。。
jesseqiao 回答时间:2018-5-27 02:29:09
感谢,有时间尝试一下
Syndicate 回答时间:2018-7-6 16:42:28
port.c和portmacro.h这两个文件的GCC编译器相应版本应该去哪里寻找呢?
smallcsduck 回答时间:2018-7-16 20:09:23
Syndicate 发表于 2018-7-6 16:42
7 M  y1 p0 v& \" n: Z# |# {0 f% r  Pport.c和portmacro.h这两个文件的GCC编译器相应版本应该去哪里寻找呢?

6 S% m7 u9 {/ v  k6 Dfreertos的源码里不是都带了么6 U1 A4 i  n/ Q
各种芯片 各种编译器的
pinganbo 回答时间:2018-9-11 16:22:04
请教前辈 使用Arm Compiler V6.10.1 编译stm32程序, 编译结果没有错误,但是有许多警告?有可能是哪里没有设置好吗?万分感谢!
a.jpg
b.jpg
c.jpg
d.jpg
KEY1 回答时间:2018-9-11 17:12:46
本帖最后由 50031185 于 2018-9-11 17:40 编辑
6 Q' m5 V1 o5 {+ ?3 b" o2 |" z' S8 t& o! a. J
经过试验  , 发现还是报了很多错误  s. U7 G2 @5 }6 g6 R2 E6 K" c
1.jpg
, ~. Q- L$ r5 y$ h( X+ N% U% x3 }+ _
没成功
0 q5 u$ G) a+ c+ n9 A8 y然后没办法 试了下文件比较,发现 同样是 CubeMx 生成,F2的文件和F7的  FreeRTOS的文件很多不一样
: u. c5 e' s( ]; {3 X2 a- Y 2.jpg
, Y& Y) Z' `* ]3 p- a
9 o& ^4 o% T( {5 x8 W5 p. g7 f
& F5 a* B8 g  `6 @5 B8 m: y最后 报错 集中在
7 P. n$ [2 u* P1 d# t3 r& `- T, F  i9 W7 E3 s9 S# ~. o
../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM3\portmacro.h(209): error: unknown type name '__forceinline'/ b  B- w6 N) z9 _( u
也就是提示  __forceinline 没有定义,这个如何解决?
" ?1 ?! D* z0 L5 Z9 l7 }6 n: w2 s( P- K" o& ?6 \

/ u  K$ q- t5 a/ G+ I2 l) C; c

: _9 U9 L  P" V
zhumx 回答时间:2019-8-28 15:33:42
50031185 发表于 2018-9-11 17:12$ n* ?  p( ]( ~
经过试验  , 发现还是报了很多错误

6 i0 N" \8 v1 i* `$ E% G我的也是,请问楼主解决了吗?
dele白学病 回答时间:2020-11-21 22:13:14
基于标准库的代码,使用arm compiler v6编译还是会报错,这种办法应该对不再维护的标准库版不适用

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版