Keil切換到Armclang編譯器,到底強(qiáng)在哪里?
大家好,我是小麥,上次寫過一篇文章 《Keil 編譯太慢怎么辦?教你一招,提速10倍 》,減少了中間文件的生成,確實(shí)把編譯速度提高了很多,其實(shí)沒有從根本上解決問題,有大佬提出用直接上AC6。
于是我就切換到AC6上嘗試了一下,效果還是不錯(cuò)的,我就分享一下,感興趣的小伙伴們可以看一下,希望對(duì)你有所幫助。
AC6有何不同?
ARM Compiler 5(及更早版本)使用 armcc 編譯器。而AC6(ARM Compiler 6) 用 armclang 替換了 armcc,因此是一個(gè)新的編譯器。七年前就有人問了這樣的問題。
AC6和AC5具體有哪些差異呢?
參考鏈接:https://developer.arm.com/documentation/100068/0612/migrating-from-arm-compiler-5-to-arm-compiler-6/migration-overview
Arm Compiler 6 基于現(xiàn)代 LLVM 編譯器框架。Arm Compiler 5 不是基于 LLVM 編譯器框架。因此,將您的項(xiàng)目和源文件從 Arm Compiler 5 遷移到 Arm Compiler 6 ,我們需要注意幾點(diǎn):
- 調(diào)用編譯器時(shí)命令行選項(xiàng)的差異。
- 遵守語(yǔ)言標(biāo)準(zhǔn)的差異。
- 編譯器特定關(guān)鍵字、屬性和編譯指示的差異。
- 編譯器優(yōu)化和診斷行為的差異。
下面是AC6和AC5的工具鏈差異:
工具鏈差異
從這里我們可以看到,出了C編譯器和預(yù)處理器不同以外,其他基本上都是相同的。
除了工具鏈的差異,優(yōu)化也有差異,還有一些默認(rèn)的差異,包括編譯選項(xiàng),生成的固件命后綴不同等等,詳細(xì)可以參考上述的鏈接。至于強(qiáng)不強(qiáng),用了才知道嘛。
Keil中切換編譯器
在Keil MDK 5.27中,我們打開項(xiàng)目選項(xiàng),就可以切換編譯器了,這里包括了AC5和AC6,具體如下圖所示;
為了測(cè)試,我用CubeMX生成了一個(gè)STM32F103CB基于HAL庫(kù)的Keil MDK工程,使用AC5編譯器進(jìn)行構(gòu)建;
總共耗時(shí) 10 秒;
后面我切換成AC6編譯器,進(jìn)行重新構(gòu)建;
總共耗時(shí) 5 秒;
如果單純基于HAL庫(kù),沒有加入其他第三方庫(kù)的話,直接在項(xiàng)目選項(xiàng)中的編譯器選項(xiàng)中,選擇AC5和AC6就可以實(shí)現(xiàn)無縫切換,這是因?yàn)樵贑MSIS中已經(jīng)幫你做好了兼容性的處理,在cmsis_compiler.h中,這里的條件編譯選項(xiàng),我們可以發(fā)現(xiàn)已經(jīng)通過判斷不同的編譯器版本,而包含了不同的頭文件,分別是對(duì)應(yīng)armcc和armclag的;如下圖所示;
項(xiàng)目已經(jīng)根據(jù)系統(tǒng)進(jìn)行了選擇;
- #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #include "cmsis_armclang.h"
判斷當(dāng)前__ARMCC_VERSION的版本號(hào),然后在包含cmsis_armclang.h頭文件,這個(gè)文件中就已經(jīng)幫我們做好了AC6所需要的兼容性修改。參考官方的文檔“apnt_298,Migrate ARM Compiler 5 to ARM Compiler 6 MDK Tutorial”,可以知道在C語(yǔ)言部分需要做以下的修改:
當(dāng)然了,一些涉及到很底層的操作,需要C和匯編混合編程的地方,也需要進(jìn)行修改,這里在文檔中也有類似的說明;
參考鏈接:https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html#Using-Assembly-Language-with-C
添加FreeRTOS
通過ST官方的CubeMX可以非常方便地在項(xiàng)目中添加FreeRTOS。
不過通過這個(gè)軟件進(jìn)行添加RTOS的話,它默認(rèn)使用的是ARMCC VERSION 5,所以,我直接切換成ARMCC VERSION 6的時(shí)候,進(jìn)行編譯就出現(xiàn)了115個(gè)Errors。
查看了錯(cuò)誤的源頭,主要錯(cuò)誤都在port.c和portmacro.h這兩個(gè)文件中,自己動(dòng)手移植過FreeRTOS的同學(xué)應(yīng)該知道,一般適配自己的硬件平臺(tái),所要做的移植工作,都會(huì)放到這個(gè)兩個(gè)文件中;
我查看了錯(cuò)誤,基本上是C編譯器語(yǔ)法,還有C和匯編混合編程語(yǔ)法不兼容所造成的問題;
從圖中可以知道,__forceinline和__asm{ }在AC6中都是不兼容的。
下面是來自文檔apnt_298對(duì)于匯編語(yǔ)法的兼容性修改;
當(dāng)然,我們可以根據(jù)文檔將不兼容的部分都修改過來,不過這里需要對(duì)ARM匯編有較好的掌握。不過FreeRTOS已經(jīng)有對(duì)AC6有較好的支持了。這里下載FreeRTOS的源碼,需要和前面的項(xiàng)目中所使用的FreeRTOS版本保持一致。
在源碼中找到了相應(yīng)文件,提示讓我們使用GCC-ports;
在GCC的路徑下找到ARM_CM3,這里包含了我們移植所需要的兩個(gè)文件,port.c和portmacro.h;
只要把這兩個(gè)文件拷貝到項(xiàng)目中,替換原來的文件即可;
重新構(gòu)建rebulid,可以看到構(gòu)建成功,耗時(shí)也很少;
總結(jié)
本文參考了官方的文檔,簡(jiǎn)單介紹了AC5和AC6的異同,并在Keil MDK環(huán)境下進(jìn)行測(cè)試,添加了FreeRTOS,要從AC5移植到AC6則需要參考文檔Migrate ARM Compiler 5 to ARM Compiler 6 MDK Tutorial,這里面解釋地非常詳細(xì)。