STM32 + GCC v8 + Qt Creator + Qbs:__libc_init_array

时间:2019-05-17 08:59:41

标签: gcc arm qt-creator stm32 thumb

将主机PC升级到较新的Linux版本后,我无法再运行项目。我只想编写一个工作的电子板的副本:硬件和代码之前已经过验证。

更准确地说,代码在_libc_init_array的启动脚本中崩溃,并跳转到BusFault_Handler()HardFault_Handler()

我在论坛上读了很多东西,似乎与链接到错误的libc风格(Thumb vs. ARM)有关。

工具:

  • 代码生成:STM32CubeMX
  • 编译器:GNU GCC版本8.2.1(8-2018-q4-major)
  • IDE:Qt Creator
  • 构建系统:Qbs(Qt的工具)

MCU是带有FPU的STM32L476RG,Cortex-M4,ARM v7e-m。在GNU GCC安装文件夹中,share/doc/gcc-arm-none-eabi/readme.txt告诉我我需要哪些标志:

|------------|--------------------------------------------|--------------|
| Cortex-M4  | -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp | thumb        |
| (Soft FP)  | -mfpu=fpv4-sp-d16                          | /v7e-m+fp    |
|            |--------------------------------------------| /softfp      |
|            | -mthumb -march=armv7e-m -mfloat-abi=softfp |              |
|            | -mfpu=fpv4-sp-d16                          |              |
|------------|--------------------------------------------|--------------|
| Cortex-M4  | -mthumb -mcpu=cortex-m4 -mfloat-abi=hard   | thumb        |
| (Hard FP)  | -mfpu=fpv4-sp-d16                          | /v7e-m+fp    |
|            |--------------------------------------------| /hard        |
|            | -mthumb -march=armv7e-m -mfloat-abi=hard   |              | 
|            | -mfpu=fpv4-sp-d16                          |              |
|------------|--------------------------------------------|--------------|

-mfloat-abi=softfp有效,-mfloat-abi=hard不起作用,但是GCC文档提示结果相同;只有调用约定不同。

这是我的Qbs文件:

import qbs

CppApplication {
    consoleApplication: true
    property string family: "STM32L4xx"
    property string linkerScript: "STM32L476RGTx_FLASH.ld"
    cpp.positionIndependentCode: false              // make sure option -fPIC is not passed to GCC
    cpp.defines: [
        "USE_HAL_DRIVER",
        "STM32L476xx",
        "__weak=__attribute__((weak))",
        "__packed=__attribute__((__packed__))"
    ]

    cpp.commonCompilerFlags: [
        "-fno-common",
        "-specs=nosys.specs",
        "-specs=nano.specs",
        "-march=armv7e-m",
        "-mcpu=cortex-m4",
        "-mthumb-interwork",                    // support ARM and Thumb instruction sets
        "-mthumb",
        "-mfloat-abi=softfp",
        "-mfpu=fpv4-sp-d16",
        "-mtune=cortex-m4",                     // tune performance of code for this processor
//        "-std=c99",
        "-ffunction-sections",
        "-fdata-sections",
//        "-Os",
        "-O0",
        "-g3",
        "-Wall",
        "-c",                                       // don't run the linker
//        "-v"                                      // print a lot of details (too much ?)
    ]
    cpp.linkerFlags: [
        "-T"+path+"/"+linkerScript,
        "--gc-sections",                            // fixes "undefined reference to _exit" error
        "-Map="+buildDirectory+"/memory.map",       // file created at the end of the link step
        "-static",
        "--verbose",                                // displays library search
//        "-lgcc",
//        "-lg",
//        "-lm"
    ]
    cpp.includePaths: [
        "Inc",
        "Drivers/CMSIS/Include",
        "Drivers/CMSIS/Device/ST/"+family+"/Include",
        "Drivers/STM32L4xx_HAL_Driver/Inc",
        "Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc",
        "Middlewares/ST/STM32_USB_Device_Library/Core/Inc/"
    ]
    files: [
        "Inc/*.h",
        linkerScript,
        "Src/*.c",
        "Drivers/CMSIS/Device/ST/"+family+"/Include/*.h",
        "Drivers/CMSIS/Device/ST/"+family+"/Source/Templates/gcc/*.s",
        "Drivers/CMSIS/Device/ST/"+family+"/Source/Templates/*.c",
        "Drivers/CMSIS/Include/*.h",
        "Drivers/"+family+"_HAL_Driver/Inc/*.h",
        "Drivers/"+family+"_HAL_Driver/Src/*.c",
        "Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/*.c",
        "Middlewares/ST/STM32_USB_Device_Library/Core/Src/*.c"
    ]

    Properties {
        condition: qbs.buildVariant === "debug"
        cpp.defines: outer.concat(["DEBUG=1"])
    }

    Group {     // Properties for the produced executable
        fileTagsFilter: product.type
        qbs.install: true
    }
}

