欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Win10 VS Code + CMake STM32开发环境

程序员文章站 2024-02-24 12:54:16
...

Win10 VS Code + CMake STM32开发环境

软件

软件安装与环境变量的配置不多讲,这步都搞不定还是老老实实用MDK把

  • VS Code
  • cmake 插件、
  • c/c++ 插件
  • mingw
  • gcc-arm-none-eabi 或者 armclang

win 下CMake的坑

  • 工具包的选择
    一开始在Linux下,选择gcc,编译都OK。到win10下,选择mingw,死活通不过,把程序当成windows的程序了。搜索良久,发现选择未指定,会自动配置,编译就OK了。

  • CMAKE_SYSTEM_NAME
    接上门的坑。CMAKE_SYSTEM_NAME不设定好,CMAKE自动配置就不行····,所以要自动配置要设置好。set(CMAKE_SYSTEM_NAME Generic) 置顶,放在CMakeLists.txt 第一行!

  • gcc与armclang的差异
    .s启动文件不一样
    gcc生成文件需要目标名称带.elf
    armclang会在目标后面自动添加.elf
    armclang的hex bin 使用fromelf

工具链

我这里把gcc-arm-none-eabi加入了环境变量,所以没带路径

# specify the cross compiler
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
set(CMAKE_OBJDUMP arm-none-eabi-objdump)
# find additional toolchain executables
find_program(ARM_SIZE_EXECUTABLE arm-none-eabi-size)
find_program(ARM_GDB_EXECUTABLE arm-none-eabi-gdb)
find_program(ARM_OBJCOPY_EXECUTABLE arm-none-eabi-objcopy)
find_program(ARM_OBJDUMP_EXECUTABLE arm-none-eabi-objdump)

set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

# search for program/library/include in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

编译参数

参考cubemax生产的makefile 里的参数配置就行

set(MCU_FLAGS "-mcpu=cortex-m0plus -mthumb ${FPU} ${FLOAT_ABI}")
# compiler: language specific flags CFLAGS
set(CMAKE_C_FLAGS "${MCU_FLAGS} -std=gnu99 -Wall -fdata-sections -ffunction-sections ${DBG_FLAGS} " CACHE INTERNAL "C compiler flags")
#CPP 
set(CMAKE_CXX_FLAGS "${MCU_FLAGS} -fno-rtti -fno-exceptions -fno-builtin -Wall -fdata-sections -ffunction-sections ${DBG_FLAGS} " CACHE INTERNAL "Cxx compiler flags")
#ASFLAGS
set(CMAKE_ASM_FLAGS "${MCU_FLAGS} -x assembler-with-cpp ${DBG_FLAGS} " CACHE INTERNAL "ASM compiler flags")
#LDFLAGS -mcpu=cortex-m0plus -mthumb
set(CMAKE_EXE_LINKER_FLAGS "${MCU_FLAGS} -specs=nano.specs -T${LINKER_SCRIPT} -Wl,-Map=${PROJECT_NAME}.map,--cref -Wl,--gc-sections" CACHE INTERNAL "Exe linker flags")
#要链接的库 对应makefile的 LIBS
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-lc -lm -lnosys" CACHE INTERNAL "Shared linker flags")

上代码

CMakeLists.txt


set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus)
#cmake最低版本
cmake_minimum_required(VERSION 3.1.0)

#工程名称
project(ETC_974 C CXX ASM)
set(target "${PROJECT_NAME}")
set(COMPILE_TOOLS  GCC)


#编译工具
set(CROSS_COMPILE_PREFIX arm-none-eabi)
include(target-def.cmake)




# STM32CubeMX generated source files
set(CUBEMX_SRC
Core/Src/main.c
Core/Src/stm32g0xx_it.c
Core/Src/stm32g0xx_hal_msp.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_adc.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_adc_ex.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_ll_adc.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rcc.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rcc_ex.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_ll_rcc.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_flash.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_flash_ex.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_gpio.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_dma.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_dma_ex.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_ll_dma.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_pwr.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_pwr_ex.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_cortex.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_exti.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_tim.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_tim_ex.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_uart.c
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_uart_ex.c
Core/Src/system_stm32g0xx.c  
startup_stm32g030xx.s
)

