From a1cbf4a3c3141a271940cae14f600f1820b7e397 Mon Sep 17 00:00:00 2001 From: kirl <18827922006@163.com> Date: Mon, 27 Jul 2026 20:00:06 +0800 Subject: [PATCH] init --- .clangd | 20 +++++ .gitignore | 5 ++ .vscode/launch.json | 17 ++++ .vscode/settings.json | 8 ++ .vscode/tasks.json | 50 ++++++++++++ CMakeLists.txt | 100 +++++++++++++++++++++++ README.md | 173 ++++++++++++++++++++++++++++++++++++++++ blink.syscfg | 18 +++++ gcc-arm-none-eabi.cmake | 19 +++++ src/main.c | 40 ++++++++++ start_pyocd.ps1 | 10 +++ 11 files changed, 460 insertions(+) create mode 100644 .clangd create mode 100644 .gitignore create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 .vscode/tasks.json create mode 100644 CMakeLists.txt create mode 100644 README.md create mode 100644 blink.syscfg create mode 100644 gcc-arm-none-eabi.cmake create mode 100644 src/main.c create mode 100644 start_pyocd.ps1 diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..21c58dd --- /dev/null +++ b/.clangd @@ -0,0 +1,20 @@ +CompileFlags: + # 指向 build 目录中的 compile_commands.json + CompilationDatabase: build/ + # 移除 clang 不认识的 GCC 特有参数 + Remove: + - -gstrict-dwarf + +Diagnostics: + # 抑制嵌入式代码中常见的 unwanted 警告 + Suppress: + - unused-parameter + - missing-prototypes + - redundant-decls + +Index: + # 后台索引线程数 + Background: Build + +Completion: + AllScopes: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e9e063a --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# 构建目录 +build/ + +# 缓存目录 +.cache/ \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..a191f45 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "MSPM0G3507 Debug", + "type": "cortex-debug", + "request": "launch", + "cwd": "${workspaceFolder}", + "executable": "${workspaceFolder}/build/blink.elf", + "servertype": "external", + "gdbTarget": "localhost:3333", + "device": "MSPM0G3507", + "runToEntryPoint": "main", + "preLaunchTask": "Start pyOCD Server" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7e5d2de --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "cmake.configureArgs": [ + "-DCMAKE_TOOLCHAIN_FILE=${workspaceFolder}/gcc-arm-none-eabi.cmake", + "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON" + ], + "cmake.buildDirectory": "${workspaceFolder}/build", + "cmake.generator": "Ninja" +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..5978d6c --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,50 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start pyOCD Server", + "type": "shell", + "command": "powershell", + "args": ["-ExecutionPolicy", "Bypass", "-File", "${workspaceFolder}/start_pyocd.ps1"], + "isBackground": true, + "problemMatcher": { + "owner": "pyocd", + "pattern": { "regexp": "." }, + "background": { + "activeOnStart": true, + "beginsPattern": ".", + "endsPattern": "GDB server listening on port" + } + } + }, + { + "label": "Configure", + "type": "process", + "command": "cmake", + "args": ["-G", "Ninja", "-S", "${workspaceFolder}", "-B", "${workspaceFolder}/build", "-DCMAKE_TOOLCHAIN_FILE=gcc-arm-none-eabi.cmake", "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"], + "problemMatcher": [] + }, + { + "label": "Build", + "type": "shell", + "command": "ninja", + "args": ["-C", "build"], + "group": { "kind": "build", "isDefault": true }, + "dependsOn": ["Configure"], + "problemMatcher": [] + }, + { + "label": "Flash", + "type": "shell", + "command": "python", + "args": ["-m", "pyocd", "flash", "-t", "mspm0g3507", "${workspaceFolder}/build/blink.elf"], + "problemMatcher": [] + }, + { + "label": "Build & Flash", + "dependsOrder": "sequence", + "dependsOn": ["Build", "Flash"], + "problemMatcher": [] + } + ] +} diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d91e08b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,100 @@ +cmake_minimum_required(VERSION 3.20) + +# 跳过编译器链接测试(裸机 ARM 无系统调用 _exit/_sbrk 等) +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +project(blink C) + +# 输出固件带 .elf 后缀,pyOCD 自动识别格式 +set(CMAKE_EXECUTABLE_SUFFIX ".elf") + +set(SDK_DIR "C:/ti/mspm0_sdk_2_11_00_07") +set(SYSCONFIG_CLI "C:/ti/sysconfig_1.28.0/sysconfig_cli.bat") +set(DEVICE "MSPM0G350X") +set(PACKAGE "LQFP-64(PM)") + +# ── SysConfig code generation ────────────────────────────────────── +set(SYSCFG_OUTPUT_DIR "${CMAKE_BINARY_DIR}/syscfg") + +add_custom_command( + OUTPUT + "${SYSCFG_OUTPUT_DIR}/ti_msp_dl_config.c" + "${SYSCFG_OUTPUT_DIR}/ti_msp_dl_config.h" + "${SYSCFG_OUTPUT_DIR}/device_linker.lds" + "${SYSCFG_OUTPUT_DIR}/device.opt" + "${SYSCFG_OUTPUT_DIR}/device.lds.genlibs" + COMMAND cmd /c "${SYSCONFIG_CLI}" + --compiler gcc + --product "${SDK_DIR}/.metadata/product.json" + --device "${DEVICE}" + --package "${PACKAGE}" + --output "${SYSCFG_OUTPUT_DIR}" + "${CMAKE_SOURCE_DIR}/blink.syscfg" + DEPENDS "${CMAKE_SOURCE_DIR}/blink.syscfg" + COMMENT "Running SysConfig..." +) + +# ── Source files ──────────────────────────────────────────────────── +set(GEN_DIR ${SYSCFG_OUTPUT_DIR}) + +add_executable(${PROJECT_NAME} + src/main.c + "${GEN_DIR}/ti_msp_dl_config.c" + "${SDK_DIR}/source/ti/devices/msp/m0p/startup_system_files/gcc/startup_mspm0g350x_gcc.c" +) + +# SysConfig outputs are dependencies +add_dependencies(${PROJECT_NAME} syscfg_gen) +add_custom_target(syscfg_gen DEPENDS "${GEN_DIR}/ti_msp_dl_config.c") + +# ── Include directories ───────────────────────────────────────────── +target_include_directories(${PROJECT_NAME} PRIVATE + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/src" + "${GEN_DIR}" + "${SDK_DIR}/source" + "${SDK_DIR}/source/third_party/CMSIS/Core/Include" +) + +# ── Compile definitions & flags ───────────────────────────────────── +target_compile_definitions(${PROJECT_NAME} PRIVATE + __MSPM0G3507__ + __USE_SYSCONFIG__ +) + +target_compile_options(${PROJECT_NAME} PRIVATE + -mcpu=cortex-m0plus + -march=armv6-m + -mthumb + -mfloat-abi=soft + -std=c99 + -O2 + -ffunction-sections + -fdata-sections + -g + -Wall + -gstrict-dwarf +) + +# ── Linker flags ──────────────────────────────────────────────────── +# Override SysConfig's linker script with G3507 (128KB Flash / 32KB SRAM) +set(LINKER_SCRIPT "${SDK_DIR}/source/ti/devices/msp/m0p/linker_files/gcc/mspm0g3507.lds") + +target_link_options(${PROJECT_NAME} PRIVATE + -mcpu=cortex-m0plus + -march=armv6-m + -mthumb + -mfloat-abi=soft + -nostartfiles + -static + -Wl,--gc-sections + -Wl,-Map,${PROJECT_NAME}.map + -T${LINKER_SCRIPT} + -T${GEN_DIR}/device.lds.genlibs + -L${SDK_DIR}/source + --specs=nano.specs + --specs=nosys.specs + -lgcc + -lc + -lm +) diff --git a/README.md b/README.md new file mode 100644 index 0000000..db721fa --- /dev/null +++ b/README.md @@ -0,0 +1,173 @@ +# MSPM0G3507 LED Blink + +基于 TI MSPM0G3507 的 LED 闪烁项目,纯命令行工具链(ARM GCC + CMake + Ninja + pyOCD),不依赖任何 IDE。 + +## 硬件 + +| 项目 | 说明 | +|------|------| +| 芯片 | MSPM0G3507 (Cortex-M0+, 80MHz, 128KB Flash / 32KB SRAM) | +| 调试器 | 通用 DAPLink / CMSIS-DAP | +| LED | PB9,低有效(低电平点亮) | + +## 开发环境 + +| 工具 | 版本 | 用途 | +|------|------|------| +| arm-none-eabi-gcc | 15.2+ | 交叉编译器 | +| CMake | 3.20+ | 构建系统 | +| Ninja | 1.10+ | 构建后端 | +| Python | 3.10+ | pyOCD 运行环境 | +| pyOCD | 0.45+ | 烧录与调试 | +| SysConfig | 1.28+ | 引脚/时钟配置生成 | +| clangd | 18+ | LSP 语言服务器 (IntelliSense) | +| MSPM0 SDK | 2.11+ | 驱动库与启动文件 | + +### 快速安装 + +```powershell +# pyOCD(含 MSPM0 Flash 算法) +pip install pyocd +python -m pyocd pack install MSPM0G3507 +``` + +MSPM0 SDK 和 SysConfig 需从 [TI 官网](https://www.ti.com/tool/MSPM0-SDK) 下载安装。 + +## 构建 + +```powershell +# 配置(首次或 CMakeLists.txt 变更后) +# PowerShell 中 .cmake 需引号包裹,否则会被拆开 +cmake -G Ninja -S . -B build "-DCMAKE_TOOLCHAIN_FILE=gcc-arm-none-eabi.cmake" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + +# 编译 +ninja -C build + +# 或 cd 进 build 目录后直接 +cd build +ninja +``` + +### LSP / IntelliSense (clangd) + +项目根目录已配置 `.clangd`,指向 `build/compile_commands.json`。 +安装 VS Code 扩展 **clangd**(LLVM 官方)并**禁用** Microsoft C/C++ IntelliSense 即可使用。 + +## 烧录 + +一条命令搞定(自动连接、擦除、写入、校验、断开): + +```powershell +python -m pyocd flash -t mspm0g3507 build/blink.elf +``` + +输出示例: + +``` +Erased 1024 bytes (1 sector), programmed 1024 bytes (1 page) +``` + +## 调试(GDB) + +需要两个终端协作,**先启动服务器再连 GDB**: + +```powershell +# 终端 1:启动 GDB 服务器(保持运行) +# DAPLink 克隆版建议降频避免通信错误 +python -m pyocd gdbserver -t mspm0g3507 -f 500000 + +# 等看到 "GDB server listening on port 3333" 后, + +# 终端 2:启动 GDB +arm-none-eabi-gdb build/blink.elf +``` + +GDB 内手动连接: + +```gdb +target remote :3333 # 连接 pyOCD 服务器 +load # 烧录固件 +monitor reset # 复位芯片 +continue # 开始运行 +``` + +常用命令: + +```gdb +# ── 断点 ────────────────────────── +break main # main 函数入口断点 +break src/main.c:20 # 文件行号断点 +info breakpoints # 列出所有断点 +delete 1 # 删除 1 号断点 + +# ── 运行 ────────────────────────── +monitor reset # 复位芯片 +continue (缩写 c) # 继续运行 +step (缩写 s) # 单步进入函数 +next (缩写 n) # 单步跳过函数 +finish (缩写 fin) # 执行到当前函数返回 + +# ── 查看 ────────────────────────── +print DELAY # 查看变量/宏 +print/x GPIO_LED_LED_PIN # 十六进制查看 +backtrace (缩写 bt) # 调用栈 +info registers # 寄存器 + +# ── 退出 ────────────────────────── +quit # 退出 GDB +``` + +### 典型调试流程 + +```gdb +target remote :3333 +load +break main +monitor reset +continue +# → 停在 main 第一行 + +next # 执行 SYSCFG_DL_init() +next # 进入 while(1) +print cycle # 检查 cycle 值 +continue # LED 开始闪 + +# 按 Ctrl+C 暂停 +break src/main.c:20 # 在看 CLEAR 还是 SET 的地方断 +continue # 停在断点 +next # 单步看 LED ON/OFF +``` + +## VS Code + +安装 [Cortex-Debug](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug) 扩展后: + +| 操作 | 按键 | +|------|:--:| +| 编译 | `Ctrl+Shift+B` | +| 编译 + 烧录 | `Ctrl+Shift+P` → `Run Task` → **Build & Flash** | +| 调试 | `F5`(自动启动 pyOCD → 烧录 → 停在 `main`) | + +断点、单步、变量查看全在图形界面操作。首次 `F5` 会启动 pyOCD,之后每次自动复用已有服务器。 + +## 项目结构 + +``` +blink/ +├── .vscode/ # VS Code 配置 (纳入 Git) +│ ├── settings.json # CMake 工具链配置 +│ ├── launch.json # Cortex-Debug F5 调试 +│ └── tasks.json # Ctrl+Shift+B 编译 / Build & Flash +├── .clangd # clangd IntelliSense 配置 +├── .gitignore +├── CMakeLists.txt # CMake 构建配置 +├── gcc-arm-none-eabi.cmake # ARM 交叉编译工具链 +├── blink.syscfg # SysConfig 引脚/时钟配置 +├── start_pyocd.ps1 # pyOCD 服务器自动启动脚本 +├── src/ +│ └── main.c # 应用代码 +├── include/ # 应用头文件 +├── lib/ # 第三方库 +└── build/ # 构建产物 (gitignore) + └── blink.elf # 固件 +``` diff --git a/blink.syscfg b/blink.syscfg new file mode 100644 index 0000000..58fe129 --- /dev/null +++ b/blink.syscfg @@ -0,0 +1,18 @@ +/** + * LED Blink configuration for MSPM0G3507 + * LED on PB9, active low + */ +//@cliArgs --device "MSPM0G350X" --package "LQFP-64(PM)" --part "Default" + +const GPIO = scripting.addModule("/ti/driverlib/GPIO", {}, false); +const GPIO1 = GPIO.addInstance(); +const SYSCTL = scripting.addModule("/ti/driverlib/SYSCTL"); + +GPIO1.$name = "GPIO_LED"; +GPIO1.port = "PORTB"; +GPIO1.associatedPins.create(1); +GPIO1.associatedPins[0].$name = "LED"; +GPIO1.associatedPins[0].assignedPin = "9"; + +SYSCTL.forceDefaultClkConfig = true; +SYSCTL.clockTreeEn = true; diff --git a/gcc-arm-none-eabi.cmake b/gcc-arm-none-eabi.cmake new file mode 100644 index 0000000..6653111 --- /dev/null +++ b/gcc-arm-none-eabi.cmake @@ -0,0 +1,19 @@ +# CMake toolchain file for ARM Cortex-M0+ (MSPM0) +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR arm) + +# Skip linker test for bare-metal (avoids _exit/_sbrk etc.) +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set(ARM_TOOLCHAIN_DIR "C:/Program Files/Arm/GNU Toolchain mingw-w64-x86_64-arm-none-eabi") + +set(CMAKE_C_COMPILER "${ARM_TOOLCHAIN_DIR}/bin/arm-none-eabi-gcc.exe") +set(CMAKE_CXX_COMPILER "${ARM_TOOLCHAIN_DIR}/bin/arm-none-eabi-g++.exe") +set(CMAKE_ASM_COMPILER "${ARM_TOOLCHAIN_DIR}/bin/arm-none-eabi-gcc.exe") +set(CMAKE_OBJCOPY "${ARM_TOOLCHAIN_DIR}/bin/arm-none-eabi-objcopy.exe") +set(CMAKE_SIZE "${ARM_TOOLCHAIN_DIR}/bin/arm-none-eabi-size.exe") + +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) diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..e1db146 --- /dev/null +++ b/src/main.c @@ -0,0 +1,40 @@ +/** + * LED Blink - MSPM0G3507 + * LED on PB9, active low (低电平点亮) + */ + +#include "ti_msp_dl_config.h" + +/** + * @brief 毫秒级延时函数 (基于 CPU 忙等) + * @param ms 要延时的毫秒数 + * + * 假设 CPUCLK_FREQ = 32 MHz, 1 ms ≈ 32000 cycles + */ +void delay(uint32_t ms) +{ + uint32_t cycles_per_ms = CPUCLK_FREQ / 1000; + while (ms--) { + delay_cycles(cycles_per_ms); + } +} + +int cycle = 0; + +int main(void) +{ + /* Initialize GPIO and clocks via SysConfig-generated code */ + SYSCFG_DL_init(); + + + while (1) { + /* LED ON: PB9 = LOW (active low) */ + DL_GPIO_clearPins(GPIO_LED_PORT, GPIO_LED_LED_PIN); + delay(100); + + /* LED OFF: PB9 = HIGH */ + DL_GPIO_setPins(GPIO_LED_PORT, GPIO_LED_LED_PIN); + delay(100); + cycle++; + } +} diff --git a/start_pyocd.ps1 b/start_pyocd.ps1 new file mode 100644 index 0000000..cf2e2ae --- /dev/null +++ b/start_pyocd.ps1 @@ -0,0 +1,10 @@ +# 检查 pyOCD 是否已在运行,没有则启动 +$port = 3333 +$alreadyRunning = netstat -ano 2>$null | Select-String ":$port .*LISTENING" + +if ($alreadyRunning) { + Write-Host "pyOCD already running on port $port" +} else { + Write-Host "Starting pyOCD GDB server..." + python -m pyocd gdbserver -t mspm0g3507 -f 500000 +}