펌웨어 플래싱
Pico(UF2), Arduino(arduino-cli), Nucleo(probe-rs) 펌웨어 플래싱 방법과 보드에서 코드를 읽고 쓰고 실행하는 방법을 설명합니다.
이 페이지에서는 Revka가 마이크로컨트롤러에 펌웨어를 올리는 방법과, 보드가 온라인 상태가 된 이후 에이전트가 코드를 읽고 쓰고 실행하는 방법을 설명합니다. 보드 계열마다 플래싱 툴체인이 다릅니다. Raspberry Pi Pico는 대용량 저장소 드라이브를 통해 UF2를 플래시하고, Arduino Uno는 arduino-cli를, STM32 Nucleo는 내장 ST-Link를 통해 probe-rs를 사용합니다. Arduino Uno Q는 별도의 방식으로, 펌웨어를 플래시하는 대신 Bridge 앱을 실행합니다.
모든 하드웨어 기능은 빌드 시 hardware Cargo 피처가 필요합니다:
cargo build --release --features hardware보드를 플래시한 후에는 GPIO 도구가 해당 보드에 접근할 수 있도록 등록해야 합니다. GPIO 도구 및 지원 보드 레퍼런스를 참고하세요. 하드웨어 스택이 처음이라면 하드웨어 빠른 시작부터 시작하세요.
Raspberry Pi Pico (UF2)
섹션 제목: “Raspberry Pi Pico (UF2)”Pico는 LLM이 호출 가능한 pico_flash 도구로 플래시합니다. 이 도구는 내장된 Revka MicroPython 펌웨어(UF2 이미지)를 BOOTSEL 모드의 Pico에 복사하고, mpremote로 main.py를 배포한 뒤, 시리얼 포트가 다시 나타날 때까지 기다린 후 디바이스 트랜스포트를 재연결합니다. 따라서 데몬을 재시작하지 않아도 GPIO 명령을 즉시 사용할 수 있습니다.
사전 요구 사항
섹션 제목: “사전 요구 사항”-
hardware피처가 컴파일에 포함되어 있어야 합니다. -
mpremote가 설치되어 있어야 합니다:Terminal window pip install mpremote
Pico 플래시
섹션 제목: “Pico 플래시”-
BOOTSEL 버튼을 누른 채로 Pico를 연결합니다.
RPI-RP2드라이브가 마운트됩니다(macOS/Linux에서는 볼륨으로, Windows에서는 드라이브 문자로 표시됩니다). -
에이전트에게 보드를 플래시하도록 지시합니다. 예: “Pico를 플래시해 줘.”
-
에이전트는 안전 게이트를 설정하여 도구를 호출합니다:
pico_flash(confirm=true) -
도구는 UF2를 복사하고, 최대 20초간 시리얼 포트를 기다린 후,
main.py를 배포하고 트랜스포트를 재연결합니다. 성공 시 다음과 같은 메시지가 출력됩니다:Pico flashed and main.py deployed successfully. Firmware is online at/dev/cu.usbmodem101. pico0 is ready — you can use gpio_write immediately.
파라미터
| 파라미터 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
confirm | boolean | 예 | 진행하려면 true이어야 합니다. 안전 게이트입니다. |
디바이스 코드 읽기 / 쓰기 / 실행
섹션 제목: “디바이스 코드 읽기 / 쓰기 / 실행”MicroPython(또는 CircuitPython) 디바이스가 온라인 상태가 되면, 세 가지 도구로 에이전트가 실행 중인 프로그램을 관리할 수 있습니다. 세 도구 모두 mpremote를 사용하므로 pip install mpremote가 필요합니다. device 파라미터는 디바이스가 하나만 등록되어 있으면 자동으로 선택됩니다.
현재 코드 읽기 (device_read_code)
섹션 제목: “현재 코드 읽기 (device_read_code)”디바이스에서 현재 main.py를 읽습니다. 디바이스 동작을 수정하기 전에 먼저 실행하세요.
device_read_code()device_read_code(device="pico0")내부적으로 mpremote connect <port> cat :main.py를 실행하여 파일 내용을 반환합니다. main.py가 존재하지 않으면 오류 대신 “아직 프로그램이 없습니다”라는 친절한 메시지를 반환합니다.
| 파라미터 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
device | string | 아니오 | 디바이스 별칭. 디바이스가 하나만 등록된 경우 자동 선택됩니다. |
코드 쓰기 (device_write_code)
섹션 제목: “코드 쓰기 (device_write_code)”완전한 Python 프로그램을 main.py로 디바이스에 쓴 후 보드를 리셋합니다.
device_write_code( device="pico0", code="import machine, time\nled = machine.Pin(25, machine.Pin.OUT)\nwhile True:\n led.toggle()\n time.sleep(0.5)\n")내부적으로 mpremote를 통해 코드를 main.py에 복사하고 디바이스를 리셋한 뒤, 최대 15초간 시리얼 포트가 다시 나타나기를 기다리고 재연결 성공 여부를 보고합니다.
| 파라미터 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
device | string | 아니오 | 디바이스 별칭. 디바이스가 하나뿐이면 자동 선택됩니다. |
code | string | 예 | main.py로 쓸 완전한 프로그램. 빈 값은 거부됩니다. |
일회성 스니펫 실행 (device_exec)
섹션 제목: “일회성 스니펫 실행 (device_exec)”main.py를 수정하지 않고 디바이스에서 Python 스니펫을 실행합니다. 스니펫 실행이 완료된 후에도 디바이스는 현재 프로그램을 계속 실행합니다. 센서 읽기, 빠른 테스트, 블링크 루프 등에 사용하세요.
device_exec(code="print(machine.Pin(25).value())")내부적으로 mpremote connect <port> run <snippet>을 실행하고 캡처된 출력(예외 등 MicroPython stderr 포함)을 반환합니다. 타임아웃은 30초이며, 응답 없는 디바이스는 타임아웃 오류 메시지를 출력합니다. 빈 코드는 거부됩니다.
| 파라미터 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
device | string | 아니오 | 디바이스 별칭. 디바이스가 하나뿐이면 자동 선택됩니다. |
code | string | 예 | 실행할 Python 스니펫. 출력이 캡처되어 반환됩니다. |
Arduino Uno (arduino-cli)
섹션 제목: “Arduino Uno (arduino-cli)”Arduino는 Revka 펌웨어 플래시와 스케치 업로드 모두에 arduino-cli를 사용합니다.
Revka 펌웨어 플래시 (revka peripheral flash)
섹션 제목: “Revka 펌웨어 플래시 (revka peripheral flash)”이 CLI 명령은 내장된 Revka 펌웨어 스케치를 Arduino Uno에 플래시합니다. arduino-cli 설치(macOS에서는 Homebrew를 통해), AVR 코어 설치, 스케치 컴파일 및 업로드를 모두 처리합니다. 이 펌웨어는 시리얼을 통해 capabilities, gpio_read, gpio_write 명령을 활성화합니다.
# 포트를 명시적으로 지정revka peripheral flash --port /dev/cu.usbmodem14301
# 또는, 보드가 이미 config.toml에 있는 경우revka peripheral flash| 플래그 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
--port | string | 아니오 | 시리얼 포트. 생략하면 config.toml에서 자동으로 해석됩니다. |
플래시 후 ~/.revka/config.toml에 보드를 추가합니다:
[peripherals]enabled = true
[[peripherals.boards]]board = "arduino-uno"transport = "serial"path = "/dev/cu.usbmodem14301"baud = 115200커스텀 스케치 업로드 (arduino_upload)
섹션 제목: “커스텀 스케치 업로드 (arduino_upload)”arduino_upload는 에이전트가 생성한 Arduino 스케치를 컴파일하고 업로드하는 LLM 호출 가능 도구로, 위의 Revka 펌웨어 플래시와는 별개입니다. arduino-uno라는 이름으로 보드가 설정되면 자동으로 추가되며, 해당 보드의 path 설정 값을 시리얼 포트로 사용합니다.
에이전트는 setup()과 loop()이 모두 포함된 완전한 .ino 스케치를 작성하여 code로 전달합니다. Revka는 스케치를 임시 디렉토리에 쓴 뒤 arduino:avr:uno 보드를 대상으로 arduino-cli compile과 arduino-cli upload를 실행합니다.
arduino_upload(code="void setup() {\n pinMode(13, OUTPUT);\n}\nvoid loop() {\n digitalWrite(13, HIGH);\n delay(500);\n digitalWrite(13, LOW);\n delay(500);\n}\n")“Arduino에 블링크 스케치를 업로드해 줘” 와 같은 자연어 요청을 받으면 에이전트가 스케치를 생성하고 도구를 호출합니다.
| 파라미터 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
code | string | 예 | 완전한 .ino 스케치 내용(전체 파일). 빈 값은 거부됩니다. |
STM32 Nucleo (probe-rs)
섹션 제목: “STM32 Nucleo (probe-rs)”Nucleo-F401RE는 보드에 내장된 ST-Link 디버거를 통해 probe-rs로 플래시합니다. 별도의 디버그 프로브가 필요 없습니다. CLI 명령은 Embassy Rust 펌웨어를 빌드하고 플래시합니다. 플래시 후 보드는 USART2(PA2/PA3)에서 Revka 시리얼 JSON 프로토콜로 통신하며, 이는 ST-Link 가상 COM 포트로 브리지됩니다.
사전 요구 사항
섹션 제목: “사전 요구 사항”probe-rs CLI 도구를 설치합니다(크레이트 이름은 probe-rs가 아닌 probe-rs-tools입니다):
cargo install probe-rs-tools --lockedRevka를 통한 플래시 (revka peripheral flash-nucleo)
섹션 제목: “Revka를 통한 플래시 (revka peripheral flash-nucleo)”revka peripheral flash-nucleofirmware/nucleo를 빌드하고 probe-rs run --chip STM32F401RETx를 실행합니다. 펌웨어는 플래시 직후 바로 동작합니다.
수동 플래시 (동일한 방법)
섹션 제목: “수동 플래시 (동일한 방법)”cd firmware/nucleocargo build --release --target thumbv7em-none-eabihfprobe-rs run --chip STM32F401RETx target/thumbv7em-none-eabihf/release/nucleo주요 상수: 칩 STM32F401RETx, 타깃 트리플 thumbv7em-none-eabihf.
시리얼 포트 확인 및 설정
섹션 제목: “시리얼 포트 확인 및 설정”플래시 후 Nucleo는 시리얼 디바이스로 나타납니다:
/dev/cu.usbmodem* 또는 /dev/tty.usbmodem* (예: /dev/cu.usbmodem101).
/dev/ttyACM0 (연결 후 dmesg로 확인). GPIO 명령이 무시된다면 사용자를 dialout 그룹에 추가하세요: sudo usermod -a -G dialout $USER, 이후 로그아웃했다가 다시 로그인합니다.
~/.revka/config.toml에 보드를 추가합니다:
[peripherals]enabled = true
[[peripherals.boards]]board = "nucleo-f401re"transport = "serial"path = "/dev/cu.usbmodem101" # adjust to your portbaud = 115200핀 13 = PA5 = Nucleo-F401RE의 사용자 LED(LD2).
probe 피처(cargo build --features hardware,probe)로 빌드하고 revka hardware info를 실행하면, 타깃에 펌웨어가 없는 상태에서도 USB/SWD를 통해 Nucleo의 칩 정보와 메모리 맵을 읽을 수 있습니다. 자세한 내용은 지원 보드를 참고하세요.
Arduino Uno Q Bridge (setup-uno-q)
섹션 제목: “Arduino Uno Q Bridge (setup-uno-q)”Arduino Uno Q는 일반적인 방식으로 플래시하지 않습니다. Linux 측에서 Revka가 실행되며, GPIO 제어는 Bridge 앱을 통해 이루어집니다. Bridge 앱은 TCP 포트 9999에서 수신 대기하는 Python + MCU 소켓 서버로, Linux 측의 gpio_read / gpio_write를 MCU의 GPIO에 연결합니다. revka peripheral setup-uno-q 명령은 scp + arduino-app-cli를 통해 Bridge 앱을 배포합니다.
# Mac에서 (revka 저장소와 함께)revka peripheral setup-uno-q --host 192.168.0.48
# Uno Q에서 직접 (SSH로 접속한 경우) — 기본값은 localhostrevka peripheral setup-uno-q이 명령은 Bridge 앱(firmware/uno-q-bridge/에서)을 ~/ArduinoApps/uno-q-bridge로 복사하고 시작합니다.
| 플래그 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
--host | string | 아니오 | Uno Q의 IP 주소. 기본값은 localhost입니다. |
설정 후 config.toml에 bridge 트랜스포트로 보드를 등록합니다:
[peripherals]enabled = true
[[peripherals.boards]]board = "arduino-uno-q"transport = "bridge"이 설정을 마치면 표준 gpio_read / gpio_write 도구가 시리얼 포트 대신 Bridge TCP 소켓(127.0.0.1:9999)을 통해 투명하게 동작합니다. 에이전트는 동일한 도구 이름을 사용합니다. Bridge가 실행 중이어야 이 도구들이 동작합니다. setup-uno-q가 Bridge를 시작합니다. 연결 타임아웃은 5초, 응답 타임아웃은 3초이며, Bridge의 오류 응답은 error:로 시작합니다.