STM32最小CLion開發環境

文章目錄

    • 1 必須文件
    • 2 工具鏈
    • 3 CLion 全局配置
    • 4 CLion 新項目配置
      • ST-Link 調試
    • 5 點亮 LED
    • 6 分析 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 "-mcpu=cortex-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} --specs=nano.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 PUBLIC"SHELL:-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

      <toolchainname="ArmMinGW"toolSetKind="SYSTEM_WINDOWS_TOOLSET"customCCompilerPath="stm32kits\arm-gnu-toolchain-14.2.rel1-mingw-w64-x86_64-arm-none-eabi\bin\arm-none-eabi-gcc.exe"customCXXCompilerPath="stm32kits\arm-gnu-toolchain-14.2.rel1-mingw-w64-x86_64-arm-none-eabi\bin\arm-none-eabi-g++.exe"debuggerKind="CUSTOM_GDB"customGDBPath="stm32kits\arm-gnu-toolchain-14.2.rel1-mingw-w64-x86_64-arm-none-eabi\bin\arm-none-eabi-gdb.exe"environment="stm32kits\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 name="DebugServers"><generic-debug-target name="OpenOCD" uniqueID="c136ea77-b81f-463e-8e9b-ef6a84b56628" selected="true"><debugger version="1"><debugger toolchainName="ArmMinGW" /><env /></debugger><gdbserver exe="C:/program/stm32kits/OpenOCD-20240916-0.12.0/bin/openocd.exe" args="-f interface\stlink.cfg -f target\stm32f1x.cfg"><env /></gdbserver><console enabled="true" port="4444" /><target reset-before="false" /><connection remote-string="tcp:localhost:3333" custom-script="echo Connecting to target...\n&#10;$GDBTargetCommand$&#10;echo Connected to target!\n" warmup-ms="500" /></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.h>extern "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 支持, 新項目都要手動重新配置 工具鏈,調試服務器

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/908191.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/908191.shtml
英文地址,請注明出處:http://en.pswp.cn/news/908191.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

核函數:解鎖支持向量機的強大能力

在機器學習的世界中&#xff0c;支持向量機&#xff08;SVM&#xff09;是一種強大的分類算法&#xff0c;而核函數則是其背后的“魔法”&#xff0c;讓 SVM 能夠處理復雜的非線性問題。今天&#xff0c;我們就來深入探討核函數的奧秘&#xff0c;看看它們是如何幫助 SVM 在高維…

【Go-6】數據結構與集合

6. 數據結構與集合 數據結構是編程中用于組織和存儲數據的方式&#xff0c;直接影響程序的效率和性能。Go語言提供了多種內置的數據結構&#xff0c;如數組、切片、Map和結構體&#xff0c;支持不同類型的數據管理和操作。本章將詳細介紹Go語言中的主要數據結構與集合&#xf…

3. 簡述node.js特性與底層原理

&#x1f63a;&#x1f63a;&#x1f63a; 一、Node.js 底層原理&#xff08;簡化版&#xff09; Node.js 是一個 基于 Chrome V8 引擎構建的 JavaScript 運行時&#xff0c;底層核心由幾部分組成&#xff1a; 組成部分簡要說明 1.V8 引擎 將 JS 編譯成機器碼執行&#xff0…

Web開發主流前后端框架總結

&#x1f5a5; 一、前端主流框架 前端框架的核心是提升用戶界面開發效率&#xff0c;實現高交互性應用。當前三大主流框架各有側重&#xff1a; React (Meta/Facebook) 核心特點&#xff1a;采用組件化架構與虛擬DOM技術&#xff08;減少真實DOM操作&#xff0c;優化渲染性能&…

大語言模型備案與深度合成算法備案的區別與聯系

“什么情況下做算法備案&#xff1f;” “什么情況下做大模型備案呢&#xff1f;” 進行大模型備案的企業必然要進行算法備案&#xff0c;而進行算法備案的企業則需根據其提供的服務性質判斷是否需要進行大模型備案。 算法備案與大模型備案已經是個老生常談的話題了&#xf…

微軟PowerBI考試 PL300-Power BI 入門

Power BI 入門 上篇更新了微軟PowerBI考試 PL-300學習指南&#xff0c;今天分享PowerBI入門學習內容。 簡介 Microsoft Power BI 是一個完整的報表解決方案&#xff0c;通過開發工具和聯機平臺提供數據準備、數據可視化、分發和管理。 Power BI 可以從使用單個數據源的簡單…

【Hive入門】

之前實習寫的筆記&#xff0c;上傳留個備份。 1. 使用docker-compose快速搭建Hive集群 使用docker快速配置Hive環境 拉取鏡像 2. Hive數據類型 隱式轉換&#xff1a;窄的可以向寬的轉換顯式轉換&#xff1a;cast 3. Hive讀寫文件 SerDe:序列化&#xff08;對象轉為字節碼…

設計模式——簡單工廠模式(創建型)

摘要 本文主要介紹了簡單工廠模式&#xff0c;包括其定義、結構、實現方式、適用場景、實戰示例以及思考。簡單工廠模式是一種創建型設計模式&#xff0c;通過工廠類根據參數決定創建哪一種產品類的實例&#xff0c;封裝了對象創建的細節&#xff0c;使客戶端無需關心具體類的…

抽象工廠模式與策略模式結合使用小案例

