我已参考Github上的issue,但仍旧需要帮助。
我的ThreadX工程由CubeMX生成,配置如下图。

在编译时我将 assembler 改为 arm-auto ,因此我没有遇到问题。
再按照github上的issue,我将keil编译成功的startup_stm32f407xx.o添加至工程,并将原先的startup_stm32f407xx.s exclude,如下图。

然而最后在链接时出错,如下

由于本人水平有限,不懂汇编,因此不是很理解该错误的原因。

版本信息:
stm32f4 Package 版本 1.26.2
cubemx 版本 6.4.0

@admin 望能提供帮助,非常感谢。

  • admin replied to this.
  • Luchenxu

    我看了一下,出错的文件是 ../Core/Src/tx_initialize_low_level.s,这个文件用宏开关来适应 3 种不同的编译器 armcc, iar, gcc

    #ifdef __CC_ARM
    ...
    #endif
    
    #ifdef __IAR_SYSTEMS_ASM__
    .....
    #endif
    
    #ifdef __GNUC__
    ....
    #endif

    但这个文件的格式是 gnu 汇编格式,用 armasm 编译直接会提示语法错误,因此只能用 armclang,但 armclang 没有定义 __CC_ARM 这个宏,相反它定义了 __GNUC__

    所以真正被编译的是 __GNUC__ 分支,但你的 startup_xx.s 文件是为 armcc 编译器所准备的,里面没有 __RAM_segment_used_end__, _vectors 变量,所以最后链接时出错,提示找不到符号

    解决办法

    打开文件 ../Core/Src/tx_initialize_low_level.s

    • #ifdef __CC_ARM 改为 #if defined(__ARMCC_VERSION) && defined(__ASSEMBLER__)

    • #ifdef __GNUC__ 改为 #if !defined(__ARMCC_VERSION) && defined(__GNUC__)

    这样分支判断条件才是正确的,改完后编译即可

    Luchenxu

    arm-auto 就是让它自动识别 arm 格式汇编 或者 gnu 格式汇编,用来自动检测 startup_xx.s 格式决定是用 armclang 还是 armasm 来编译。勾上这个选项就OK了呀!为什么还要将 startup_xx.s 重新编译成 .o 又加到项目里呢?这不是多此一举吗?

      admin
      感谢回复。
      当使用arm-auto并编译startup.s文件时,链接依旧出错。

      github issue链接。我在顶楼贴的就是按照issue把armcc5编译的.o文件添加至工程后报的错,使用不论是arm-clang(gnu syntax)还是arm-auto都会报错,也不论使用ac6还是ac5编译得到的.o文件也会都报错。

      我也把工程贴这里。其中/MDK-ARM/startup_stm32f407xx.oac5编译后得来。/MDK-ARM/f407zg_learn/startup_stm32f407xx.oac6编译得来。

      链接:https://pan.baidu.com/s/1iVFUNDO2wBDOJ9H508TwMg
      提取码:xs8f

        Luchenxu

        我看了一下,出错的文件是 ../Core/Src/tx_initialize_low_level.s,这个文件用宏开关来适应 3 种不同的编译器 armcc, iar, gcc

        #ifdef __CC_ARM
        ...
        #endif
        
        #ifdef __IAR_SYSTEMS_ASM__
        .....
        #endif
        
        #ifdef __GNUC__
        ....
        #endif

        但这个文件的格式是 gnu 汇编格式,用 armasm 编译直接会提示语法错误,因此只能用 armclang,但 armclang 没有定义 __CC_ARM 这个宏,相反它定义了 __GNUC__

        所以真正被编译的是 __GNUC__ 分支,但你的 startup_xx.s 文件是为 armcc 编译器所准备的,里面没有 __RAM_segment_used_end__, _vectors 变量,所以最后链接时出错,提示找不到符号

        解决办法

        打开文件 ../Core/Src/tx_initialize_low_level.s

        • #ifdef __CC_ARM 改为 #if defined(__ARMCC_VERSION) && defined(__ASSEMBLER__)

        • #ifdef __GNUC__ 改为 #if !defined(__ARMCC_VERSION) && defined(__GNUC__)

        这样分支判断条件才是正确的,改完后编译即可

        Luchenxu

        我已参考Github上的issue ... ,再按照github上的issue,我将keil编译成功的startup_stm32f407xx.o添加至工程,并将原先的startup_stm32f407xx.s exclude,如下图。

        这个 issuse 提出的时候,那时候 eide 还没有 arm-auto 这个选项,所以只能自己编译后,将 .o 放进去;后面增加了 arm-auto 选项,就是为了解决这个问题,因此现在不用这么做了

          明白了,已经编译成功,感谢帮助。

          2 months later
          2 years later

          可以在EIDE里添加arm-clang(arm syntax)吗? admin

          25 days later

          yono 我试过这样做了,还是编译失败,还是得将 #ifdef CC_ARM 改为 #if defined(ARMCC_VERSION) && defined(ASSEMBLER)才能顺利编译

          • yono replied to this.

            TP-Thread 因为我也在研究threadX,我这边的tx_initialize_low_level.s都是从官方库包里面拉的,整个软件包都没有(ARMCC_VERSION)相关的代码,挺好奇的。如果方便的话,可以把工程分析给我学习一下吗?Yono233@outlook.com非常感谢

              yono 可以,不过我这个工程是使用CubeMX生成的

              TP-Thread

              你这个勾选框最终决定的是这个参数的值,你在 keil 上选好,然后看一下这个 -masm= 的值是多少

              然后把 -masm=值 填到eide的汇编器选项里就行了,你填的值会覆盖掉勾选框产生的值