vscode-cube-mcp 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vscode_cube_mcp-0.1.0/LICENSE +21 -0
- vscode_cube_mcp-0.1.0/PKG-INFO +139 -0
- vscode_cube_mcp-0.1.0/README.md +120 -0
- vscode_cube_mcp-0.1.0/cubemx_mcp.py +236 -0
- vscode_cube_mcp-0.1.0/pyproject.toml +28 -0
- vscode_cube_mcp-0.1.0/setup.cfg +4 -0
- vscode_cube_mcp-0.1.0/vscode_cube_mcp.egg-info/PKG-INFO +139 -0
- vscode_cube_mcp-0.1.0/vscode_cube_mcp.egg-info/SOURCES.txt +10 -0
- vscode_cube_mcp-0.1.0/vscode_cube_mcp.egg-info/dependency_links.txt +1 -0
- vscode_cube_mcp-0.1.0/vscode_cube_mcp.egg-info/entry_points.txt +2 -0
- vscode_cube_mcp-0.1.0/vscode_cube_mcp.egg-info/requires.txt +1 -0
- vscode_cube_mcp-0.1.0/vscode_cube_mcp.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vscode_cube_mcp contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vscode-cube-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server 封装 STM32CubeMX 命令行,通过 MCP 工具配置引脚/外设并生成 HAL 工程
|
|
5
|
+
Author-email: F1ZyCaO_3286 <3286266250@qq.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: mcp,stm32,stm32cubemx,embedded,hal
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Software Development :: Embedded Systems
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: mcp>=2.0.0
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# Vscode_cube_mcp
|
|
21
|
+
|
|
22
|
+
> 全部由 deepseek-v4-flash 生成
|
|
23
|
+
|
|
24
|
+
MCP(Model Context Protocol) server,封装 **STM32CubeMX** 官方命令行脚本模式(`-q`),
|
|
25
|
+
让 AI 助手可以直接加载 .ioc 工程、改引脚/外设配置、生成 HAL 代码、导出引脚表。
|
|
26
|
+
|
|
27
|
+
每次调用:命令序列写入临时脚本 → 启动 `STM32CubeMX -q` → 超时强杀
|
|
28
|
+
→ 过滤 log4j 噪音 → 检测 KO 失败标记 → 返回干净输出。
|
|
29
|
+
|
|
30
|
+
## 功能
|
|
31
|
+
|
|
32
|
+
| 工具 | 说明 |
|
|
33
|
+
|------|------|
|
|
34
|
+
| `cubemx_script` | 任意 CubeMX 脚本命令序列(逃生通道) |
|
|
35
|
+
| `cubemx_load` | 加载 .ioc 并回读关键配置(只读) |
|
|
36
|
+
| `cubemx_configure` | 加载 .ioc,执行 `set` 命令序列,`saveas` 写回 |
|
|
37
|
+
| `cubemx_generate` | 加载 .ioc 并 `project generate` 生成 HAL 工程 |
|
|
38
|
+
| `cubemx_export_pinout` | 导出引脚配置 CSV(只读) |
|
|
39
|
+
|
|
40
|
+
## 要求
|
|
41
|
+
|
|
42
|
+
- Python **>= 3.10**,安装依赖 `mcp>=2.0`
|
|
43
|
+
- **STM32CubeMX**(ST 专有软件,请从 ST 官网免费下载并自行遵守其许可)—— 本工具仅运行时调用其命令行,不包含、不修改其任何代码
|
|
44
|
+
|
|
45
|
+
## 安装
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install vscode-cube-mcp # 从 PyPI(发布后)
|
|
49
|
+
# 或本地开发安装
|
|
50
|
+
pip install -e .
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 配置(环境变量)
|
|
54
|
+
|
|
55
|
+
| 变量 | 默认 | 说明 |
|
|
56
|
+
|------|------|------|
|
|
57
|
+
| `ST_CUBEMX_EXE` | PATH 中的 `STM32CubeMX` / 常见 Windows 安装位置 | STM32CubeMX 可执行文件完整路径 |
|
|
58
|
+
| `ST_CUBEMX_ALLOWED_ROOTS` | 当前工作目录 | .ioc 允许访问的根目录,`os.pathsep` 分隔(`;` for Windows) |
|
|
59
|
+
| `ST_CUBEMX_TIMEOUT` | `240` | CubeMX 子进程超时秒数 |
|
|
60
|
+
|
|
61
|
+
示例(Windows PowerShell):
|
|
62
|
+
|
|
63
|
+
```powershell
|
|
64
|
+
$env:ST_CUBEMX_EXE = "C:\MINE\STM\STM\STM32CubeMX.exe"
|
|
65
|
+
$env:ST_CUBEMX_ALLOWED_ROOTS = "C:\MINE\STM32Project\STM32VScode"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
> 安全设计:所有 .ioc / 生成路径都必须在 `ST_CUBEMX_ALLOWED_ROOTS` 白名单内,
|
|
69
|
+
> 白名单外的路径会被拒绝(路径校验见 `_check_path`)。
|
|
70
|
+
|
|
71
|
+
## 使用(接入 MCP 客户端)
|
|
72
|
+
|
|
73
|
+
把 server 注册到支持 MCP 的客户端(如 Reasonix / Claude Desktop 等),
|
|
74
|
+
stdio 方式启动:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"mcpServers": {
|
|
79
|
+
"Vscode_cube_mcp": {
|
|
80
|
+
"command": "python",
|
|
81
|
+
"args": ["-m", "cubemx_mcp"]
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
或直接用 console 入口:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
vscode-cube-mcp
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 开发
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
python -m unittest test_cubemx_mcp -v # 运行单元测试(不依赖 CubeMX)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
测试覆盖:`_cleanup` 噪音过滤、`_check_path` 白名单校验、`_find_cubemx` /
|
|
100
|
+
`_allowed_roots` 配置解析、`_run_script`(mock 子进程)的 KO 检测与超时路径。
|
|
101
|
+
|
|
102
|
+
## 许可与依赖声明
|
|
103
|
+
|
|
104
|
+
- **本工具代码**:MIT License(见 `LICENSE`)
|
|
105
|
+
- **mcp SDK**(唯一 Python 依赖):MIT License(modelcontextprotocol/python-sdk)
|
|
106
|
+
- **STM32CubeMX**:ST 专有软件,运行时外部调用,需用户自备并遵守其许可条款
|
|
107
|
+
|
|
108
|
+
## 实践经验(2026-08-05,OLED_MCP 项目踩坑记录)
|
|
109
|
+
|
|
110
|
+
用 `cubemx_generate` 生成的新工程,在 VSCode 里用 **STM32 VS Code Extension** 打开时可能遇到:
|
|
111
|
+
Run and Debug 迟迟不出现 / ST 扩展识别工程很慢 / 报 `OLED_MCPsettings\ide.store.json` 之类 ENOENT。
|
|
112
|
+
|
|
113
|
+
**根因**:CubeMX CLI 生成的新工程缺少 ST 扩展识别工程所需的文件:
|
|
114
|
+
|
|
115
|
+
| 文件 | 作用 |
|
|
116
|
+
|------|------|
|
|
117
|
+
| `.settings/ide.store.json` | 声明 `sourceType=STM32CubeMX`、`device`、`core`(扩展识别硬件的关键) |
|
|
118
|
+
| `.settings/bundles.store.json`、`bundles-lock.store.json` | bundles(工具链)版本锁定 |
|
|
119
|
+
| `.vscode/settings.json` | cube-cmake / clangd 配置 |
|
|
120
|
+
| `.vscode/c_cpp_properties.json` | compile_commands.json 索引 |
|
|
121
|
+
| `.clangd` | clangd 配置 |
|
|
122
|
+
|
|
123
|
+
**正确做法(对齐实例工程,如 OLED_HAL)**:
|
|
124
|
+
1. 生成新工程后,**不要手写 launch.json**(实例工程没有,ST 扩展会自动提供调试配置);
|
|
125
|
+
2. 在 VSCode 里**重新加载窗口**(Reload Window),扩展会识别工程并自动补齐上述文件(device 名取自 `.ioc`,如 `STM32F103C8T6`);
|
|
126
|
+
3. 若扩展没自动补齐,可从同芯片的实例工程复制 `.settings/`、`.vscode/`、`.clangd`(注意核对 `ide.store.json` 里的 `device` 是否一致)。
|
|
127
|
+
|
|
128
|
+
**其他教训**:
|
|
129
|
+
- 若确实要手写 launch.json,ST 扩展的调试器类型是 `stlinkgdbtarget`,`deviceName` 必须与 `.settings/ide.store.json` 的 `device` 一致(如 `STM32F103C8T6`,不是 `STM32F103C8Tx`),否则扩展可能解析异常;
|
|
130
|
+
- 本机 STM32 VS Code Extension 全家桶调试类型:`stlinkgdbtarget`(ST-Link)/ `jlinkgdbtarget`(J-Link)/ `stgdbtarget`(通用 GDB);
|
|
131
|
+
- `cubemx_generate` 的 `project path` 对已存在目录返回 KO 是正常现象,generate 默认在 .ioc 同目录生成,结果不受影响。
|
|
132
|
+
|
|
133
|
+
## 能力边界:不是真正意义上的"从零开始"
|
|
134
|
+
|
|
135
|
+
所有工具都要求先有一个 `.ioc` 文件(`cubemx_load` / `cubemx_configure` / `cubemx_generate` 起手都是 `config load`,且 `_ioc_path()` 校验文件必须存在):
|
|
136
|
+
|
|
137
|
+
- CubeMX 的 `-q` 脚本模式**没有 `new project` 命令**,"新建工程 → 选芯片"是 GUI 独有的流程;
|
|
138
|
+
- 因此"生成新工程"的实际做法是:**复制一个 6.18 原生生成的 .ioc(TEST / OLED_HAL 这类)改造**(改 `ProjectManager.ProjectName` / `ProjectFileName`,再用 `set` 命令加外设/引脚)后 `cubemx_generate`;
|
|
139
|
+
- 手写全新 .ioc 理论可行,但 6.18-RC3 对手写/非原生 .ioc 加载会 NPE,不推荐。
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Vscode_cube_mcp
|
|
2
|
+
|
|
3
|
+
> 全部由 deepseek-v4-flash 生成
|
|
4
|
+
|
|
5
|
+
MCP(Model Context Protocol) server,封装 **STM32CubeMX** 官方命令行脚本模式(`-q`),
|
|
6
|
+
让 AI 助手可以直接加载 .ioc 工程、改引脚/外设配置、生成 HAL 代码、导出引脚表。
|
|
7
|
+
|
|
8
|
+
每次调用:命令序列写入临时脚本 → 启动 `STM32CubeMX -q` → 超时强杀
|
|
9
|
+
→ 过滤 log4j 噪音 → 检测 KO 失败标记 → 返回干净输出。
|
|
10
|
+
|
|
11
|
+
## 功能
|
|
12
|
+
|
|
13
|
+
| 工具 | 说明 |
|
|
14
|
+
|------|------|
|
|
15
|
+
| `cubemx_script` | 任意 CubeMX 脚本命令序列(逃生通道) |
|
|
16
|
+
| `cubemx_load` | 加载 .ioc 并回读关键配置(只读) |
|
|
17
|
+
| `cubemx_configure` | 加载 .ioc,执行 `set` 命令序列,`saveas` 写回 |
|
|
18
|
+
| `cubemx_generate` | 加载 .ioc 并 `project generate` 生成 HAL 工程 |
|
|
19
|
+
| `cubemx_export_pinout` | 导出引脚配置 CSV(只读) |
|
|
20
|
+
|
|
21
|
+
## 要求
|
|
22
|
+
|
|
23
|
+
- Python **>= 3.10**,安装依赖 `mcp>=2.0`
|
|
24
|
+
- **STM32CubeMX**(ST 专有软件,请从 ST 官网免费下载并自行遵守其许可)—— 本工具仅运行时调用其命令行,不包含、不修改其任何代码
|
|
25
|
+
|
|
26
|
+
## 安装
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install vscode-cube-mcp # 从 PyPI(发布后)
|
|
30
|
+
# 或本地开发安装
|
|
31
|
+
pip install -e .
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 配置(环境变量)
|
|
35
|
+
|
|
36
|
+
| 变量 | 默认 | 说明 |
|
|
37
|
+
|------|------|------|
|
|
38
|
+
| `ST_CUBEMX_EXE` | PATH 中的 `STM32CubeMX` / 常见 Windows 安装位置 | STM32CubeMX 可执行文件完整路径 |
|
|
39
|
+
| `ST_CUBEMX_ALLOWED_ROOTS` | 当前工作目录 | .ioc 允许访问的根目录,`os.pathsep` 分隔(`;` for Windows) |
|
|
40
|
+
| `ST_CUBEMX_TIMEOUT` | `240` | CubeMX 子进程超时秒数 |
|
|
41
|
+
|
|
42
|
+
示例(Windows PowerShell):
|
|
43
|
+
|
|
44
|
+
```powershell
|
|
45
|
+
$env:ST_CUBEMX_EXE = "C:\MINE\STM\STM\STM32CubeMX.exe"
|
|
46
|
+
$env:ST_CUBEMX_ALLOWED_ROOTS = "C:\MINE\STM32Project\STM32VScode"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
> 安全设计:所有 .ioc / 生成路径都必须在 `ST_CUBEMX_ALLOWED_ROOTS` 白名单内,
|
|
50
|
+
> 白名单外的路径会被拒绝(路径校验见 `_check_path`)。
|
|
51
|
+
|
|
52
|
+
## 使用(接入 MCP 客户端)
|
|
53
|
+
|
|
54
|
+
把 server 注册到支持 MCP 的客户端(如 Reasonix / Claude Desktop 等),
|
|
55
|
+
stdio 方式启动:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"mcpServers": {
|
|
60
|
+
"Vscode_cube_mcp": {
|
|
61
|
+
"command": "python",
|
|
62
|
+
"args": ["-m", "cubemx_mcp"]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
或直接用 console 入口:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
vscode-cube-mcp
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 开发
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
python -m unittest test_cubemx_mcp -v # 运行单元测试(不依赖 CubeMX)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
测试覆盖:`_cleanup` 噪音过滤、`_check_path` 白名单校验、`_find_cubemx` /
|
|
81
|
+
`_allowed_roots` 配置解析、`_run_script`(mock 子进程)的 KO 检测与超时路径。
|
|
82
|
+
|
|
83
|
+
## 许可与依赖声明
|
|
84
|
+
|
|
85
|
+
- **本工具代码**:MIT License(见 `LICENSE`)
|
|
86
|
+
- **mcp SDK**(唯一 Python 依赖):MIT License(modelcontextprotocol/python-sdk)
|
|
87
|
+
- **STM32CubeMX**:ST 专有软件,运行时外部调用,需用户自备并遵守其许可条款
|
|
88
|
+
|
|
89
|
+
## 实践经验(2026-08-05,OLED_MCP 项目踩坑记录)
|
|
90
|
+
|
|
91
|
+
用 `cubemx_generate` 生成的新工程,在 VSCode 里用 **STM32 VS Code Extension** 打开时可能遇到:
|
|
92
|
+
Run and Debug 迟迟不出现 / ST 扩展识别工程很慢 / 报 `OLED_MCPsettings\ide.store.json` 之类 ENOENT。
|
|
93
|
+
|
|
94
|
+
**根因**:CubeMX CLI 生成的新工程缺少 ST 扩展识别工程所需的文件:
|
|
95
|
+
|
|
96
|
+
| 文件 | 作用 |
|
|
97
|
+
|------|------|
|
|
98
|
+
| `.settings/ide.store.json` | 声明 `sourceType=STM32CubeMX`、`device`、`core`(扩展识别硬件的关键) |
|
|
99
|
+
| `.settings/bundles.store.json`、`bundles-lock.store.json` | bundles(工具链)版本锁定 |
|
|
100
|
+
| `.vscode/settings.json` | cube-cmake / clangd 配置 |
|
|
101
|
+
| `.vscode/c_cpp_properties.json` | compile_commands.json 索引 |
|
|
102
|
+
| `.clangd` | clangd 配置 |
|
|
103
|
+
|
|
104
|
+
**正确做法(对齐实例工程,如 OLED_HAL)**:
|
|
105
|
+
1. 生成新工程后,**不要手写 launch.json**(实例工程没有,ST 扩展会自动提供调试配置);
|
|
106
|
+
2. 在 VSCode 里**重新加载窗口**(Reload Window),扩展会识别工程并自动补齐上述文件(device 名取自 `.ioc`,如 `STM32F103C8T6`);
|
|
107
|
+
3. 若扩展没自动补齐,可从同芯片的实例工程复制 `.settings/`、`.vscode/`、`.clangd`(注意核对 `ide.store.json` 里的 `device` 是否一致)。
|
|
108
|
+
|
|
109
|
+
**其他教训**:
|
|
110
|
+
- 若确实要手写 launch.json,ST 扩展的调试器类型是 `stlinkgdbtarget`,`deviceName` 必须与 `.settings/ide.store.json` 的 `device` 一致(如 `STM32F103C8T6`,不是 `STM32F103C8Tx`),否则扩展可能解析异常;
|
|
111
|
+
- 本机 STM32 VS Code Extension 全家桶调试类型:`stlinkgdbtarget`(ST-Link)/ `jlinkgdbtarget`(J-Link)/ `stgdbtarget`(通用 GDB);
|
|
112
|
+
- `cubemx_generate` 的 `project path` 对已存在目录返回 KO 是正常现象,generate 默认在 .ioc 同目录生成,结果不受影响。
|
|
113
|
+
|
|
114
|
+
## 能力边界:不是真正意义上的"从零开始"
|
|
115
|
+
|
|
116
|
+
所有工具都要求先有一个 `.ioc` 文件(`cubemx_load` / `cubemx_configure` / `cubemx_generate` 起手都是 `config load`,且 `_ioc_path()` 校验文件必须存在):
|
|
117
|
+
|
|
118
|
+
- CubeMX 的 `-q` 脚本模式**没有 `new project` 命令**,"新建工程 → 选芯片"是 GUI 独有的流程;
|
|
119
|
+
- 因此"生成新工程"的实际做法是:**复制一个 6.18 原生生成的 .ioc(TEST / OLED_HAL 这类)改造**(改 `ProjectManager.ProjectName` / `ProjectFileName`,再用 `set` 命令加外设/引脚)后 `cubemx_generate`;
|
|
120
|
+
- 手写全新 .ioc 理论可行,但 6.18-RC3 对手写/非原生 .ioc 加载会 NPE,不推荐。
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Vscode_cube_mcp: MCP server 封装 STM32CubeMX 官方 -q 脚本控制台(无状态子进程)。
|
|
4
|
+
|
|
5
|
+
每次调用:命令序列写入临时脚本 -> 启动 STM32CubeMX -q -> 超时强杀
|
|
6
|
+
-> 过滤 log4j 噪音 -> 检测 KO 失败标记 -> 返回干净输出。
|
|
7
|
+
|
|
8
|
+
Tools:
|
|
9
|
+
cubemx_script(script) 任意脚本(逃生通道)
|
|
10
|
+
cubemx_load(ioc) config load + 回读配置(只读)
|
|
11
|
+
cubemx_configure(ioc, cmds) load + set 命令序列 + saveas(写回 .ioc)
|
|
12
|
+
cubemx_generate(ioc, project_dir) load + project generate
|
|
13
|
+
cubemx_export_pinout(ioc) csv pinout 导出(只读)
|
|
14
|
+
|
|
15
|
+
配置(环境变量,不硬编码本机路径):
|
|
16
|
+
ST_CUBEMX_EXE STM32CubeMX 可执行文件路径;未设置时尝试 PATH 中的
|
|
17
|
+
STM32CubeMX 及常见 Windows 安装位置,最后退回命令名。
|
|
18
|
+
ST_CUBEMX_ALLOWED_ROOTS .ioc 允许访问的根目录(os.pathsep 分隔);
|
|
19
|
+
未设置时默认仅允许当前工作目录。
|
|
20
|
+
ST_CUBEMX_TIMEOUT CubeMX 子进程超时秒数,默认 240。
|
|
21
|
+
|
|
22
|
+
能力边界:本 MCP 不是真正意义上的"从零开始" —— 所有工具都要求先有
|
|
23
|
+
一个 .ioc(CubeMX -q 脚本模式没有 new project 命令),详见 README.md。
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
import asyncio
|
|
27
|
+
import os
|
|
28
|
+
import re
|
|
29
|
+
import shutil
|
|
30
|
+
import subprocess
|
|
31
|
+
import tempfile
|
|
32
|
+
import threading
|
|
33
|
+
|
|
34
|
+
from mcp.server import MCPServer
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# ------------------------------------------------------------------ config
|
|
38
|
+
def _find_cubemx() -> str:
|
|
39
|
+
"""解析 STM32CubeMX 可执行文件路径(环境变量 > PATH > 常见安装位置)。"""
|
|
40
|
+
exe = os.environ.get("ST_CUBEMX_EXE", "").strip()
|
|
41
|
+
if exe:
|
|
42
|
+
return exe
|
|
43
|
+
candidates = ["STM32CubeMX"]
|
|
44
|
+
if os.name == "nt":
|
|
45
|
+
for env_key in ("ProgramFiles", "ProgramFiles(x86)"):
|
|
46
|
+
base = os.environ.get(env_key)
|
|
47
|
+
if base:
|
|
48
|
+
candidates.append(
|
|
49
|
+
os.path.join(base, "STMicroelectronics", "STM32Cube", "STM32CubeMX", "STM32CubeMX.exe")
|
|
50
|
+
)
|
|
51
|
+
for c in candidates:
|
|
52
|
+
if os.path.isfile(c) or shutil.which(c):
|
|
53
|
+
return c
|
|
54
|
+
return candidates[0]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _allowed_roots() -> list:
|
|
58
|
+
"""解析允许访问的根目录列表(环境变量 os.pathsep 分隔,默认当前目录)。"""
|
|
59
|
+
raw = os.environ.get("ST_CUBEMX_ALLOWED_ROOTS", "")
|
|
60
|
+
roots = [r.strip() for r in raw.split(os.pathsep) if r.strip()]
|
|
61
|
+
return roots or [os.getcwd()]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
CUBEMX_EXE = _find_cubemx()
|
|
65
|
+
ALLOWED_ROOTS = _allowed_roots()
|
|
66
|
+
TIMEOUT_SECONDS = int(os.environ.get("ST_CUBEMX_TIMEOUT", "240"))
|
|
67
|
+
|
|
68
|
+
NOISE_RE = re.compile(
|
|
69
|
+
r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3} \[(INFO|WARN|DEBUG|TRACE)\]|"
|
|
70
|
+
r"^(Picked up|log4j[: ]|[A-Z][a-z]{2} \d{2}, \d{4} \d{1,2}:\d{2}:\d{2} (AM|PM)|"
|
|
71
|
+
r"WARNING: Could not open|Configure log4j|Cannot load)",
|
|
72
|
+
re.MULTILINE,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# CubeMX 有单实例锁,串行化防止并发互踩
|
|
76
|
+
_LOCK = threading.Lock()
|
|
77
|
+
|
|
78
|
+
mcp = MCPServer("Vscode_cube_mcp")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# ---------------------------------------------------------------- helpers
|
|
82
|
+
def _check_path(p: str) -> str:
|
|
83
|
+
"""校验路径在允许根目录下,返回绝对路径。"""
|
|
84
|
+
ap = os.path.abspath(p)
|
|
85
|
+
for root in ALLOWED_ROOTS:
|
|
86
|
+
if ap.lower().startswith(os.path.abspath(root).lower()):
|
|
87
|
+
return ap
|
|
88
|
+
raise ValueError(f"路径不在白名单内(仅允许 {ALLOWED_ROOTS}): {p}")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _cleanup(raw: str) -> str:
|
|
92
|
+
lines = []
|
|
93
|
+
for ln in raw.splitlines():
|
|
94
|
+
if NOISE_RE.match(ln):
|
|
95
|
+
continue
|
|
96
|
+
s = ln.strip()
|
|
97
|
+
if s:
|
|
98
|
+
lines.append(s)
|
|
99
|
+
return "\n".join(lines)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _run_script(script: str) -> dict:
|
|
103
|
+
"""执行 CubeMX 脚本,返回 {ok, output, exit_code}。"""
|
|
104
|
+
fd, tmp = tempfile.mkstemp(prefix="cubemx_mcp_", suffix=".txt")
|
|
105
|
+
try:
|
|
106
|
+
with os.fdopen(fd, "w", encoding="utf-8") as f:
|
|
107
|
+
f.write(script.strip() + "\n")
|
|
108
|
+
f.write("exit\n")
|
|
109
|
+
with _LOCK:
|
|
110
|
+
proc = subprocess.run(
|
|
111
|
+
[CUBEMX_EXE, "-q", tmp],
|
|
112
|
+
capture_output=True,
|
|
113
|
+
text=True,
|
|
114
|
+
encoding="utf-8",
|
|
115
|
+
errors="replace",
|
|
116
|
+
timeout=TIMEOUT_SECONDS,
|
|
117
|
+
cwd=os.path.dirname(CUBEMX_EXE) if os.path.dirname(CUBEMX_EXE) else None,
|
|
118
|
+
)
|
|
119
|
+
except subprocess.TimeoutExpired:
|
|
120
|
+
return {"ok": False, "output": f"TIMEOUT: CubeMX 子进程超过 {TIMEOUT_SECONDS}s 被终止", "exit_code": None}
|
|
121
|
+
finally:
|
|
122
|
+
try:
|
|
123
|
+
os.remove(tmp)
|
|
124
|
+
except OSError:
|
|
125
|
+
pass
|
|
126
|
+
|
|
127
|
+
raw = (proc.stdout or "") + "\n" + (proc.stderr or "")
|
|
128
|
+
output = _cleanup(raw)
|
|
129
|
+
ok = proc.returncode == 0 and not any(line.strip() == "KO" for line in output.splitlines())
|
|
130
|
+
return {"ok": ok, "output": output, "exit_code": proc.returncode}
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def _ioc_path(ioc: str) -> str:
|
|
134
|
+
ap = _check_path(ioc)
|
|
135
|
+
if not os.path.isfile(ap):
|
|
136
|
+
raise ValueError(f".ioc 文件不存在: {ap}")
|
|
137
|
+
if not ap.lower().endswith(".ioc"):
|
|
138
|
+
raise ValueError(f"不是 .ioc 文件: {ap}")
|
|
139
|
+
return ap
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
# ------------------------------------------------------------------ tools
|
|
143
|
+
@mcp.tool()
|
|
144
|
+
def cubemx_script(script: str) -> str:
|
|
145
|
+
"""执行任意 CubeMX 脚本命令序列(逃生通道,原样传给 -q)。
|
|
146
|
+
|
|
147
|
+
常用命令示例:
|
|
148
|
+
config load "C:/path/proj.ioc"
|
|
149
|
+
set mode USART1 Asynchronous
|
|
150
|
+
set pin PB13 GPIO_Output
|
|
151
|
+
set gpio parameters PB13 GPIO_Label=LED
|
|
152
|
+
config saveas "C:/path/proj.ioc"
|
|
153
|
+
project generate
|
|
154
|
+
"""
|
|
155
|
+
r = _run_script(script)
|
|
156
|
+
return f"[{'OK' if r['ok'] else 'FAIL'} exit={r['exit_code']}]\n{r['output']}"
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@mcp.tool()
|
|
160
|
+
def cubemx_load(ioc: str) -> str:
|
|
161
|
+
"""加载 .ioc 工程并回读关键配置(只读,不修改任何文件)。
|
|
162
|
+
|
|
163
|
+
参数:
|
|
164
|
+
ioc: 工程 .ioc 文件绝对路径(须在允许目录内)
|
|
165
|
+
"""
|
|
166
|
+
ap = _ioc_path(ioc)
|
|
167
|
+
r = _run_script(f'config load "{ap}"')
|
|
168
|
+
return f"[{'OK' if r['ok'] else 'FAIL'} exit={r['exit_code']}]\n{r['output']}"
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@mcp.tool()
|
|
172
|
+
def cubemx_configure(ioc: str, commands: list) -> str:
|
|
173
|
+
"""加载 .ioc,依次执行 set 命令,最后 saveas 写回原文件。
|
|
174
|
+
|
|
175
|
+
参数:
|
|
176
|
+
ioc: 工程 .ioc 文件绝对路径(会被写回,先备份再调用)
|
|
177
|
+
commands: 命令列表,如 ["set mode USART1 Asynchronous", "set pin PB13 GPIO_Output"]
|
|
178
|
+
"""
|
|
179
|
+
ap = _ioc_path(ioc)
|
|
180
|
+
lines = [f'config load "{ap}"']
|
|
181
|
+
lines.extend(commands)
|
|
182
|
+
lines.append(f'config saveas "{ap}"')
|
|
183
|
+
r = _run_script("\n".join(lines))
|
|
184
|
+
return f"[{'OK' if r['ok'] else 'FAIL'} exit={r['exit_code']}]\n{r['output']}"
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
@mcp.tool()
|
|
188
|
+
def cubemx_generate(ioc: str, project_dir: str = "") -> str:
|
|
189
|
+
"""加载 .ioc 并执行 project generate 生成 HAL 代码。
|
|
190
|
+
|
|
191
|
+
参数:
|
|
192
|
+
ioc: 工程 .ioc 文件绝对路径
|
|
193
|
+
project_dir: 生成目标目录;留空则在 .ioc 所在目录生成。
|
|
194
|
+
强烈建议指向副本/测试目录,避免覆盖现有工程。
|
|
195
|
+
"""
|
|
196
|
+
ap = _ioc_path(ioc)
|
|
197
|
+
lines = [f'config load "{ap}"']
|
|
198
|
+
if project_dir:
|
|
199
|
+
pd = _check_path(project_dir)
|
|
200
|
+
os.makedirs(pd, exist_ok=True)
|
|
201
|
+
lines.append(f'project path "{pd}"')
|
|
202
|
+
lines.append("project generate")
|
|
203
|
+
r = _run_script("\n".join(lines))
|
|
204
|
+
return f"[{'OK' if r['ok'] else 'FAIL'} exit={r['exit_code']}]\n{r['output']}"
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
@mcp.tool()
|
|
208
|
+
def cubemx_export_pinout(ioc: str) -> str:
|
|
209
|
+
"""加载 .ioc 并导出当前引脚配置 CSV(只读,CSV 写系统临时目录后读回)。
|
|
210
|
+
|
|
211
|
+
参数:
|
|
212
|
+
ioc: 工程 .ioc 文件绝对路径
|
|
213
|
+
"""
|
|
214
|
+
ap = _ioc_path(ioc)
|
|
215
|
+
fd, csv = tempfile.mkstemp(prefix="cubemx_pinout_", suffix=".csv")
|
|
216
|
+
os.close(fd)
|
|
217
|
+
try:
|
|
218
|
+
r = _run_script(f'config load "{ap}"\ncsv pinout "{csv}"')
|
|
219
|
+
if not r["ok"]:
|
|
220
|
+
return f"[FAIL exit={r['exit_code']}]\n{r['output']}"
|
|
221
|
+
with open(csv, encoding="utf-8", errors="replace") as f:
|
|
222
|
+
content = f.read()
|
|
223
|
+
return f"[OK]\n{r['output']}\n--- CSV ---\n{content}"
|
|
224
|
+
finally:
|
|
225
|
+
try:
|
|
226
|
+
os.remove(csv)
|
|
227
|
+
except OSError:
|
|
228
|
+
pass
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def main() -> None:
|
|
232
|
+
asyncio.run(mcp.run_stdio_async())
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
if __name__ == "__main__":
|
|
236
|
+
main()
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "vscode-cube-mcp"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "MCP server 封装 STM32CubeMX 命令行,通过 MCP 工具配置引脚/外设并生成 HAL 工程"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "F1ZyCaO_3286", email = "3286266250@qq.com" }]
|
|
13
|
+
keywords = ["mcp", "stm32", "stm32cubemx", "embedded", "hal"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Environment :: Console",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Topic :: Software Development :: Embedded Systems",
|
|
21
|
+
]
|
|
22
|
+
dependencies = ["mcp>=2.0.0"]
|
|
23
|
+
|
|
24
|
+
[project.scripts]
|
|
25
|
+
vscode-cube-mcp = "cubemx_mcp:main"
|
|
26
|
+
|
|
27
|
+
[tool.setuptools]
|
|
28
|
+
py-modules = ["cubemx_mcp"]
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vscode-cube-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server 封装 STM32CubeMX 命令行,通过 MCP 工具配置引脚/外设并生成 HAL 工程
|
|
5
|
+
Author-email: F1ZyCaO_3286 <3286266250@qq.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: mcp,stm32,stm32cubemx,embedded,hal
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Software Development :: Embedded Systems
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: mcp>=2.0.0
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# Vscode_cube_mcp
|
|
21
|
+
|
|
22
|
+
> 全部由 deepseek-v4-flash 生成
|
|
23
|
+
|
|
24
|
+
MCP(Model Context Protocol) server,封装 **STM32CubeMX** 官方命令行脚本模式(`-q`),
|
|
25
|
+
让 AI 助手可以直接加载 .ioc 工程、改引脚/外设配置、生成 HAL 代码、导出引脚表。
|
|
26
|
+
|
|
27
|
+
每次调用:命令序列写入临时脚本 → 启动 `STM32CubeMX -q` → 超时强杀
|
|
28
|
+
→ 过滤 log4j 噪音 → 检测 KO 失败标记 → 返回干净输出。
|
|
29
|
+
|
|
30
|
+
## 功能
|
|
31
|
+
|
|
32
|
+
| 工具 | 说明 |
|
|
33
|
+
|------|------|
|
|
34
|
+
| `cubemx_script` | 任意 CubeMX 脚本命令序列(逃生通道) |
|
|
35
|
+
| `cubemx_load` | 加载 .ioc 并回读关键配置(只读) |
|
|
36
|
+
| `cubemx_configure` | 加载 .ioc,执行 `set` 命令序列,`saveas` 写回 |
|
|
37
|
+
| `cubemx_generate` | 加载 .ioc 并 `project generate` 生成 HAL 工程 |
|
|
38
|
+
| `cubemx_export_pinout` | 导出引脚配置 CSV(只读) |
|
|
39
|
+
|
|
40
|
+
## 要求
|
|
41
|
+
|
|
42
|
+
- Python **>= 3.10**,安装依赖 `mcp>=2.0`
|
|
43
|
+
- **STM32CubeMX**(ST 专有软件,请从 ST 官网免费下载并自行遵守其许可)—— 本工具仅运行时调用其命令行,不包含、不修改其任何代码
|
|
44
|
+
|
|
45
|
+
## 安装
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install vscode-cube-mcp # 从 PyPI(发布后)
|
|
49
|
+
# 或本地开发安装
|
|
50
|
+
pip install -e .
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 配置(环境变量)
|
|
54
|
+
|
|
55
|
+
| 变量 | 默认 | 说明 |
|
|
56
|
+
|------|------|------|
|
|
57
|
+
| `ST_CUBEMX_EXE` | PATH 中的 `STM32CubeMX` / 常见 Windows 安装位置 | STM32CubeMX 可执行文件完整路径 |
|
|
58
|
+
| `ST_CUBEMX_ALLOWED_ROOTS` | 当前工作目录 | .ioc 允许访问的根目录,`os.pathsep` 分隔(`;` for Windows) |
|
|
59
|
+
| `ST_CUBEMX_TIMEOUT` | `240` | CubeMX 子进程超时秒数 |
|
|
60
|
+
|
|
61
|
+
示例(Windows PowerShell):
|
|
62
|
+
|
|
63
|
+
```powershell
|
|
64
|
+
$env:ST_CUBEMX_EXE = "C:\MINE\STM\STM\STM32CubeMX.exe"
|
|
65
|
+
$env:ST_CUBEMX_ALLOWED_ROOTS = "C:\MINE\STM32Project\STM32VScode"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
> 安全设计:所有 .ioc / 生成路径都必须在 `ST_CUBEMX_ALLOWED_ROOTS` 白名单内,
|
|
69
|
+
> 白名单外的路径会被拒绝(路径校验见 `_check_path`)。
|
|
70
|
+
|
|
71
|
+
## 使用(接入 MCP 客户端)
|
|
72
|
+
|
|
73
|
+
把 server 注册到支持 MCP 的客户端(如 Reasonix / Claude Desktop 等),
|
|
74
|
+
stdio 方式启动:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"mcpServers": {
|
|
79
|
+
"Vscode_cube_mcp": {
|
|
80
|
+
"command": "python",
|
|
81
|
+
"args": ["-m", "cubemx_mcp"]
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
或直接用 console 入口:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
vscode-cube-mcp
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 开发
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
python -m unittest test_cubemx_mcp -v # 运行单元测试(不依赖 CubeMX)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
测试覆盖:`_cleanup` 噪音过滤、`_check_path` 白名单校验、`_find_cubemx` /
|
|
100
|
+
`_allowed_roots` 配置解析、`_run_script`(mock 子进程)的 KO 检测与超时路径。
|
|
101
|
+
|
|
102
|
+
## 许可与依赖声明
|
|
103
|
+
|
|
104
|
+
- **本工具代码**:MIT License(见 `LICENSE`)
|
|
105
|
+
- **mcp SDK**(唯一 Python 依赖):MIT License(modelcontextprotocol/python-sdk)
|
|
106
|
+
- **STM32CubeMX**:ST 专有软件,运行时外部调用,需用户自备并遵守其许可条款
|
|
107
|
+
|
|
108
|
+
## 实践经验(2026-08-05,OLED_MCP 项目踩坑记录)
|
|
109
|
+
|
|
110
|
+
用 `cubemx_generate` 生成的新工程,在 VSCode 里用 **STM32 VS Code Extension** 打开时可能遇到:
|
|
111
|
+
Run and Debug 迟迟不出现 / ST 扩展识别工程很慢 / 报 `OLED_MCPsettings\ide.store.json` 之类 ENOENT。
|
|
112
|
+
|
|
113
|
+
**根因**:CubeMX CLI 生成的新工程缺少 ST 扩展识别工程所需的文件:
|
|
114
|
+
|
|
115
|
+
| 文件 | 作用 |
|
|
116
|
+
|------|------|
|
|
117
|
+
| `.settings/ide.store.json` | 声明 `sourceType=STM32CubeMX`、`device`、`core`(扩展识别硬件的关键) |
|
|
118
|
+
| `.settings/bundles.store.json`、`bundles-lock.store.json` | bundles(工具链)版本锁定 |
|
|
119
|
+
| `.vscode/settings.json` | cube-cmake / clangd 配置 |
|
|
120
|
+
| `.vscode/c_cpp_properties.json` | compile_commands.json 索引 |
|
|
121
|
+
| `.clangd` | clangd 配置 |
|
|
122
|
+
|
|
123
|
+
**正确做法(对齐实例工程,如 OLED_HAL)**:
|
|
124
|
+
1. 生成新工程后,**不要手写 launch.json**(实例工程没有,ST 扩展会自动提供调试配置);
|
|
125
|
+
2. 在 VSCode 里**重新加载窗口**(Reload Window),扩展会识别工程并自动补齐上述文件(device 名取自 `.ioc`,如 `STM32F103C8T6`);
|
|
126
|
+
3. 若扩展没自动补齐,可从同芯片的实例工程复制 `.settings/`、`.vscode/`、`.clangd`(注意核对 `ide.store.json` 里的 `device` 是否一致)。
|
|
127
|
+
|
|
128
|
+
**其他教训**:
|
|
129
|
+
- 若确实要手写 launch.json,ST 扩展的调试器类型是 `stlinkgdbtarget`,`deviceName` 必须与 `.settings/ide.store.json` 的 `device` 一致(如 `STM32F103C8T6`,不是 `STM32F103C8Tx`),否则扩展可能解析异常;
|
|
130
|
+
- 本机 STM32 VS Code Extension 全家桶调试类型:`stlinkgdbtarget`(ST-Link)/ `jlinkgdbtarget`(J-Link)/ `stgdbtarget`(通用 GDB);
|
|
131
|
+
- `cubemx_generate` 的 `project path` 对已存在目录返回 KO 是正常现象,generate 默认在 .ioc 同目录生成,结果不受影响。
|
|
132
|
+
|
|
133
|
+
## 能力边界:不是真正意义上的"从零开始"
|
|
134
|
+
|
|
135
|
+
所有工具都要求先有一个 `.ioc` 文件(`cubemx_load` / `cubemx_configure` / `cubemx_generate` 起手都是 `config load`,且 `_ioc_path()` 校验文件必须存在):
|
|
136
|
+
|
|
137
|
+
- CubeMX 的 `-q` 脚本模式**没有 `new project` 命令**,"新建工程 → 选芯片"是 GUI 独有的流程;
|
|
138
|
+
- 因此"生成新工程"的实际做法是:**复制一个 6.18 原生生成的 .ioc(TEST / OLED_HAL 这类)改造**(改 `ProjectManager.ProjectName` / `ProjectFileName`,再用 `set` 命令加外设/引脚)后 `cubemx_generate`;
|
|
139
|
+
- 手写全新 .ioc 理论可行,但 6.18-RC3 对手写/非原生 .ioc 加载会 NPE,不推荐。
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
cubemx_mcp.py
|
|
4
|
+
pyproject.toml
|
|
5
|
+
vscode_cube_mcp.egg-info/PKG-INFO
|
|
6
|
+
vscode_cube_mcp.egg-info/SOURCES.txt
|
|
7
|
+
vscode_cube_mcp.egg-info/dependency_links.txt
|
|
8
|
+
vscode_cube_mcp.egg-info/entry_points.txt
|
|
9
|
+
vscode_cube_mcp.egg-info/requires.txt
|
|
10
|
+
vscode_cube_mcp.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
mcp>=2.0.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cubemx_mcp
|