Skip to content

Commit f4241cf

Browse files
bsp/renesas/ra6m3-hmi-board: add VSCode pyOCD debug workspace and guide
1 parent fd2bae8 commit f4241cf

9 files changed

Lines changed: 324 additions & 0 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"recommendations": [
3+
"marus25.cortex-debug",
4+
"ms-vscode.cpptools"
5+
]
6+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "RA6M3 HMI Debug (pyOCD CMSIS-DAP)",
6+
"type": "cortex-debug",
7+
"request": "launch",
8+
"servertype": "external",
9+
"cwd": "${workspaceFolder}",
10+
"executable": "${workspaceFolder}/rtthread.elf",
11+
"armToolchainPath": "/usr/bin",
12+
"toolchainPrefix": "arm-none-eabi",
13+
"gdbPath": "/usr/bin/arm-none-eabi-gdb",
14+
"objdumpPath": "/usr/bin/arm-none-eabi-objdump",
15+
"nmPath": "/usr/bin/arm-none-eabi-nm",
16+
"gdbTarget": "localhost:50000",
17+
"runToEntryPoint": "main",
18+
"preLaunchTask": "debug:prepare",
19+
"postDebugTask": "pyocd:stop",
20+
"showDevDebugOutput": "raw",
21+
"postRestartCommands": [
22+
"monitor reset halt"
23+
]
24+
},
25+
{
26+
"name": "RA6M3 HMI Attach (pyOCD CMSIS-DAP)",
27+
"type": "cortex-debug",
28+
"request": "attach",
29+
"servertype": "pyocd",
30+
"serverpath": "/usr/bin/pyocd",
31+
"cwd": "${workspaceFolder}",
32+
"executable": "${workspaceFolder}/rtthread.elf",
33+
"armToolchainPath": "/usr/bin",
34+
"toolchainPrefix": "arm-none-eabi",
35+
"gdbPath": "/usr/bin/arm-none-eabi-gdb",
36+
"objdumpPath": "/usr/bin/arm-none-eabi-objdump",
37+
"nmPath": "/usr/bin/arm-none-eabi-nm",
38+
"targetId": "r7fa6m3ah",
39+
"showDevDebugOutput": "raw",
40+
"serverArgs": [
41+
"--frequency",
42+
"4000000"
43+
]
44+
},
45+
{
46+
"name": "RA6M3 HMI Attach (external pyOCD :50000)",
47+
"type": "cortex-debug",
48+
"request": "attach",
49+
"servertype": "external",
50+
"cwd": "${workspaceFolder}",
51+
"executable": "${workspaceFolder}/rtthread.elf",
52+
"armToolchainPath": "/usr/bin",
53+
"toolchainPrefix": "arm-none-eabi",
54+
"gdbPath": "/usr/bin/arm-none-eabi-gdb",
55+
"objdumpPath": "/usr/bin/arm-none-eabi-objdump",
56+
"nmPath": "/usr/bin/arm-none-eabi-nm",
57+
"gdbTarget": "localhost:50000",
58+
"preLaunchTask": "pyocd:start",
59+
"postDebugTask": "pyocd:stop",
60+
"showDevDebugOutput": "raw"
61+
}
62+
]
63+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5+
PID_FILE="${ROOT_DIR}/.vscode/.pyocd.pid"
6+
LOG_FILE="${ROOT_DIR}/.vscode/.pyocd.log"
7+
8+
PYOCD_BIN="${PYOCD_BIN:-/usr/bin/pyocd}"
9+
TARGET="${PYOCD_TARGET:-r7fa6m3ah}"
10+
GDB_PORT="${PYOCD_GDB_PORT:-50000}"
11+
TELNET_PORT="${PYOCD_TELNET_PORT:-50001}"
12+
FREQUENCY="${PYOCD_FREQUENCY:-4000000}"
13+
14+
if [[ -f "${PID_FILE}" ]]; then
15+
OLD_PID="$(cat "${PID_FILE}" || true)"
16+
if [[ -n "${OLD_PID}" ]] && kill -0 "${OLD_PID}" 2>/dev/null; then
17+
echo "pyOCD already running (pid=${OLD_PID})"
18+
exit 0
19+
fi
20+
rm -f "${PID_FILE}"
21+
fi
22+
23+
rm -f "${LOG_FILE}"
24+
nohup "${PYOCD_BIN}" gdbserver \
25+
--target "${TARGET}" \
26+
--port "${GDB_PORT}" \
27+
--telnet-port "${TELNET_PORT}" \
28+
--frequency "${FREQUENCY}" \
29+
>"${LOG_FILE}" 2>&1 &
30+
31+
PID=$!
32+
echo "${PID}" > "${PID_FILE}"
33+
34+
for _ in $(seq 1 80); do
35+
if grep -q "GDB server listening on port ${GDB_PORT}" "${LOG_FILE}" 2>/dev/null; then
36+
echo "pyOCD started (pid=${PID}, port=${GDB_PORT})"
37+
exit 0
38+
fi
39+
40+
if ! kill -0 "${PID}" 2>/dev/null; then
41+
echo "pyOCD exited unexpectedly."
42+
tail -n 80 "${LOG_FILE}" || true
43+
exit 1
44+
fi
45+
46+
sleep 0.1
47+
done
48+
49+
echo "Timed out waiting for pyOCD to start on port ${GDB_PORT}."
50+
tail -n 80 "${LOG_FILE}" || true
51+
exit 1
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5+
PID_FILE="${ROOT_DIR}/.vscode/.pyocd.pid"
6+
7+
if [[ ! -f "${PID_FILE}" ]]; then
8+
exit 0
9+
fi
10+
11+
PID="$(cat "${PID_FILE}" || true)"
12+
if [[ -n "${PID}" ]] && kill -0 "${PID}" 2>/dev/null; then
13+
kill "${PID}" || true
14+
15+
for _ in $(seq 1 30); do
16+
if ! kill -0 "${PID}" 2>/dev/null; then
17+
break
18+
fi
19+
sleep 0.1
20+
done
21+
22+
if kill -0 "${PID}" 2>/dev/null; then
23+
kill -9 "${PID}" || true
24+
fi
25+
fi
26+
27+
rm -f "${PID_FILE}"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"files.associations": {
3+
"*.h": "c",
4+
"*.c": "c",
5+
"*.cpp": "cpp"
6+
},
7+
"terminal.integrated.defaultProfile.linux": "zsh"
8+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "build",
6+
"type": "shell",
7+
"command": "scons -j$(nproc)",
8+
"problemMatcher": [
9+
"$gcc"
10+
],
11+
"group": {
12+
"kind": "build",
13+
"isDefault": true
14+
}
15+
},
16+
{
17+
"label": "clean",
18+
"type": "shell",
19+
"command": "scons -c",
20+
"problemMatcher": [
21+
"$gcc"
22+
]
23+
},
24+
{
25+
"label": "rebuild",
26+
"type": "shell",
27+
"command": "scons -c && scons -j$(nproc)",
28+
"problemMatcher": [
29+
"$gcc"
30+
]
31+
},
32+
{
33+
"label": "flash:pyocd",
34+
"type": "shell",
35+
"command": "pyocd flash --target r7fa6m3ah --erase chip rtthread.elf",
36+
"dependsOn": "build",
37+
"problemMatcher": []
38+
},
39+
{
40+
"label": "pyocd:start",
41+
"type": "shell",
42+
"command": "${workspaceFolder}/.vscode/scripts/start-pyocd.sh",
43+
"options": {
44+
"cwd": "${workspaceFolder}"
45+
},
46+
"problemMatcher": []
47+
},
48+
{
49+
"label": "pyocd:stop",
50+
"type": "shell",
51+
"command": "${workspaceFolder}/.vscode/scripts/stop-pyocd.sh",
52+
"options": {
53+
"cwd": "${workspaceFolder}"
54+
},
55+
"problemMatcher": []
56+
},
57+
{
58+
"label": "debug:prepare",
59+
"dependsOrder": "sequence",
60+
"dependsOn": [
61+
"build",
62+
"pyocd:start"
63+
],
64+
"problemMatcher": []
65+
}
66+
]
67+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# RA6M3 HMI Board VSCode + pyOCD 调试说明
2+
3+
本文档对应 `bsp/renesas/ra6m3-hmi-board` 目录下新增的 VSCode 调试配置。
4+
5+
## 1. 目标与适配器
6+
7+
- MCU: `R7FA6M3AH`(target id: `r7fa6m3ah`
8+
- 调试器: `ART-Link CMSIS-DAP`(USB VID:PID `0416:7687`
9+
- 调试链路: `VSCode (Cortex-Debug)` + `arm-none-eabi-gdb` + `pyocd gdbserver`
10+
11+
## 2. 依赖安装(Arch Linux)
12+
13+
```bash
14+
sudo pacman -S --needed code arm-none-eabi-gcc arm-none-eabi-gdb arm-none-eabi-newlib
15+
# pyocd 推荐 AUR 包(若 check 失败可加 --mflags "--nocheck")
16+
yay -S python-pyocd --mflags "--nocheck"
17+
```
18+
19+
可选 USB 权限规则(避免普通用户访问调试器失败):
20+
21+
```bash
22+
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="0416", ATTR{idProduct}=="7687", TAG+="uaccess"' | \
23+
sudo tee /etc/udev/rules.d/70-art-link-cmsis-dap.rules
24+
sudo udevadm control --reload-rules
25+
sudo udevadm trigger
26+
```
27+
28+
## 3. 新增/整理的文件
29+
30+
- `.vscode/launch.json`
31+
- `.vscode/tasks.json`
32+
- `.vscode/settings.json`
33+
- `.vscode/extensions.json`
34+
- `.vscode/scripts/start-pyocd.sh`
35+
- `.vscode/scripts/stop-pyocd.sh`
36+
- `pyocd.yaml`
37+
- `ra6m3-hmi-board.code-workspace`
38+
39+
## 4. VSCode 调试配置说明
40+
41+
### 4.1 `RA6M3 HMI Debug (pyOCD CMSIS-DAP)`
42+
43+
一键调试主配置,流程如下:
44+
45+
1. 执行 `debug:prepare` 任务
46+
2. `build``scons -j$(nproc)`
47+
3. 自动启动 `pyocd gdbserver`(50000/50001)
48+
4. Cortex-Debug 连接到 `localhost:50000`
49+
5. 结束调试后自动执行 `pyocd:stop`
50+
51+
### 4.2 `RA6M3 HMI Attach (pyOCD CMSIS-DAP)`
52+
53+
由 Cortex-Debug 直接拉起 pyOCD 并 attach,保留为备用配置。
54+
55+
### 4.3 `RA6M3 HMI Attach (external pyOCD :50000)`
56+
57+
用于手动/脚本先启动 server 后再 attach 的场景。
58+
59+
## 5. 手动调试(排查模式)
60+
61+
当需要单独验证 pyOCD 链路时:
62+
63+
```bash
64+
pyocd gdbserver --target r7fa6m3ah --port 50000 --telnet-port 50001
65+
```
66+
67+
然后在 VSCode 里选择 `RA6M3 HMI Attach (external pyOCD :50000)`
68+
69+
## 6. 常用任务
70+
71+
- `build`
72+
- `clean`
73+
- `rebuild`
74+
- `flash:pyocd`(先 build,再整片擦写+烧录 `rtthread.elf`
75+
76+
## 7. 日志与进程文件
77+
78+
自动起停脚本会在 `.vscode/` 下生成临时文件:
79+
80+
- `.pyocd.pid`: pyOCD 进程号
81+
- `.pyocd.log`: pyOCD 启动与运行日志
82+
83+
调试结束后 `stop-pyocd.sh` 会清理 `.pyocd.pid` 并终止 server。
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Project-local pyOCD defaults for RA6M3 HMI board.
2+
target_override: r7fa6m3ah
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"folders": [
3+
{
4+
"path": "."
5+
}
6+
],
7+
"settings": {
8+
"cortex-debug.armToolchainPath": "/usr/bin",
9+
"cortex-debug.gdbPath": "arm-none-eabi-gdb"
10+
},
11+
"extensions": {
12+
"recommendations": [
13+
"marus25.cortex-debug",
14+
"ms-vscode.cpptools"
15+
]
16+
}
17+
}

0 commit comments

Comments
 (0)