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

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

[复制链接]
smallcsduck 发布时间:2018-4-12 03:13
本帖最后由 smallcsduck 于 2018-4-12 05:07 编辑

使用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试运行不知道哪里有问题,但是编译是可以通过的,后面再解决)。实际项目结构如下图。

11.png

     下面是使用Arm Compiler 6工具链需要设置的步骤:
     首先是STM32的HAL库的迁移。
     1.选择Arm Compiler 6.9编译器
1.png

      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的代码。

     最后是STemwin的迁移。
     以前写的文章在这个问题上叙述有误。我没有进行验证,想当然的认为是使用GCC版的预编译库就可以了。其实我经过试验后发现,还是得用keil版本的预编译库才行。如下图。
7.png
      上面总结就是如果是使用预编译库,那还是使用keil版本的预编译库,GCC版本的预编译库是不能通过编译的。
      最后是前一篇文章里的关于Arm Compiler 6编译器的描述。


      现在主流的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内联格式。
   本人水平有限,以上如有错误之处,敬请指出

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




6.png

点评

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

评分

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

查看全部评分

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

举报

12个回答
流水源 回答时间:2018-4-12 10:12:09
学习了
zero99 回答时间:2018-4-17 14:47:58
感谢分享,请汇总到4月技术原创
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
port.c和portmacro.h这两个文件的GCC编译器相应版本应该去哪里寻找呢?

freertos的源码里不是都带了么
各种芯片 各种编译器的
ananbo 回答时间:2018-9-11 16:22:04
请教前辈 使用Arm Compiler V6.10.1 编译stm32程序, 编译结果没有错误,但是有许多警告?有可能是哪里没有设置好吗?万分感谢!
a.jpg
b.jpg
c.jpg
d.jpg
50031185 回答时间:2018-9-11 17:12:46
本帖最后由 50031185 于 2018-9-11 17:40 编辑

经过试验  , 发现还是报了很多错误
1.jpg

没成功
然后没办法 试了下文件比较,发现 同样是 CubeMx 生成,F2的文件和F7的  FreeRTOS的文件很多不一样
2.jpg


最后 报错 集中在

../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM3\portmacro.h(209): error: unknown type name '__forceinline'
也就是提示  __forceinline 没有定义,这个如何解决?




12下一页

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

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