STM32 + GCC v8 + Qt Creator + Qbs: сбой в __libc_init_array - PullRequest
0 голосов
/ 17 мая 2019

После обновления моего хост-компьютера до более новой версии 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 - это STM32L476RG, Cortex-M4, ARM v7e-m, с FPU.В папке установки 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 голосов
/ 18 мая 2019

Проблема заключалась в том, что более новая версия Qbs, которую я получил (v1.12.1), достаточно умна, чтобы добавить «-Wl» ко всем параметрам в cpp.linkerFlags ... Решение состоит в том, чтобы установить флаги, необходимые для компиляции AND ссылка в разделе 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
}
}

...