目錄 1.前言1.示例說明1.1定義通用接口1.2 定義抽象工廠1.3 支付寶實現1.4 微信實現1.5 客戶端使用代碼&#xff08;組合使用&#xff09;1.6 示例結果輸出1.7 總結 1.前言 上一篇章就通過簡單的案例來了解抽象工廠模式和策略模式的使用&#xff0c;現在就用個支付場景的小案例…

通過WiFi無線連接小米手機攝像頭到電腦的方法

通過WiFi無線連接小米手機攝像頭到電腦的方法 以下是基于Scrcpy和DroidCam兩種工具的無線連接方案&#xff0c;需提前完成開發者模式與USB調試的開啟&#xff08;參考原教程步驟&#xff09;&#xff1a; 方法一&#xff1a;Scrcpy無線投屏&#xff08;無需手機端安裝&#xf…

2025軟件供應鏈安全最佳實踐︱證券DevSecOps下供應鏈與開源治理實踐

項目背景&#xff1a;近年來&#xff0c;云計算、AI人工智能、大數據等信息技術的不斷發展、各行各業的信息電子化的步伐不斷加快、信息化的水平不斷提高&#xff0c;網絡安全的風險不斷累積&#xff0c;金融證券行業面臨著越來越多的威脅挑戰。特別是近年以來&#xff0c;開源…

Java高級 | 【實驗二】Springboot 控制器類+相關注解知識

隸屬文章&#xff1a; Java高級 | &#xff08;二十二&#xff09;Java常用類庫-CSDN博客 系列文章&#xff1a; Java高級 | 【實驗一】Spring Boot安裝及測試 最新-CSDN博客 目錄 一、MVC模式 二、SpringBoot基礎——控制層Controller詳解 &#xff08;一&#xff09;主要工…

MySQL 事務深度解析:面試核心知識點與實戰

&#x1f91f;致敬讀者 &#x1f7e9;感謝閱讀&#x1f7e6;笑口常開&#x1f7ea;生日快樂?早點睡覺 &#x1f4d8;博主相關 &#x1f7e7;博主信息&#x1f7e8;博客首頁&#x1f7eb;專欄推薦&#x1f7e5;活動信息 文章目錄 Java 中 MySQL 事務深度解析&#xff1a;面試…

【趣味Html】第11課:動態閃爍發光粒子五角星

打造炫酷的動態閃爍發光粒子五角星效果 前言 在現代Web開發中&#xff0c;視覺效果的重要性不言而喻。今天我們將深入探討如何使用HTML5 Canvas和JavaScript創建一個令人驚艷的動態閃爍發光粒子五角星效果。這個項目不僅展示了Canvas的強大功能&#xff0c;還涉及了粒子系統、…

6.RV1126-OPENCV 形態學基礎膨脹及腐蝕

一.膨脹 1.膨脹原理 膨脹的本質就是通過微積分的轉換&#xff0c;將圖像A和圖形B進行卷積操作合并成一個AB圖像。核就是指任意的形狀或者大小的圖形B。例如下圖&#xff0c;將核(也就是圖形B)通過微積分卷積&#xff0c;和圖像A合并成一個圖像AB。 2.特點 圖像就會更加明亮 …

機器學習實戰37-基于情感字典和機器學習的股市輿情分析可視化系統

文章目錄 一、項目背景數字時代情感分析情況二、項目流程1.數據采集與預處理2.復合情感分析模型構建3.輿情分析可視化:三、機器學習算法原理1.支持向量機基礎2.核函數與高維映射3.情感分類特征融合4.模型訓練與優化四、實現代碼五、系統特點與優勢1.復合情感分析模型2.多維度可…

STM32F407VET6學習筆記9:編譯輸出固定大小.bin文件

今日學習如何輸出固定大小的.bin編譯文件 目錄 Keil_V5 fromelf.exe 軟件目錄&#xff1a; 魔棒添加命令輸出bin文件&#xff1a; 輸出固定大小的bin文件&#xff1a; 計算bin文件大小&#xff1a; 安裝 SRecord 工具集&#xff1a; 使用SRecord&#xff1a; 參考文章&#…

【Web應用】若依框架:基礎篇14 源碼閱讀-后端代碼分析

文章目錄 ?前言?一、課程講解?總結 標題詳情作者JosieBook頭銜CSDN博客專家資格、阿里云社區專家博主、軟件設計工程師博客內容開源、框架、軟件工程、全棧&#xff08;,NET/Java/Python/C&#xff09;、數據庫、操作系統、大數據、人工智能、工控、網絡、程序人生口號成為你…

Java 單例模式詳解

目錄 1. 餓漢式&#xff08;Eager Initialization&#xff09; 2. 懶漢式&#xff08;Lazy Initialization&#xff09; 3. 懶漢式 同步鎖&#xff08;線程安全&#xff09; 4. 雙重檢查鎖&#xff08;Double-Checked Locking&#xff09; 5. 靜態內部類&#xff08;推薦…

從 AMQP 到 RabbitMQ:核心組件設計與工作原理(一)

一、引言 ** 在當今分布式系統盛行的時代&#xff0c;消息隊列作為一種關鍵的中間件技術&#xff0c;承擔著系統間異步通信、解耦和削峰填谷的重要職責。AMQP&#xff08;Advanced Message Queuing Protocol&#xff09;作為一種高級消息隊列協議&#xff0c;為消息隊列的實現…