Keil切换到armclang编译器,到底强在哪里?

点击上方“小麦大叔”,选择“置顶/星标公众号”

福利干货,第一时间送达

大家好,我是小麦,上次写过一篇文章 《Keil 编译太慢怎么办?教你一招,提速10倍 》,减少了中间文件的生成,确实把编译速度提高了很多,其实没有从根本上解决问题,有大佬提出用直接上AC6。

820f287195fa6fff47e7a86a23e259fe.png


于是我就切换到AC6上尝试了一下,效果还是不错的,我就分享一下,感兴趣的小伙伴们可以看一下,希望对你有所帮助。

AC6有何不同?

ARM Compiler 5(及更早版本)使用 armcc 编译器。而AC6(ARM Compiler 6) 用 armclang 替换了 armcc,因此是一个新的编译器。七年前就有人问了这样的问题。

70d9833ecac81b4e47b469f0f13733b6.png

AC6和AC5具体有哪些差异呢?

参考链接:https://developer.arm.com/documentation/100068/0612/migrating-from-arm-compiler-5-to-arm-compiler-6/migration-overview

Arm Compiler 6 基于现代 LLVM 编译器框架。Arm Compiler 5 不是基于 LLVM 编译器框架。因此,将您的项目和源文件从 Arm Compiler 5 迁移到 Arm Compiler 6 ,我们需要注意几点:

  • 调用编译器时命令行选项的差异。

  • 遵守语言标准的差异。

  • 编译器特定关键字、属性和编译指示的差异。

  • 编译器优化和诊断行为的差异。

下面是AC6和AC5的工具链差异:

df79b594584dff25ec9339549e7626a8.png
工具链差异

从这里我们可以看到,出了C编译器和预处理器不同以外,其他基本上都是相同的。

除了工具链的差异,优化也有差异,还有一些默认的差异,包括编译选项,生成的固件命后缀不同等等,详细可以参考上述的链接。至于强不强,用了才知道嘛。

Keil中切换编译器

Keil MDK 5.27中,我们打开项目选项,就可以切换编译器了,这里包括了AC5和AC6,具体如下图所示;

306c34d979168e652c346f8d8f54e4be.png

为了测试,我用CubeMX生成了一个STM32F103CB基于HAL库的Keil MDK工程,使用AC5编译器进行构建;

4a6e921acc35e8cc14c96fa85fa44078.png

总共耗时 10 秒

后面我切换成AC6编译器,进行重新构建;

761da9be967e79692df018050691ee7f.png

总共耗时 5 秒

如果单纯基于HAL库,没有加入其他第三方库的话,直接在项目选项中的编译器选项中,选择AC5和AC6就可以实现无缝切换,这是因为在CMSIS中已经帮你做好了兼容性的处理,在cmsis_compiler.h中,这里的条件编译选项,我们可以发现已经通过判断不同的编译器版本,而包含了不同的头文件,分别是对应armccarmclag的;如下图所示;

ee0d5f0cb21ac67c695b9a2db5eef6b0.png

项目已经根据系统进行了选择;

#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
  #include "cmsis_armclang.h"

判断当前__ARMCC_VERSION的版本号,然后在包含cmsis_armclang.h头文件,这个文件中就已经帮我们做好了AC6所需要的兼容性修改。参考官方的文档“apnt_298,Migrate ARM Compiler 5 to ARM Compiler 6 MDK Tutorial”,可以知道在C语言部分需要做以下的修改:

b6b273a018acc3e0e2f8339243c84856.png

当然了,一些涉及到很底层的操作,需要C和汇编混合编程的地方,也需要进行修改,这里在文档中也有类似的说明;

参考链接https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html#Using-Assembly-Language-with-C

添加FreeRTOS

通过ST官方的CubeMX可以非常方便地在项目中添加FreeRTOS。

c456d38668faa44eb5a9743138f76ef5.png

不过通过这个软件进行添加RTOS的话,它默认使用的是ARMCC VERSION 5,所以,我直接切换成ARMCC VERSION 6的时候,进行编译就出现了115个Errors。

7189bb4b66442e278e6cdbffd70a3a8a.png

查看了错误的源头,主要错误都在port.cportmacro.h这两个文件中,自己动手移植过FreeRTOS的同学应该知道,一般适配自己的硬件平台,所要做的移植工作,都会放到这个两个文件中;

我查看了错误,基本上是C编译器语法,还有C和汇编混合编程语法不兼容所造成的问题;

43ba255e0ce9f7576a9ea29c8ac415b4.png

从图中可以知道,__forceinline__asm{ }在AC6中都是不兼容的。

下面是来自文档apnt_298对于汇编语法的兼容性修改;a54ae04be685a7e6c6d9e0b472a14156.png

当然,我们可以根据文档将不兼容的部分都修改过来,不过这里需要对ARM汇编有较好的掌握。不过FreeRTOS已经有对AC6有较好的支持了。这里下载FreeRTOS的源码,需要和前面的项目中所使用的FreeRTOS版本保持一致。

在源码中找到了相应文件,提示让我们使用GCC-ports

763183977a747f2dc12ae14ed58ff009.png

在GCC的路径下找到ARM_CM3,这里包含了我们移植所需要的两个文件,port.cportmacro.hff39a36782e50cc48160e2d1174ac6cb.png

只要把这两个文件拷贝到项目中,替换原来的文件即可;

重新构建rebulid,可以看到构建成功,耗时也很少;

5f8ab258910fc094d211b1f995bad3c8.png

总结

本文参考了官方的文档,简单介绍了AC5和AC6的异同,并在Keil MDK环境下进行测试,添加了FreeRTOS,要从AC5移植到AC6则需要参考文档Migrate ARM Compiler 5 to ARM Compiler 6 MDK Tutorial,这里面解释地非常详细。最后如果文章有什么错误或者不足的地方,请指正,如果有什么好的想法分享,欢迎在下方讨论

—— The End ——

推荐好文  点击蓝色字体即可跳转

 实例分析如何远离漫天飞舞的全局变量

☞ 我写了一段代码,CPU为什么就能运行?eb7411dcc95afe7ebed78366d347fcc1.gif

☞ 这14种嵌入式实时系统,你用过哪些?

☞ 推荐一款我私藏已久的串口示波神器

欢迎转发、留言、点赞、分享给你的朋友,感谢您的支持!

点击上方名片关注公众号

分享 💬  点赞 👍  在看 ❤️ 

以“三连”行动支持优质内容!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小麦大叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值