一、keil5工程介绍
1、工程创建
使用keil5创建stm32工程这种界面化的方式对于初学者来说比较友好,创建步骤网上已经有很多了,主要是选择芯片型号、勾选外设库、工程下载配置、创建自己的代码等;
使用keil创建工程隐藏了一些细节,比如链接文件的生成是由工程配置自动生成的,启动脚本也是根据选择的芯片型号自动选择的;
最新的工具可以生成更多的初始化代码使开发更加便捷;
2、工程组成
芯片启动文件、芯片寄存器头文件、芯片内核文件core_xxx.h 、外设库文件、自己开发的项目代码文件、不易看到的文件(链接文件由工程配置后产生、编译控制文件集成开发环境自己控制编译)
二、cmake管理的工程介绍
1、cmake工程组成
2、安装工具
已经安装好ubuntu环境;
cmake安装:sudo apt-get install cmake;
编译工具链安装:
下载gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2;
配置/etc/profile中添加
export ARM_GCC_HOME=/usr/gcc-arm-none-eabi-9-2019-q4-major
PATH=/usr/gcc-arm-none-eabi-9-2019-q4-major/bin:$PATH
3、cmake编译文本编写
以下实例包含CMakelist.txt,对于自己的项目可以根据自己的代码添加源文件、头文件、根据平台更换启动文件,链接文件,库文件源码即可
4、cmake实例工程
源码: 见压缩包资源 stm32工程改造成cmake的工程demo.tar.gz
工程使用方法:
解压后mkdir build ,cd build ,cmake . . ,make 即可生成执行文件;
CMakelist.txt文件内容:
# CMake minimum version
cmake_minimum_required (VERSION 2.8.7)
function(redefine_file_macro targetname)
get_target_property(source_files "${targetname}" SOURCES)
foreach(sourcefile ${source_files})
get_property(defs SOURCE "${sourcefile}"
PROPERTY COMPILE_DEFINITIONS)
get_filename_component(filepath "${sourcefile}" ABSOLUTE)
string(REPLACE ${PROJECT_SOURCE_DIR}/ "" relpath ${filepath})
list(APPEND defs "__FILE__=\"${relpath}\"")
set_property(
SOURCE "${sourcefile}"
PROPERTY COMPILE_DEFINITIONS ${defs}
)
endforeach()
endfunction()
# Project Infomation 根据项目情况修改生成的执行文件的名字
project( App )
enable_language(ASM)
enable_language(C)
add_definitions(-Wno-builtin-macro-redefined)
# Reset output path
set (EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set (LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
# STDLIB
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS)
# Set include path 根据自己的项目修改此部分源文件目录
include_directories (./Libraries/CMSIS/CM3/CoreSupport)
include_directories (./Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x)
include_directories (./Libraries/STM32F10x_StdPeriph_Driver/inc)
include_directories (./ProjectCode)
# The need build source path and build all files 根据自己的项目修改此部分头文件目录
aux_source_directory (./Libraries/CMSIS/CM3/CoreSupport SRC_CM3)
aux_source_directory (./Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x SRC_STDEV)
aux_source_directory (./Libraries/STM32F10x_StdPeriph_Driver/src SRC_STDLIB)
aux_source_directory (./ProjectCode SRC_PRO)
set (SRC_STARTUP ./Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/TrueSTUDIO/startup_stm32f10x_hd.s) #g 根据项目情况修改此部分启动文件
set_source_files_properties(./Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/TrueSTUDIO/startup_stm32f10x_hd.s PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp")
set(SRC_LIST
${SRC_CM3}
${SRC_STDEV}
${SRC_STDLIB}
${SRC_PRO}
${SRC_STARTUP}
)
set(CROSS_TARGET_TRIPLET "arm-none-eabi-")
# CC AR LD AS
set(CMAKE_C_COMPILER "${CROSS_TARGET_TRIPLET}gcc")
set(CMAKE_ASM_COMPILER "${CROSS_TARGET_TRIPLET}gcc")
# CFLAGS
set (CMAKE_C_FLAGS " -g -Os -Wall -fdata-sections -ffunction-sections --specs=nosys.specs --specs=nano.specs -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp" CACHE INTERNAL "c compiler flags")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D USE_STDPERIPH_DRIVER -D STM32F10X_HD -D APP -D DEBUG ")
# CXXFLAGS
set (CMAKE_CXX_FLAGS "-g -Wextra -Wshadow -Wredundant-decls -Weffc++ -fno-common -ffunction-sections -fdata-sections -MD -Wall -Wundef -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp" CACHE INTERNAL "cxx compiler flags")
# ASMFLAGS
set (CMAKE_ASM_FLAGS "-g -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp" CACHE INTERNAL "asm compiler flags")
# LDFLAGS
set (CMAKE_EXE_LINKER_FLAGS "-g -Wl,--gc-sections,-Map=App.map -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp" CACHE INTERNAL "executable linker flags")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T ${CMAKE_SOURCE_DIR}/STM32FLASH.ld")
# Generate the target
add_executable (${CMAKE_PROJECT_NAME}.elf ${SRC_LIST})
redefine_file_macro(${CMAKE_PROJECT_NAME}.elf)
# Link the library to the target
target_link_libraries (${CMAKE_PROJECT_NAME}.elf -lc -lm -lnosys)
# Generate the binary file
add_custom_target (${CMAKE_PROJECT_NAME}.bin ALL arm-none-eabi-objcopy -Obinary "${EXECUTABLE_OUTPUT_PATH}/${CMAKE_PROJECT_NAME}.elf" "${EXECUTABLE_OUTPUT_PATH}/${CMAKE_PROJECT_NAME}.bin" DEPENDS ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_PROJECT_NAME}.elf)
# Generate the hex file
add_custom_target (${CMAKE_PROJECT_NAME}.hex ALL arm-none-eabi-objcopy -Oihex "${EXECUTABLE_OUTPUT_PATH}/${CMAKE_PROJECT_NAME}.elf" "${EXECUTABLE_OUTPUT_PATH}/${CMAKE_PROJECT_NAME}.hex" DEPENDS ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_PROJECT_NAME}.elf)
# Echo the size Infomation
add_custom_target (size ALL arm-none-eabi-size "${EXECUTABLE_OUTPUT_PATH}/${CMAKE_PROJECT_NAME}.elf" DEPENDS ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_PROJECT_NAME}.elf)
# Make flash to the board by st-link
#add_custom_target (flash COMMAND st-flash write ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_PROJECT_NAME}.bin 0x8000000)
# Make clean-all
add_custom_target (clean-all COMMAND rm -rf ${CMAKE_BINARY_DIR}/*)
三、两种工程优缺点
keil工程界面更好,但是由于隐藏了编译细节对于编译过程,编译原理的理解不太直接;
cmake工程虽然不是界面化的,但是更轻量,有助于理解编译过程的细节,工作几年的人一般更喜欢用命令行;