日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

从 Arm Compiler 5 迁移到 Arm Compiler 6

發布時間:2023/12/8 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从 Arm Compiler 5 迁移到 Arm Compiler 6 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在開始之前,建議先備份你的工程代碼。

遷移條件

要使用 ARM Compiler 6,建議MDK的版本至少為:

  • MDK版本5.23或更高版本

MDK版本5.23提供兩個編譯器,分別是 ARM Compiler 5.06 和 ARM Compiler 6.6。

軟件包也需要支持 ARM Compiler 6,以下是支持 ARM Compiler 6 的最低軟件包版本:

  • Keil MDK-Middleware包: 版本7.4.0及以上
  • Keil ARM Compiler Support 包: 版本1.3.0及以上
  • ARM CMSIS 包: 版本5.0.1及以上

切換編譯器

  • 使用MDK打開工程。

  • 選擇 Project - Options for Target from the menu

  • 點擊 Target 選項卡,找到 ARM Compiler: 下拉列表。

  • 設置ARM編譯器為 Version 6

  • 點擊 OK 鍵確認更改。

  • 切換后的ARM Compiler 6所有設置都為默認值。

    設置警告級別

    ARM Compiler 6 提供的警告級別比 ARM Compiler 5 多,如果你習慣 ARM Compiler 5 的警告級別,選擇AC5-like Wamings。

    可以通過在參數前面加上-Wno-來禁用特定診斷組的警告。

    例如,通過選項-Wno-missing-noreturn禁用了–Wmissing-noreturn。

    在遷移的第一步中,建議將級別切換為“無警告”。 這將使您可以專注于錯誤消息。

    解決所有錯誤信息后,選擇AC5-like Wamings,設置-Wno-invalid-source-encoding選項:禁用源代碼編碼檢測,因為LCD和打印信息有中文,編譯器認為這些是無效編碼。

    如果想測試下代碼是否規范,可以選擇All wamings。

    設置優化級別

    選擇-Os babanced級別,平衡代碼大小和性能。
    如果想代碼執行速度快,可以選擇-O2、-O3、-Ofast級別,優化性能(速度),優化依次提升,但生成的代碼大小可能會變大。
    如果想減少代碼大小,可以選擇-Os babanced、-Oz image size級別,代碼大小優化依次提升。
    比如我的工程,使用-Oz image size級別編譯出的code大小為103026、使用-Os babanced級別編譯出的code大小為115848字節、使用-O3級別編譯出的code大小為160536。差別很大。

    -O0級別沒有做任何優化。注意ARM Compiler 5的-O0實際上是有優化的,所以ARM Compiler 6的-O1級別與ARM Compiler 5的-O0級別最為相似,都可以獲取良好的調試體驗,在調試階段可以選用。

    不兼容的語言擴展

    主要是代碼中的__align(x)、__packed、__weak等編譯器擴展語言。解決方法是使用CMSIS定義的相關宏。

  • 替換CMSIS頭文件,這里使用的是5.6.0版本的CMSIS。
    如果安裝了較新的Keil,可以在路徑.\Keil_v5\ARM\PACK\ARM\CMSIS目錄中找到合適的CMSIS版本。
    將.\Keil_v5\ARM\PACK\ARM\CMSIS\5.6.0\CMSIS\Core\Include內的文件替換到工程code_cm3.h所在的文件夾。

  • 修改lwip協議棧的cc.h文件,因為lwip使用到了編譯器的擴展語言,比如取消結構體的對齊優化、指定變量對齊方式等,這些擴展語言 ARM Compiler 5 和 ARM Compiler 6 并不相同。
    在cc.h文件中引用CMSIS提供的cmsis_compiler.h文件,然后修改結構體封裝與對齊宏代碼為:

    /* Arm Compiler 4/5 */ #if defined ( __CC_ARM )#define PACK_STRUCT_BEGIN __packed#define PACK_STRUCT_STRUCT#define PACK_STRUCT_END#define PACK_STRUCT_FIELD(fld) fld#define ALIGNED(n) __ALIGNED(n)/* Arm Compiler above 6.10.1 (armclang) */ #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)#define PACK_STRUCT_BEGIN#define PACK_STRUCT_STRUCT __PACKED#define PACK_STRUCT_END#define PACK_STRUCT_FIELD(fld) fld#define ALIGNED(n) __ALIGNED(n)/* GNU Compiler */ #elif defined ( __GNUC__ )#define PACK_STRUCT_BEGIN#define PACK_STRUCT_STRUCT __PACKED#define PACK_STRUCT_END#define PACK_STRUCT_FIELD(fld) fld#define ALIGNED(n) __ALIGNED(n)#else#error "Unsupported compiler" #endif
  • 程序中使用了__packed、__align(n)、__inline、__weak的地方分別用CMSIS提供的宏__PACKED、__ALIGNED(n)、__INLINE、__WEAK代替。

    注意__packed和__attribute__((packed))的使用區別:

    ARM Compiler 5 使用__packed:

    typedef __packed struct {char x; int y; } X;

    ARM Compiler 6 使用__attribute__((packed)):

    typedef struct __attribute__((packed)) {char x; int y; } X;
  • 如果使用ARM Compiler 5 時習慣使用typedef __packed struct {}X; 句法,推薦改為CMSIS提供的宏句法:typedef __PACKED_STRUCT {}X;

    當使用ARM Compiler 5 時會自動擴展為:typedef __packed struct {}X;

    當使用ARM Compiler 6 時會自動擴展為:typedef struct __attribute__((packed)) {}X;

  • 如果使用內聯函數建議按照以下格式:

    __STATIC_INLINE func_name(arg) {//函數體 }

    防止ARM Compiler 6在-O0、-O1級別設置下,鏈接時出現未定義符號的錯誤。(在這種優化級別下__INLINE可能并不會內聯)

  • 不兼容的語言擴展總結如下:

    ARM Compiler 5ARM Compiler 6CMSIS(推薦)
    __align(x)__attribute__((aligned(x)))__ALIGNED(x)
    __alignof____alignof__
    __ALIGNOF____alignof__
    __asm匯編遷移__ASM
    __const__attribute__((const))
    __forceinline__attribute__((always_inline))
    __global_reg不支持
    __inline__inline__ 此功能使用取決于語言模式__INLINE
    __STATIC_INLINE
    __int64沒有對等選項.使用 long longint64_t
    __irq__attribute__((interrupt))Cortex-M ISR不需要此關鍵字
    __packed
    __packed x struct
    __attribute__((packed))
    struct x attribute((packed))
    __PACKED
    __PACKED_STRUCT x
    __pure__attribute__((const))
    __smc不支持,使用內聯匯編或等效程序
    __softfp__attribute__((pcs(“aapcs”)))
    __svc不支持,使用內聯匯編或等效程序
    __svc_indirect不支持,使用內聯匯編或等效程序
    __thread__thread
    __value_in_regs__attribute__((value_in_regs))
    __weak__attribute__((weak))__WEAK
    __writeonly不支持

    提示:可以使用uVision IDE的查找功能來查找上述關鍵字,然后做遷移處理。

    不兼容的屬性擴展:

    Arm Compiler 5 屬性Arm Compiler 6 屬性描述
    __attribute__((at(address)))__attribute__((section(".ARM.__at_address")))Arm Compiler 6 中的 armlink 仍然支持以 .ARM.__at_address 的形式放置段
    __attribute__((at(address), zero_init))__attribute__((section(".bss.ARM.__at_address")))Arm Compiler 6 中的 armlink 支持以 .bss.ARM.__at_address 的形式放置零初始化段。 .bss 前綴區分大小寫,并且必須全部小寫。
    __attribute__((section(name), zero_init))__attribute__((section(".bss.name")))name 是你選擇的名字。 .bss 前綴區分大小寫,并且必須全部小寫。
    __attribute__((zero_init))不支持
    默認將零初始化變量放在.bss 段。
    如果變量具有初始值設定項,則 Arm Compiler 5 會生成錯誤。 否則,它將零初始化變量放在 .bss段。

    點擊這里查看遷移詳細例程。

    內嵌匯編

    ARM Compiler 6 完全改變了處理匯編代碼的策略。

    匯編語法現在兼容GNU風格而不是ARM風格。 匯編也是由C編譯器完成, 無需單獨的匯編器。

  • FreeRTOS的移植層由..\FreeRTOS\Source\portable\RVDS\ARM_CM3目錄下的port.c和portmacro.h文件改為..\FreeRTOS\Source\portable\GCC\ARM_CM3目錄下的port.c和portmacro.h文件。

    這是因為這兩個文件會涉及內嵌匯編。

  • 自定義的內嵌匯編函數。

    ARM Compiler 5:

    __asm uint32_t __get_flash_base(void) {IMPORT |Image$$ER_IROM1$$RO$$Base|;ldr r0,=|Image$$ER_IROM1$$RO$$Base|;bx lr; }

    ARM Compiler 6:(看了下幫助手冊,也可以不使用匯編)

    uint32_t get_flash_base(void) {extern uint32_t Image$$ER_IROM1$$RO$$Base;return (uint32_t)&Image$$ER_IROM1$$RO$$Base; }
  • 語法更嚴格

  • 比如某個函數之前要對外開放,.c和.h中定義和聲明都相同。后來在.c文件中將該函數定義為本地函數,使用static修飾,但.h中忘記刪除也沒有做相應修改。這種情況下,ARM Compiler 5 不會報錯,ARM Compiler 6 會報錯:

    ../file_name.c(10): error: static declaration of 'func_name' follows non-static declaration

  • 如下代碼:

    for(i=0; i<0x7E-0x20; i++)

    ARM Compiler 5 不會報錯,ARM Compiler 6 會報錯:

    ../file_name.c(332): error: invalid suffix '-0x20' on integer constant

    需要將代碼改為:

    for(i=0; i<0x7E - 0x20; i++)
  • 優化問題

    以下代碼在 ARM Compiler 5 中,正常執行,但在 ARM Compiler 6 中,只要不是-O0級別,整個函數因為空循環問題,都被優化掉。也就是延時沒有起作用。

    void delay_us (uint32_t ul_time) {ul_time *= 30; while(--ul_time != 0); }

    這個函數不會修改自己范圍之外的資源,所以編譯器認為這段是無副作用(no side-effect)的代碼,可以通俗的理解為沒什么作用的代碼。對于這樣的代碼,編譯器有可能會優化掉他們。

    有副作用的函數的特點:

    • 修改了全局變量
    • 修改了參數引用的變量
    • 調用其它有副作用的函數
    • 操作了 volatile 修飾的變量
    • 內嵌了匯編或 __NOP()指令

    所以當升級到 ARM Compiler 6 出現使用軟延時的外設不工作,比如軟件IIC出錯、軟件SPI出錯、LCD黑屏等問題,可以檢查是否有類似的代碼。

    需要改成:

    void delay_us (uint32_t ul_time) {ul_time *= 30; while(--ul_time != 0)__nop(); }

    Keil編譯器保證__nop()必定會插入一個NOP指令,在這里可以阻止編譯器優化。當然,延時的初始值也要做相應的調整。

    或者改成:

    void delay_us (volatile uint32_t ul_time) {ul_time *= 30; while(--ul_time != 0); }

    通過關鍵字 volatile 來禁止編譯器優化。

    編譯時間和大小

    • -O0:Program Size: Code=200360 RO-data=20576 RW-data=96 ZI-data=76316
      Build Time Elapsed: 00:00:25

    • -O1:Program Size: Code=119328 RO-data=16824 RW-data=96 ZI-data=76300
      Build Time Elapsed: 00:00:25

    • -O2:Program Size: Code=153340 RO-data=17100 RW-data=96 ZI-data=76300
      Build Time Elapsed: 00:00:26

    • -O3:Program Size: Code=162292 RO-data=17040 RW-data=96 ZI-data=76308
      Build Time Elapsed: 00:00:27

    • -Ofast:Program Size: Code=161896 RO-data=17040 RW-data=96 ZI-data=76308
      Build Time Elapsed: 00:00:26

    • -Os balanced:Program Size: Code=115628 RO-data=17048 RW-data=96 ZI-data=76300
      Build Time Elapsed: 00:00:28

    • -Oz image size:Program Size: Code=103784 RO-data=17020 RW-data=96 ZI-data=76308
      Build Time Elapsed: 00:00:25

    • -Oz image size LTO:Program Size: Code=85888 RO-data=17064 RW-data=40 ZI-data=75960
      Build Time Elapsed: 00:00:32

    與Compiler 5 對比(我的程序-可能不具有一般性):

    • -O2:Program Size: Code=94232 RO-data=16736 RW-data=540 ZI-data=75640
      Build Time Elapsed: 00:00:16

    參考文檔

    • 《Arm? Compiler Migration and Compatibility Guide》(內容詳細)
    • 《Migrate ARM Compiler 5 to ARM Compiler 6》 (AN298)






    讀后有收獲,資助博主養娃 - 千金難買知識,但可以買好多奶粉 (〃‘▽’〃)

    總結

    以上是生活随笔為你收集整理的从 Arm Compiler 5 迁移到 Arm Compiler 6的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。