建立网站目录的意义,wordpress申请表单,ssh框架可以做网站么,免费seo网站优化文章目录 1 必须文件2 工具链3 CLion 全局配置4 CLion 新项目配置ST-Link 调试 5 点亮 LED6 分析 elf 文件7 项目模板 1 必须文件
ST 提供的头文件支持 MDK-ARM, GCC, IAR 3种编译器, 下面采用 GCC
编译器 Arm GNU Toolchain Downloads – Arm Developer 或 安装包版 调试器服… 文章目录 1 必须文件2 工具链3 CLion 全局配置4 CLion 新项目配置ST-Link 调试 5 点亮 LED6 分析 elf 文件7 项目模板 1 必须文件
ST 提供的头文件支持 MDK-ARM, GCC, IAR 3种编译器, 下面采用 GCC
编译器 Arm GNU Toolchain Downloads – Arm Developer 或 安装包版 调试器服务端 OpenOCD 基础头文件仓库 STMicroelectronics/cmsis-core F1头文件仓库 STMicroelectronics/cmsis-device-f1 F1头文件仓库 STMicroelectronics/stm32f1xx-hal-driver 外设 SVD 文件 stm32 svd
上述所有项目拉取/解压/解包后各自一个文件夹放在 stm32kits 中
2 工具链
新建 stm32kits/cmake/startup.bat, 内容如下
set CMAKE_TOOLCHAIN_FILE%~dp0arm.toolchain.cmake新建 stm32kits/cmake/arm.toolchain.cmake, 内容如下
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)set(CMAKE_C_COMPILER_ID GNU)
set(CMAKE_CXX_COMPILER_ID GNU)set(CMAKE_EXECUTABLE_SUFFIX_ASM .elf)
set(CMAKE_EXECUTABLE_SUFFIX_C .elf)
set(CMAKE_EXECUTABLE_SUFFIX_CXX .elf)set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)set(STM32_KITS_DIR ${CMAKE_CURRENT_LIST_DIR}/..)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH};${CMAKE_CURRENT_LIST_DIR})# MCU specific flags
set(TARGET_FLAGS -mcpucortex-m3 )set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} ${TARGET_FLAGS})
set(CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS} -x assembler-with-cpp -MMD -MP)
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -Wall -Wextra -Wpedantic -fdata-sections -ffunction-sections -Wl,--no-warn-rwx-segments)set(CMAKE_C_FLAGS_DEBUG -O0 -g3)
set(CMAKE_C_FLAGS_RELEASE -Os -g0)
set(CMAKE_CXX_FLAGS_DEBUG -O0 -g3)
set(CMAKE_CXX_FLAGS_RELEASE -Os -g0)set(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions -fno-threadsafe-statics)set(CMAKE_C_LINK_FLAGS ${TARGET_FLAGS})
set(CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS} --specsnano.specs)
set(CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS} -Wl,-Map${CMAKE_PROJECT_NAME}.map -Wl,--gc-sections)
set(CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS} -Wl,--start-group -lc -lm -Wl,--end-group)
set(CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS} -Wl,--print-memory-usage)set(CMAKE_CXX_LINK_FLAGS ${CMAKE_C_LINK_FLAGS} -Wl,--start-group -lstdc -lsupc -Wl,--end-group)新建 stm32kits/cmake/FindSTM32Driver.cmake, 内容如下
function(stm32_parse_mcu_name MCU_NAME)string(TOUPPER ${MCU_NAME} MCU_NAME_UPPER)if(NOT MCU_NAME_UPPER MATCHES ^STM32([C|F|G|H|L|M|N|U|W][A-Z0-9][A-Z0-9]?[A-Z0-9]?)([0-9][0-9])([A-Z])([0-9A-IZ])([BDG-KMPQTUVY]?)([6A7B3CD]?)$)set(STM32Driver_FOUND PARENT_SCOPE)return()endif()string(TOLOWER ${CMAKE_MATCH_1} MATCH_1_LOWER)SET(MCU_SERIES_VARIANT_LOWER ${MATCH_1_LOWER} PARENT_SCOPE)SET(MCU_SERIES_VARIANT ${CMAKE_MATCH_1} PARENT_SCOPE)SET(MCU_VARIANT ${CMAKE_MATCH_2} PARENT_SCOPE)SET(MCU_PIN_COUNT ${CMAKE_MATCH_3} PARENT_SCOPE)string(TOLOWER ${CMAKE_MATCH_4} CMAKE_MATCH_4_LOWER)SET(MCU_FLASH_LOWER ${CMAKE_MATCH_4_LOWER} PARENT_SCOPE)SET(MCU_FLASH ${CMAKE_MATCH_4} PARENT_SCOPE)SET(MCU_PACKAGE ${CMAKE_MATCH_5} PARENT_SCOPE)SET(MCU_TEMP_RANGE ${CMAKE_MATCH_6} PARENT_SCOPE)set(STM32Driver_FOUND TRUE PARENT_SCOPE)
endfunction()if(NOT DEFINED MCU_NAME)list(POP_FRONT STM32Driver_FIND_COMPONENTS MCU_NAME)
endif()
if(NOT DEFINED MCU_NAME)message(FATAL_ERROR MCU_NAME variable must be defined before calling find_package(STM32Driver))
endif()stm32_parse_mcu_name(${MCU_NAME})
if(NOT STM32Driver_FOUND)message(WARNING Invalid STM32 MCU name: ${MCU_NAME})return()
endif()set(STM32Driver_FOUND)
foreach(flash_fit IN ITEMS 0 1 2 3 4 5 6 7 8 9 A B Z C D E F G H I)if(${flash_fit} STRGREATER_EQUAL ${MCU_FLASH})string(TOLOWER ${flash_fit} MCU_FLASH_FIT_LOWER)if(EXISTS ${STM32_KITS_DIR}/cmsis-device-${MCU_SERIES_VARIANT_LOWER}/Source/Templates/gcc/startup_stm32${MCU_SERIES_VARIANT_LOWER}${MCU_VARIANT}x${MCU_FLASH_FIT_LOWER}.s)set(STM32Driver_FOUND TRUE)set(MCU_FLASH_FIT ${flash_fit})break()endif()endif()
endforeach()
if(NOT STM32Driver_FOUND)message(WARNING Invalid STM32 MCU Flash: ${MCU_FLASH})return()
endif()enable_language(C ASM)
set(STM32Driver_FOUND TRUE)
add_library(STM32Driver STATIC${STM32_KITS_DIR}/cmsis-device-${MCU_SERIES_VARIANT_LOWER}/Source/Templates/gcc/startup_stm32${MCU_SERIES_VARIANT_LOWER}${MCU_VARIANT}x${MCU_FLASH_FIT_LOWER}.s${STM32_KITS_DIR}/cmsis-device-${MCU_SERIES_VARIANT_LOWER}/Source/Templates/system_stm32${MCU_SERIES_VARIANT_LOWER}xx.c${STM32_KITS_DIR}/stm32${MCU_SERIES_VARIANT_LOWER}xx-hal-driver/Src/stm32${MCU_SERIES_VARIANT_LOWER}xx_hal.c${STM32_KITS_DIR}/stm32${MCU_SERIES_VARIANT_LOWER}xx-hal-driver/Src/stm32${MCU_SERIES_VARIANT_LOWER}xx_hal_cortex.c
)
foreach(feature IN LISTS STM32Driver_FIND_COMPONENTS)target_sources(STM32Driver PRIVATE${STM32_KITS_DIR}/stm32${MCU_SERIES_VARIANT_LOWER}xx-hal-driver/Src/stm32${MCU_SERIES_VARIANT_LOWER}xx_hal_${feature}.c)
endforeach()
target_include_directories(STM32Driver PUBLIC${STM32_KITS_DIR}/cmsis-core/Include${STM32_KITS_DIR}/cmsis-device-${MCU_SERIES_VARIANT_LOWER}/Include${STM32_KITS_DIR}/stm32${MCU_SERIES_VARIANT_LOWER}xx-hal-driver/Inc${STM32_KITS_DIR}/easyheader
)
target_compile_definitions(STM32Driver PUBLIC STM32${MCU_SERIES_VARIANT}${MCU_VARIANT}x${MCU_FLASH_FIT})
target_link_options(STM32Driver PUBLICSHELL:-T\${STM32_KITS_DIR}/cmsis-device-${MCU_SERIES_VARIANT_LOWER}/Source/Templates/gcc/linker/STM32${MCU_SERIES_VARIANT}${MCU_VARIANT}X${MCU_FLASH_FIT}_FLASH.ld\
)新建 stm32kits/easyheader/stm32f1xx_hal_conf.h, 内容如下
#include stm32f1xx_hal_conf_template.h至此 stm32kits 已手工创建完成
3 CLion 全局配置
设置→构建、执行、部署→工具链→→系统 环境文件: stm32kits\cmake\startup.bat C 编译器: arm-none-eabi-gcc.exe C 编译器: arm-none-eabi-g.exe 调试器: arm-none-eabi-gdb.exe 上述全局配置实际保存在 %APPDATA%\JetBrains\CLion2025.1\options\windows\toolchains.xml 中 toolchainnameArmMinGWtoolSetKindSYSTEM_WINDOWS_TOOLSETcustomCCompilerPathstm32kits\arm-gnu-toolchain-14.2.rel1-mingw-w64-x86_64-arm-none-eabi\bin\arm-none-eabi-gcc.execustomCXXCompilerPathstm32kits\arm-gnu-toolchain-14.2.rel1-mingw-w64-x86_64-arm-none-eabi\bin\arm-none-eabi-g.exedebuggerKindCUSTOM_GDBcustomGDBPathstm32kits\arm-gnu-toolchain-14.2.rel1-mingw-w64-x86_64-arm-none-eabi\bin\arm-none-eabi-gdb.exeenvironmentstm32kits\startup.bat /4 CLion 新项目配置
任意创建一个 C 项目后, 进行如下配置 设置→构建、执行、部署→CMake→配置文件 工具链: ArmMinGW CMakeLists.txt 添加:
find_package(STM32Driver COMPONENTS STM32F103C8T6 gpio spi)
target_link_libraries(项目名 PRIVATE STM32Driver)之后程序就可编译了
ST-Link 调试
下面配置嵌入式 GDB 调试服务端, 需安装 Embedded Development Support 插件 设置→构建、执行、部署→调试器→调试服务器→→泛型→GDB 服务器 可执行文件: stm32kits/OpenOCD/bin/openocd.exe 实参: -f interface\stlink.cfg -f target\stm32f1x.cfg 下面配置调试客户端 设置→构建、执行、部署→调试器→调试服务器→调试器 调试器: stm32kits\arm-gnu-toolchain\bin\arm-none-eabi-gdb.exe 连接/实参: tcp:localhost:3333 (用于启动客户端后连接服务端)
上述配置将在 ${CMAKE_CURRENT_SOURCE_DIR}/.idea/debugServers 生成 OpenOCD.xml, 该文件以后可直接复制使用, 其内容如下
component nameDebugServersgeneric-debug-target nameOpenOCD uniqueIDc136ea77-b81f-463e-8e9b-ef6a84b56628 selectedtruedebugger version1debugger toolchainNameArmMinGW /env //debuggergdbserver exeC:/program/stm32kits/OpenOCD-20240916-0.12.0/bin/openocd.exe args-f interface\stlink.cfg -f target\stm32f1x.cfgenv //gdbserverconsole enabledtrue port4444 /target reset-beforefalse /connection remote-stringtcp:localhost:3333 custom-scriptecho Connecting to target...\n#10;$GDBTargetCommand$#10;echo Connected to target!\n warmup-ms500 //generic-debug-target
/component最后再设置一下当前调试服务器, 之后可通过 ST-Link 走 SWD 接口 下载程序和调试 ST-Link 也要装好驱动, OpenOCD已内置了ST-Link的驱动, 位置在 stm32kits/OpenOCD/drivers/ST-Link/dpinst_amd64.exe 在运行被中断时, 可以用调试浮窗的内存视图直接查看 SRAM 内存 而功能寄存器需要在调试浮窗可找到外设页(需安装 Embedded Development Support 插件), 加载 svd 文件来读取 调试时会出现 info pretty-printer 执行失败的错误 原因是 arm-none-eabi-gdb 编译时移除了 python 支持, 否则通常可以在 gdb 隔壁 ../share/gdb/python/gdb/command/pretty_printers.py 找到该命令
5 点亮 LED
以tb上常见的STM32F103C8T6最小系统板为例, 一个 LED 负极接在 PC13 的位置 下面闪烁该 LED
#include stm32f1xx_hal.h
#include stm32f1xx_hal_rcc.h
#include stm32f1xx_hal_gpio.hextern C void SysTick_Handler() {HAL_IncTick();
}int main() {HAL_Init();__HAL_RCC_GPIOC_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.Pin GPIO_PIN_13;GPIO_InitStructure.Speed GPIO_SPEED_FREQ_LOW;GPIO_InitStructure.Mode GPIO_MODE_OUTPUT_PP;GPIO_InitStructure.Pull GPIO_NOPULL;HAL_GPIO_Init(GPIOC, GPIO_InitStructure);while (true) {HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);HAL_Delay(100);HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);HAL_Delay(100);}
}6 分析 elf 文件
IDA 加载 elf 文件后, Processor type 选 ARM Little-endian [ARM], Processor options→Edit ARM architecture options 选 ARMv7-M 可以看到08000000开始是向量表, 第2个是程序入口 Reset_Handler, 在0x0800021C
7 项目模板
CLion 暂不支持将项目保存为项目模板 (详见 Save project as template in CLion. How? ), 只有 Idea 其他 IDE 支持, 新项目都要手动重新配置 工具链,调试服务器