Проект STM32 с CMake

Я пытаюсь создать и скомпилировать проект STM32 на базе ARM с помощью CMake.

CMakeLsts.txt - это следующее:

cmake_minimum_required(VERSION 3.7)
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_VERSION 1)

# Enable logging messages
#set(CMAKE_VERBOSE_MAKEFILE ON)

# Project name
set(PROJECT_NAME FixtureTACO)
PROJECT(${PROJECT_NAME} C CXX ASM)
SET(CMAKE_CXX_STANDARD 11)

###################### CHIP CONFIGURATION ##########################
SET(ROOT_PROJ   ${CMAKE_CURRENT_SOURCE_DIR})
SET(CPU         "cortex-m4")
SET(ARCH_NAME   "arm")
SET(ARCH_VER    "v7e-m")
SET(FAMILY      "stm32f3")
SET(CHIP        "STM32F303xC")
SET(ARCH        "${ARCH_NAME}${ARCH_VER}")
####################################################################

# MCU Config
set(FPU         "-mfpu=fpv4-sp-d16")
set(FLOAT_ABI   "-mfloat-abi=hard")

# Toolchain path
set(TOOLCHAIN_PATH  "")
set(ARM_LIB         "/usr/lib/arm-none-eabi/lib/${ARCH}")
# Specify C, C++ and ASM compilers
SET(CMAKE_C_COMPILER    ${TOOLCHAIN_PATH}arm-none-eabi-gcc)
SET(CMAKE_CXX_COMPILER  ${TOOLCHAIN_PATH}arm-none-eabi-g++)
set(AS                  ${TOOLCHAIN_PATH}arm-none-eabi-as)
set(AR                  ${TOOLCHAIN_PATH}arm-none-eabi-ar)
set(OBJCOPY             ${TOOLCHAIN_PATH}arm-none-eabi-objcopy)
set(OBJDUMP             ${TOOLCHAIN_PATH}arm-none-eabi-objdump)
set(SIZE                ${TOOLCHAIN_PATH}arm-none-eabi-size)
set(GDB                 ${TOOLCHAIN_PATH}arm-none-eabi-gdb)
set(SIZE                ${TOOLCHAIN_PATH}arm-none-eabi-size)

# Definitions passed at compile time (#defines)
add_definitions(-DFAMILY=${FAMILY})
add_definitions(-DCHIP=${CHIP})
add_definitions(-D${CHIP})
add_definitions(-DUSE_FULL_LL_DRIVER)
add_definitions(-USE_HAL_DRIVER)
add_definitions(-DHSE_VALUE=8000000)
add_definitions(-DHSE_STARTUP_TIMEOUT=100)
add_definitions(-DLSE_STARTUP_TIMEOUT=5000)
add_definitions(-DLSE_VALUE=32768)
add_definitions(-DHSI_VALUE=8000000)
add_definitions(-DLSI_VALUE=40000)
add_definitions(-DDD_VALUE=3300)
add_definitions(-DPREFETCH_ENABLE=1)

# Compilation flags
add_compile_options(-mcpu=${CPU})
add_compile_options(-march=${ARCH})
add_compile_options(-mthumb)
add_compile_options(${FPU})
add_compile_options(${FLOAT_ABI})
add_compile_options(-Og)
add_compile_options(-Wall)
add_compile_options(-fdata-sections)
add_compile_options(-ffunction-sections)
# Only for debugging
add_compile_options(-g -gdwarf-2)