include_directories(
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Core/Inc>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Drivers/STM32G0xx_HAL_Driver/Inc>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Drivers/STM32G0xx_HAL_Driver/Inc/Legacy>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Device/ST/STM32G0xx/Include>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Include>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/user/inc>

)

add_subdirectory(user)
#先定义target 才可以添加define include
add_executable(${target} ${CUBEMX_SRC})

target_link_libraries(${target} user)

target-def.cmake

# specify the cross compiler
set(CMAKE_C_COMPILER ${CROSS_COMPILE_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${CROSS_COMPILE_PREFIX}-g++)
set(CMAKE_ASM_COMPILER ${CROSS_COMPILE_PREFIX}-gcc)
set(CMAKE_OBJCOPY ${CROSS_COMPILE_PREFIX}-objcopy)
set(CMAKE_OBJDUMP ${CROSS_COMPILE_PREFIX}-objdump)
# find additional toolchain executables
find_program(ARM_SIZE_EXECUTABLE ${CROSS_COMPILE_PREFIX}-size)
find_program(ARM_GDB_EXECUTABLE ${CROSS_COMPILE_PREFIX}-gdb)
find_program(ARM_OBJCOPY_EXECUTABLE ${CROSS_COMPILE_PREFIX}-objcopy)
find_program(ARM_OBJDUMP_EXECUTABLE ${CROSS_COMPILE_PREFIX}-objdump)

set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

# search for program/library/include in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# Target-specific flags
#型号
set(MCU_FAMILY STM32G030xx)
#布局文件
set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/STM32G030K6Tx_FLASH.ld)
#内核相关
set(CPU "-mcpu=cortex-m0plus")
set(FPU "")
set(FLOAT_ABI "")



add_definitions(-D${MCU_FAMILY})

# generate flags from user variables
if(CMAKE_BUILD_TYPE MATCHES Debug)
set(DBG_FLAGS "-g3 -gdwarf-2 -O0")
elseif(CMAKE_BUILD_TYPE MATCHES Release)
set(DBG_FLAGS "-O3")
endif()

set(MCU_FLAGS "-mcpu=cortex-m0plus -mthumb ${FPU} ${FLOAT_ABI}")
# compiler: language specific flags CFLAGS
set(CMAKE_C_FLAGS "${MCU_FLAGS} -std=gnu99 -Wall -fdata-sections -ffunction-sections ${DBG_FLAGS} " CACHE INTERNAL "C compiler flags")
#CPP 
set(CMAKE_CXX_FLAGS "${MCU_FLAGS} -fno-rtti -fno-exceptions -fno-builtin -Wall -fdata-sections -ffunction-sections ${DBG_FLAGS} " CACHE INTERNAL "Cxx compiler flags")
#ASFLAGS
set(CMAKE_ASM_FLAGS "${MCU_FLAGS} -x assembler-with-cpp ${DBG_FLAGS} " CACHE INTERNAL "ASM compiler flags")
#LDFLAGS -mcpu=cortex-m0plus -mthumb
set(CMAKE_EXE_LINKER_FLAGS "${MCU_FLAGS} -specs=nano.specs -T${LINKER_SCRIPT} -Wl,-Map=${PROJECT_NAME}.map,--cref -Wl,--gc-sections" CACHE INTERNAL "Exe linker flags")
#要链接的库 对应makefile的 LIBS
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-lc -lm -lnosys" CACHE INTERNAL "Shared linker flags")

armclang

armclang 编译完体积要比gcc小不少,所以一定情况下还是需要用到的

    #编译工具
    #set(CROSS_COMPILE_PREFIX C:/Keil_v5/ARM/ARMCLANG/bin/)
    #include(target-def_armclang.cmake)
    #设置Sections脚本路径
    #CMSIS_SetSectionsScriptPath(${CMAKE_HOME_DIRECTORY}/ETC-974.sct)
    #配置交叉编译
    #CMSIS_CrossCompilingConfiguration()
