请选择 进入手机版 | 继续访问电脑版
搜索
查看: 16241|回复: 12

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

[复制链接]

该用户从未签到

14

主题

50

帖子

29

蝴蝶豆

中级会员

最后登录
2018-8-25
发表于 2018-4-12 03:13:55 | 显示全部楼层 |阅读模式
本帖最后由 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

评分

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

查看全部评分

回复

使用道具 举报

该用户从未签到

10

主题

1665

帖子

65

蝴蝶豆

论坛元老

最后登录
2021-5-10
发表于 2018-4-12 10:12:09 | 显示全部楼层
学习了
回复

使用道具 举报

  • TA的每日心情
    开心
    2018-2-6 09:20
  • 签到天数: 1 天

    [LV.1]初来乍到

    1182

    主题

    4967

    帖子

    1

    蝴蝶豆

    论坛元老

    最后登录
    2020-3-17
    发表于 2018-4-17 14:47:58 | 显示全部楼层
    感谢分享,请汇总到4月技术原创
    https://www.stmcu.org.cn/module/forum/thread-615497-1-1.html
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    2

    帖子

    0

    蝴蝶豆

    中级会员

    最后登录
    2020-11-25
    发表于 2018-5-8 15:36:30 | 显示全部楼层
    很详细,非常感谢
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    15

    帖子

    10

    蝴蝶豆

    中级会员

    最后登录
    2020-5-26
    发表于 2018-5-20 11:02:42 | 显示全部楼层
    “C的内联汇编必须使用GNU内联格式”,看起来事项拉拢做嵌入式Linux的人,不过这样原来很多代码都要重写,没有升级动力。。。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    77

    帖子

    0

    蝴蝶豆

    中级会员

    最后登录
    2021-3-15
    发表于 2018-5-27 02:29:09 | 显示全部楼层
    感谢,有时间尝试一下
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    1

    帖子

    0

    蝴蝶豆

    新手上路

    最后登录
    2018-7-9
    发表于 2018-7-6 16:42:28 | 显示全部楼层
    port.c和portmacro.h这两个文件的GCC编译器相应版本应该去哪里寻找呢?
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    14

    主题

    50

    帖子

    29

    蝴蝶豆

    中级会员

    最后登录
    2018-8-25
     楼主| 发表于 2018-7-16 20:09:23 | 显示全部楼层
    Syndicate 发表于 2018-7-6 16:42
    port.c和portmacro.h这两个文件的GCC编译器相应版本应该去哪里寻找呢?

    freertos的源码里不是都带了么
    各种芯片 各种编译器的
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    29

    主题

    106

    帖子

    0

    蝴蝶豆

    金牌会员

    最后登录
    2023-6-9
    发表于 2018-9-11 16:22:04 | 显示全部楼层
    请教前辈 使用Arm Compiler V6.10.1 编译stm32程序, 编译结果没有错误,但是有许多警告?有可能是哪里没有设置好吗?万分感谢!
    a.jpg
    b.jpg
    c.jpg
    d.jpg
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    41

    主题

    332

    帖子

    42

    蝴蝶豆

    金牌会员

    最后登录
    2021-4-2
    发表于 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 没有定义,这个如何解决?




    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

    GMT+8, 2024-4-16 21:26 , Processed in 1.211741 second(s), 43 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表