使用链接器--verbose选项可以打印链接到的库的完整路径。并且它始终解析为arm-none-eabi/lib/libc.a。但是我本来希望arm-none-eabi/lib/thumb/v7e-m+fp/softfp/libc.a

我也尝试将链接器选项-nostdlib-L标志一起使用,但是没有效果。即使我省略-L,它也可以编译,但是根据GCC手册页,它不应该编译。

所以,我很困在这里。那5分钟的工作变成了几天...

1 个答案:

答案 0 :(得分:0)

问题是我得到的Qbs的较新版本(v1.12.1)足够聪明,可以在cpp.linkerFlags下的所有选项之前加上“ -Wl” ...解决方案是将那些标志设置为在cpp.driverFlags部分中编译并链接。

对任何人都应该有帮助,这是我目前正在使用的(-;))Qbs文件。

import qbs
CppApplication {
consoleApplication: true
property string family: "STM32L4xx"
property string linkerScript: "STM32L476RGTx_FLASH.ld"
cpp.positionIndependentCode: false              // make sure option -fPIC is not passed to GCC

// Make sure to call the linker through GCC driver :
cpp.linkerMode: "manual"        // default : "automatic"
cpp.linkerName: "gcc"           // this string is appended to "<full_path_to_toolchain>/arm-none-eabi-"

// Define some symbols (GCC -D flag)
cpp.defines: [
    "USE_HAL_DRIVER",
    "STM32L476xx",
    "__weak=__attribute__((weak))",
    "__packed=__attribute__((__packed__))"
]

// Options for compilation AND linking.
cpp.driverFlags: [
    // CPU
    "-mcpu=cortex-m4",
    "-mthumb",
    "-mfpu=fpv4-sp-d16",
    "-mfloat-abi=hard",
    "-specs=nano.specs",                  // use smaller libc
]

// Compiler flags for all langages (C, C++).
cpp.commonCompilerFlags: [
    // Optimizations
    //"-Os",
    //"-O0",
    "-Og",

    "-Wall",
    "-fdata-sections",
    "-ffunction-sections",

    // For debug
    "-g",
    "-gdwarf-2",

    "-c",                                       // don't run the linker
    //"-v"                                      // print a whole lot of details
]

// Linker flag only i.e. understood by LD !!!
// Qbs will prepend all these flags with "-Wl," so that GCC transfers them to LD.
// Other options required for linking should be set in the driverFlags section.
cpp.linkerFlags: [
    "-T"+path+"/"+linkerScript,
    "-static",
    "--verbose",                                // displays library search
    "-lc",
    "-lm",
    "-lnosys",
    "-Map="+buildDirectory+"/memory.map",       // file created at the end of the link step
    "--cref",                                   // map file formatting
    "--gc-sections",                            // enables garbage collection for unused sections
]

// Include directories.
cpp.includePaths: [
    "Inc",
    "Drivers/CMSIS/Include",
    "Drivers/CMSIS/Device/ST/"+family+"/Include",
    "Drivers/STM32L4xx_HAL_Driver/Inc",
    "Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc",
    "Middlewares/ST/STM32_USB_Device_Library/Core/Inc/"
]

// Source files.
files: [
    "Inc/*.h",
    linkerScript,
    "Src/*.c",
    "Drivers/CMSIS/Device/ST/"+family+"/Include/*.h",
    "startup/*.s",
    "Drivers/CMSIS/Device/ST/"+family+"/Source/Templates/*.c",
    "Drivers/CMSIS/Include/*.h",
    "Drivers/"+family+"_HAL_Driver/Inc/*.h",
    "Drivers/"+family+"_HAL_Driver/Src/*.c",
    "Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/*.c",
    "Middlewares/ST/STM32_USB_Device_Library/Core/Src/*.c"
]

Properties {
    condition: qbs.buildVariant === "debug"
    cpp.defines: outer.concat(["DEBUG=1"])
}

Group {     // Properties for the produced executable
    fileTagsFilter: product.type
    qbs.install: true
}
}