#设置CMake最低支持版本
cmake_minimum_required(VERSION 3.1.0)

#交叉编译:设置目标机器类型
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus)

#设置编译器
set(CMAKE_C_COMPILER ${CROSS_COMPILE_PREFIX}armclang.exe)
set(CMAKE_CXX_COMPILER ${CROSS_COMPILE_PREFIX}armclang.exe)
set(CMAKE_ASM_COMPILER ${CROSS_COMPILE_PREFIX}armclang.exe)
set(CMAKE_C_COMPILER_WORKS TRUE)
set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_ASM_COMPILER_WORKS TRUE)

#设置链接器
set(CMAKE_C_LINK_EXECUTABLE ${CROSS_COMPILE_PREFIX}armlink.exe)
set(CMAKE_CXX_LINK_EXECUTABLE ${CROSS_COMPILE_PREFIX}armlink.exe)
set(CMAKE_ASM_LINK_EXECUTABLE ${CROSS_COMPILE_PREFIX}armlink.exe)

add_definitions(-DSTM32G030xx -DUSE_HAL_DRIVER -D_RTE_ -D__MICROLIB)


#接口:设置Sections脚本
function(CMSIS_SetSectionsScriptPath path)
    set(SECTIONS_SCRIPT_PATH ${path} CACHE STRING "global")
endfunction()

# generate flags from user variables
if(CMAKE_BUILD_TYPE MATCHES Debug)
set(DBG_FLAGS "-O0")
elseif(CMAKE_BUILD_TYPE MATCHES Release)
set(DBG_FLAGS "-O3")
elseif(CMAKE_BUILD_TYPE MATCHES MinSizeRel)
set(DBG_FLAGS "-Oz")
elseif(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
set(DBG_FLAGS "-Ofast")
endif()



#接口:配置交叉编译
function(CMSIS_CrossCompilingConfiguration)
    #设置通用编译参数
    set(COMPILE_RULE_FLAG "--target=arm-arm-none-eabi -mcpu=${CMAKE_SYSTEM_PROCESSOR}")

    #设置C编译器选项
    set(CMAKE_C_FLAGS_INIT "  ${COMPILE_RULE_FLAG} -fno-rtti -c -ffunction-sections ${DBG_FLAGS} -w" CACHE STRING "global")

    #设置C++编译器选项
    set(CMAKE_CXX_FLAGS_INIT ${CMAKE_C_FLAGS_INIT} CACHE STRING "global")

    #设置ASM编译器选项
    set(CMAKE_ASM_FLAGS_INIT " ${COMPILE_RULE_FLAG} -masm=auto -c -gdwarf-3 " CACHE STRING "global")

    #判断链接脚本是否存在
    if (NOT SECTIONS_SCRIPT_PATH)
        message(FATAL_ERROR "You not set SECTIONS_SCRIPT_PATH!")
    endif ()

    #设置链接选项
    set(CMAKE_EXE_LINKER_FLAGS_INIT "\
        --cpu=Cortex-M0+ \
        --strict \
        --scatter ${SECTIONS_SCRIPT_PATH} \
        --summary_stderr \
        --info summarysizes \
        --map --load_addr_map_info --xref --callgraph --symbols \
        --info sizes --info totals --info unused --info veneers \
    " CACHE STRING "global")

    #使能汇编
    enable_language(ASM)

endfunction()

function(CMSIS_hex)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
        COMMAND ${CROSS_COMPILE_PREFIX}fromelf.exe --i32 -o ${PROJECT_NAME}.hex ${PROJECT_NAME}.elf
        COMMAND ${CROSS_COMPILE_PREFIX}fromelf.exe --bin -o ${PROJECT_NAME}.bin ${PROJECT_NAME}.elf )
endfunction()

参考文章