0

将我的主机 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 创建者
  • 构建系统:Qbs(Qt 的工具)

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

|------------|------------------------------------ --------|--------------|
| 皮质-M4 | -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp | 拇指 |
| (软FP)| -mfpu=fpv4-sp-d16 | /v7e-m+fp |
| |--------------------------------------------| /softfp |
| | -mthumb -march=armv7e-m -mfloat-abi=softfp | |
| | -mfpu=fpv4-sp-d16 | |
|------------|------------------------------------ --------|--------------|
| 皮质-M4 | -mthumb -mcpu=cortex-m4 -mfloat-abi=hard | 拇指 |
| (硬FP)| -mfpu=fpv4-sp-d16 | /v7e-m+fp |
| |--------------------------------------------| /硬 |
| | -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-Lflag 结合使用,但没有效果。即使我省略它也会编译-L,但根据 GCC 手册页,它不应该。

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

4

1 回答 1

0

问题是我得到的较新版本的 Qbs (v1.12.1) 足够聪明,可以在...下的所有选项前加上“-Wl” 。解决方案是在一个部分cpp.linkerFlags中设置编译和链接所需的标志。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
}
}

于 2019-05-18T10:19:46.643 回答