# Linker script path
file(GLOB_RECURSE LINKER_SCRIPT ${ROOT_PROJ}/platforms/${FAMILY}/Linker/*.ld)

# Variables initialized first time
SET(CMAKE_CXX_FLAGS_INIT "-std=c++11")
SET(CMAKE_C_FLAGS_INIT "-std=gnu99")

################################## Source code ###############################################################
# Retrieve all sources # "platforms/${FAMILY}/Startup/*.s"
file(GLOB SOURCES  "platforms/${FAMILY}/Startup/*.s" "src/*.cpp" "src/*.c" "platforms/${FAMILY}/Hal/src/*.c" "platforms/${FAMILY}/Device/*.c")
#Retrieve all locations of headers
file(GLOB_RECURSE HEADERS "includes/*.h"  "src/*.h" "platforms/${FAMILY}*.h")
set (INCLUDE_DIRS "")
foreach (_headerFile ${HEADERS})
    get_filename_component(_dir ${_headerFile} PATH)
    list (APPEND INCLUDE_DIRS ${_dir})
endforeach()
list(REMOVE_DUPLICATES INCLUDE_DIRS)
include_directories(${INCLUDE_DIRS})
link_directories(${ARM_LIB})
################################## Source code END ###########################################################

set(EXE_NAME "${PROJECT_NAME}_${CHIP}")
add_executable(${EXE_NAME}.elf ${SOURCES} ${LINKER_SCRIPT})
set(CMAKE_EXE_LINKER_FLAGS "-mcpu=${CPU} -mthumb ${FPU} ${FLOAT_ABI} --specs=nano.specs -T${LINKER_SCRIPT} -Wl,-Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map,--cref -Wl,--gc-sections")

# Libs and external dependencies
target_link_libraries(${EXE_NAME}.elf -lc -lm -lnosys)

# Outputs
set(ELF_FILE ${PROJECT_BINARY_DIR}/${EXE_NAME}.elf)
set(HEX_FILE ${PROJECT_BINARY_DIR}/${EXE_NAME}.hex)
set(BIN_FILE ${PROJECT_BINARY_DIR}/${EXE_NAME}.bin)

add_custom_command(TARGET "${EXE_NAME}.elf" POST_BUILD
        # Build .hex and .bin files
        COMMAND ${OBJCOPY} -Obinary ${ELF_FILE} ${BIN_FILE}
        COMMAND ${OBJCOPY} -Oihex  ${ELF_FILE} ${HEX_FILE}
        COMMENT "Building ${PROJECT_NAME}.bin and ${PROJECT_NAME}.hex"

        # Copy files to a custom build directory
        COMMAND ${CMAKE_COMMAND} -E copy ${ELF_FILE} "${ROOT_PROJ}/builds/${CHIP}/${EXE_NAME}.elf"
        COMMAND ${CMAKE_COMMAND} -E copy ${HEX_FILE} "${ROOT_PROJ}/builds/${CHIP}/${EXE_NAME}.hex"
        COMMAND ${CMAKE_COMMAND} -E copy ${BIN_FILE} "${ROOT_PROJ}/builds/${CHIP}/${EXE_NAME}.bin"

        # Display sizes
        COMMAND ${SIZE} --format=berkeley ${EXE_NAME}.elf ${EXE_NAME}.hex
        COMMENT "Invoking: Cross ARM GNU Print Size"
        )

add_custom_target(UPLOAD
        ${GDB} -iex "target remote tcp:127.0.0.1:3333"
        -iex "monitor program ${EXE_NAME}.elf"
        -iex "monitor reset init"
        -iex "disconnect" -iex "quit ")

Когда я пытаюсь скомпилировать, я получаю следующие ошибки:

[ 82%] Building C object CMakeFiles/FixtureTACO_STM32F303xC.elf.dir/platforms/stm32f3/Hal/src/stm32f3xx_ll_utils.c.obj
[ 86%] Building ASM object CMakeFiles/FixtureTACO_STM32F303xC.elf.dir/platforms/stm32f3/Startup/startup_stm32f303xc.s.obj
cc: warning: ‘-mcpu=’ is deprecated; use ‘-mtune=’ or ‘-march=’ instead
cc: error: unrecognized command line option ‘-mthumb’; did you mean ‘-mtbm’?
cc: error: unrecognized command line option ‘-mfpu=fpv4-sp-d16’
cc: error: unrecognized command line option ‘-mfloat-abi=hard’

Ошибка возникает ТОЛЬКО, когда файл сборки (в данном случае startup.s) присутствует в исходных файлах и когда присутствуют флаги FPU и FLOAR_ABI. Как видите, ошибка возникает при компиляции startup_stm32f303xc.s.

Я подозреваю, что добавляю эти флаги не в том месте, но понятия не имею, куда их добавить, чтобы все заработало.

Позднее редактирование: я уже установил компилятор arm 7 в свою систему ubuntu. Я могу использовать его без указания пути, так как он уже присутствует в переменных среды. Я могу без проблем скомпилировать код ARM (из Makefiles) для других целей на машине. Моя проблема с cmake.

Я предполагаю, что вам нужно использовать выражения генератора и $ <COMPILE_LANGUAGE: lang> только для добавления параметров C к компилятору C и параметров ASM к компилятору ASM. По сути, вы добавляете параметры в компилятор для обоих языков, и это то, что ломается при компиляции файла ASM.

fdk1342 17.12.2018 18:26

@Fred Я думаю, это как раз моя проблема. Не могли бы вы дать мне более подробную информацию?

caffeine 17.12.2018 22:37
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
2
4 163
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Думаю, вы попробуете скомпилировать код для ARM с помощью компилятора x86. Она не будет работать. Вам необходимо загрузить набор инструментов ARM и использовать правильный компилятор.

-mcpu не используется в ветке x86, но не в ветке ARM.

других вариантов просто нет в компиляторе x86.

Да! Это была проблема. Только компилятор ASM был опущен, остальные были в порядке.

caffeine 18.12.2018 10:40

@caffeine отличный. Но сообщение было на самом деле очевидным.

0___________ 18.12.2018 10:47

В вашей строке set(TOOLCHAIN_PATH "") вы должны добавить путь к компилятору. Сначала получите бесплатный GCC ARM ToolChain. Загрузите для своей ОС. а затем просто скопируйте в свое любимое место. Если вы используете Linux, вы можете использовать мои конфигурации пути: 1.) Скопируйте gcc arm compirel в каталог / opt /:

sudo tar xjfv ~/Downloads/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2 -C /opt/

Для более «сексуального» пути можно сделать символическую ссылку:

sudo ln -s /opt/gcc-arm-none-eabi-7-2018-q2-update/  /opt/gcc-arm-none-eabi

После этого перейдите в свой CMakeLists.txt и перепишите команду set следующим образом:

set(TOOLCHAIN_PATH  "/opt/gcc-arm-none-eabi/bin")

Но есть лучшее решение для создания вашего проекта для STM32, но с уже готовым проектом шаблона stm32-cmake, специально созданным для семейства STM32. Это намного легче сделать, если что-то работает. Вам также потребуются два предварительных требования: STM32CubeMX и снова GCC ARM ToolChain. Если вы хотите узнать, как использовать этот шаблон, просто напишите мне, и я дам вам краткое руководство.

Вы не «устанавливаете» инструментальную цепочку, вы просто копируете файлы в один каталог. Если у вас уже есть файлы toolchian, добавьте путь в свой код, добавьте set(TOOLCHAIN_PATH "path/to/your/toolchain/bin")

user45189 18.12.2018 10:12
Ответ принят как подходящий

Хорошо, наконец-то я разобрался!

Мне пришлось заменить

set(AS ${TOOLCHAIN_PATH}arm-none-eabi-as)

с участием

set(CMAKE_ASM_COMPILER  ${TOOLCHAIN_PATH}arm-none-eabi-gcc)

Это не ошибка, это компилятор gcc. Вы также можете добавить эти флаги: -x assembler-with-cpp.

CMake не знал о моем пользовательском компиляторе ASM, поэтому он использовал системный компилятор ASM по умолчанию, если я не заставлю его написать CMAKE_ASM_COMPILER. Сейчас проект строится и отлично работает на микроконтроллере.

Остальные ответы были нормальными, но у них была половина решения. Только файлы ASM были скомпилированы с неправильным компилятором.

Другие вопросы по теме