VSCode + Renode: 현대적인 임베디드 시뮬레이션 워크플로우 구축
Source: Dev.to
왜 Renode + VSCode인가?
현대 임베디드 개발은 다음과 같은 방식에서 벗어나고 있습니다:
- IAR + 물리 보드 + 하드웨어 프로그래머 + 시리얼 케이블
- 물리 장치에만 제한된 브레이크포인트와 스텝핑
- MCU 패밀리를 바꿀 때마다 툴체인을 재설치
다음으로 이동합니다:
- VSCode + GCC – 가볍고 현대적이며 크로스‑플랫폼
- Renode – STM32 / ESP32 장치의 전체 시뮬레이션 (UART, SPI, I2C, GPIO, DMA)
- GDB 원격 디버깅 – 플랫폼에 구애받지 않으며 네트워크를 통해 디버깅 가능
- 자동화 친화 – CI/CD와 재현 가능한 테스트에 적합
많은 국제 기업에서 관찰된 장점
- 개발 효율이 크게 향상됨
- 자동화 테스트가 가능해짐
- CI 파이프라인에서 MCU 시뮬레이션을 실행할 수 있음
- 물리 하드웨어에 대한 의존도가 감소
Renode 설치
Renode는 여러 바이너리 배포판을 제공합니다. 사용 중인 플랫폼에 맞는 것을 선택하세요.
- 저장소:
- 예시 선택:
renode-latest.linux-portable-dotnet.tar.gz
왜 이 버전인가?
- 자체 .NET 런타임을 포함하고 있음
- 시스템에 설치된
dotnet/mono가 필요 없음 - Orange Pi / Raspberry Pi에서 바로 실행 가능
설치 단계
# Download the tarball, then extract
tar -xzf renode-latest.linux-portable-dotnet.tar.gz
cd renode
# Launch Renode
./renode
Renode 구성
시뮬레이션하려는 MCU와 주변 장치를 설명하는 최소 .resc 스크립트를 만듭니다.
아래 예시는 STM32F103을 대상으로 합니다.
using sysbus
mach create "stm32f103"
machine LoadPlatformDescription @platforms/cpus/stm32f103.repl
# Load the ELF firmware (adjust the path for your setup)
machine LoadELF @/home/orangepi/object/renode_portable/firmware.elf
# Enable UART2 analyzer
showAnalyzer sysbus.usart2
# Start GDB server on port 3333 (accessible from VSCode)
machine StartGdbServer 3333 true
start
이 파일을 run_stm32.resc 로 저장합니다.
VSCode 디버그 구성
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug STM32F103 on Renode Remote",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/firmware.elf",
"cwd": "${workspaceFolder}",
"miDebuggerPath": "arm-none-eabi-gdb",
"miDebuggerServerAddress": "xxx.xxx.xxx.xxx:3333",
"preLaunchTask": "Run Renode Remote",
"stopAtEntry": true,
"setupCommands": [
{ "text": "set pagination off" },
{ "text": "set confirm off" },
{ "text": "set print pretty on" }
],
"postRemoteConnectCommands": [
{ "text": "monitor machine Pause" },
{ "text": "monitor sysbus LoadELF @/home/orangepi/object/renode_portable/firmware.elf" },
{ "text": "monitor cpu Reset" }
],
"externalConsole": false,
"targetArchitecture": "arm"
}
]
}
핵심 파라미터
miDebuggerPath– 로컬 GDB 실행 파일 경로.miDebuggerServerAddress– 원격 Renode GDB 엔드포인트.preLaunchTask– 디버깅 전에 원격 머신에서 Renode를 시작합니다.postRemoteConnectCommands– 시뮬레이션을 일시 정지하고 ELF를 다시 로드한 뒤 CPU를 리셋하여 상태를 동기화합니다.
tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "CMake Configure",
"type": "shell",
"command": "cmake",
"args": [
"-S", "${workspaceFolder}",
"-B", "${workspaceFolder}/build",
"-DCMAKE_BUILD_TYPE=Debug"
]
},
{
"label": "CMake Build",
"type": "shell",
"command": "cmake",
"args": [
"--build", "${workspaceFolder}/build",
"--config", "Debug"
],
"dependsOn": ["CMake Configure"]
},
{
"label": "Run Renode Remote",
"type": "shell",
"command": "ssh",
"args": [
"orangepi@xxx.xxx.xxx.xxx",
"\"cd /home/orangepi/object/renode_portable && ./renode run_stm32.resc\""
],
"dependsOn": ["CMake Build"]
}
]
}
이 작업 파이프라인은 펌웨어를 빌드하고, ELF와 .resc 스크립트를 원격 머신에 복사한 뒤 Renode를 시작하고, 마지막으로 GDB 디버거를 연결합니다.
테스트
- VSCode에서 F5 키를 누릅니다.
- Renode가 원격 보드에서 부팅됩니다.
- 펌웨어가 자동으로 로드됩니다.
- UART 출력이 VSCode 터미널에 나타나고, 브레이크포인트가 정상적으로 동작합니다.
이제 VSCode, Renode, 그리고 GDB를 활용한 완전한 현대 임베디드 시뮬레이션 워크플로우를 구축했습니다.