8000 GitHub - krtokia/pico-test · GitHub
[go: up one dir, main page]

Skip to content
krtokiaPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

pico2w-wake

Raspberry Pi Pico 2 W 펌웨어. Wi-Fi에 붙어 UDP 9번 포트를 듣고 있다가 WAKE_G14 문자열이 담긴 패킷을 받으면 USB HID 키보드로 F13을 한 번 눌렀다 뗍니다. 호스트가 잠들어 있으면 먼저 USB remote wakeup으로 깨웁니다.

  • 보드: pico2_w (RP2350 + CYW43439)
  • 빌드: pico-sdk 2.2.0 / CMake
  • USB: TinyUSB HID 키보드 단일 인터페이스, remote wakeup 지원
  • 자격증명은 소스에 하드코딩하지 않습니다 (아래 참조)

1. 펌웨어 받기

Push할 때마다 GitHub Actions가 빌드합니다. Actions → 최신 run → Artifacts에서 pico2w-wake-<sha> 를 내려받으면 안에 세 파일이 있습니다.

파일 용도
pico2w_wake.uf2 플래시할 펌웨어 (자격증명 없음)
pico2w_wake.elf 디버깅용
uf2-wifi-config.html Wi-Fi 설정 주입기

직접 빌드하려면:

git clone --branch 2.2.0 https://github.com/raspberrypi/pico-sdk.git
cd pico-sdk && git submodule update --init lib/tinyusb lib/lwip lib/cyw43-driver lib/mbedtls && cd ..

cmake -B build -G Ninja -DPICO_BOARD=pico2_w -DPICO_SDK_PATH=$PWD/pico-sdk .
cmake --build build

2. Wi-Fi 자격증명 넣기

CI가 만드는 .uf2에는 SSID/비밀번호가 들어있지 않습니다. 이 저장소는 공개이고 빌드 아티팩트도 공개되는데, 컴파일 정의로 넣은 문자열은 strings firmware.uf2 한 줄이면 그대로 읽히기 때문입니다.

대신 펌웨어 안에 고정 레이아웃의 152바이트 설정 블록을 두고, 빌드가 끝난 .uf2에 나중에 써넣습니다.

  1. uf2-wifi-config.html을 브라우저로 엽니다 (더블클릭. 인터넷 연결 필요 없음).
  2. 내려받은 pico2w_wake.uf2를 선택하고 SSID와 비밀번호를 입력합니다.
  3. pico2w_wake-configured.uf2가 내려받아집니다.

이 페이지는 순수 클라이언트 JS입니다. 파일 읽기·수정·저장이 전부 브라우저 안에서 일어나고 네트워크로 나가는 것은 없습니다. 설치할 것도, 개발환경도 필요 없습니다.

빌드 타임 주입도 가능합니다. cmake -B build ... -DWIFI_SSID="my-net" -DWIFI_PASSWORD="my-pass" 다만 이렇게 만든 .uf2/.elf에는 비밀번호가 평문으로 박히므로 공유하면 안 됩니다. CI에서 이 경로를 쓰려면 저장소 secrets WIFI_SSID/WIFI_PASSWORD를 등록하고 저장소 variable BAKE_WIFI_CREDENTIALS를 true로 설정하세요. 공개 저장소에서는 권장하지 않습니다.

3. 플래시 (BOOTSEL 드래그 앤 드롭)

  1. Pico 2 W의 BOOTSEL 버튼을 누른 채로 USB 케이블을 PC에 연결합니다.
  2. RP2350 이라는 이름의 USB 드라이브가 나타납니다.
  3. pico2w_wake-configured.uf2를 그 드라이브에 끌어다 놓습니다.
  4. 드라이브가 사라지고 보드가 자동으로 재부팅됩니다.

4. 동작 확인

온보드 LED가 상태를 나타냅니다.

LED 의미
0.25초 주기 깜빡임 Wi-Fi 접속 시도 중 (또는 자격증명 없음)
계속 켜짐 접속 완료, IP 획득, UDP 대기 중

테스트용 UDP 전송 (nc):

echo -n "WAKE_G14" | nc -u -w1 192.168.0.42 9

192.168.0.42를 Pico의 IP로 바꾸세요. Windows에는 nc도 python도 기본 탑재가 아니므로 PowerShell을 쓰세요 (이건 항상 있습니다):

$u=New-Object Net.Sockets.UdpClient; $b=[Text.Encoding]::ASCII.GetBytes("WAKE_G14"); $u.Send($b,$b.Length,"192.168.0.42",9)

보낸 바이트 수 8 이 출력되면 전송된 것입니다. 다른 내용의 패킷은 조용히 무시됩니다.

F13이 도착했는지 확인하는 법:

F13은 화면에 아무 글자도 찍지 않는 키라서 메모장으로는 확인할 수 없습니다. 브라우저로 https://keycode.info 같은 키 입력 테스터를 열어놓고 확인하세요.

주의할 점이 하나 있습니다. 키는 그 순간 포커스된 창으로 갑니다. 터미널에서 전송 명령을 실행하면 포커스가 터미널에 있으므로 F13도 터미널로 가고, 브라우저는 아무것도 받지 못합니다.

그래서 Windows에서는 브라우저를 쓰지 말고, 보내는 창에서 그대로 받는 이 한 줄이 제일 확실합니다 (PowerShell ISE 말고 일반 PowerShell 또는 Windows Terminal에서):

$u=New-Object Net.Sockets.UdpClient; $u.EnableBroadcast=$true; $b=[Text.Encoding]::ASCII.GetBytes("WAKE_G14"); $u.Send($b,$b.Length,"192.168.0.255",9)|Out-Null; "전송함. 키 대기중"; $k=$Host.UI.RawUI.ReadKey("IncludeKeyDown,NoEcho"); "받은 키: VirtualKeyCode=$($k.VirtualKeyCode)"

저절로 VirtualKeyCode=124 (= F13) 이 뜨면 전 경로가 동작하는 것입니다. 아무 반응 없이 계속 대기하면 패킷이 보드에 닿지 않은 것입니다.

UART 로그를 보고 있다면 포커스와 무관하게 hid: F13 down / hid: F13 up 이 찍힙니다.

안 될 때 어디부터 보나

증상 의미 다음 확인
LED가 계속 깜빡임 Wi-Fi 접속 실패 SSID/비밀번호, 2.4GHz 대역인지
LED 켜짐, F13 안 옴 Wi-Fi는 정상 아래 두 가지
  1. 키보드로 인식됐는지 — 장치 관리자 → 키보드 → Pico 2 W Wake Key 가 있어야 합니다. 없으면 USB 쪽 문제입니다 (충전 전용 케이블, 포트).
  2. 패킷이 도달하는지 — 브로드캐스트를 막는 공유기가 있습니다. 공유기 DHCP 클라이언트 목록에서 pico2w-wake 의 IP를 찾아 유니캐스트로 보내보세요. 유니캐스트만 되면 원인은 공유기이므로, 그 MAC에 DHCP 예약을 걸고 유니캐스트로 쓰면 됩니다.

주소를 어떻게 알아내나 (DHCP라 IP가 바뀝니다)

IP를 몰라도 됩니다 — 브로드캐스트로 보내면 됩니다. 펌웨어는 IP_ANY에 바인딩되어 있고 SOF_BROADCAST가 켜져 있어서 서브넷 브로드캐스트도 받습니다. Wake-on-LAN 매직 패킷이 동작하는 것과 같은 원리입니다.

Windows (PowerShell) — 유니캐스트와 달리 EnableBroadcast 를 켜야 합니다:

$u=New-Object Net.Sockets.UdpClient; $u.EnableBroadcast=$true; $b=[Text.Encoding]::ASCII.GetBytes("WAKE_G14"); $u.Send($b,$b.Length,"192.168.0.255",9)

Linux / macOS:

python3 -c "import socket;s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM);s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1);s.sendto(b'WAKE_G14',('192.168.0.255',9))"

nc로도 되지만 브로드캐스트에는 SO_BROADCAST가 필요해서 버전에 따라 -b가 있어야 합니다 (nc -u -b -w1 192.168.0.255 9).

브로드캐스트 주소 구하기: 본인 IP에서 나옵니다 (마스크가 /24 = 255.255.255.0일 때, 집 공유기는 거의 다 이렇습니다). 앞 세 칸은 그대로 두고 마지막 칸만 255로 바꾸면 됩니다.

내 IP 대역 브로드캐스트 주소
192.168.0.x 192.168.0.255
192.168.219.x 192.168.219.255
10.39.39.x 10.39.39.255

내 IP는 Windows에서 ipconfig, Linux/macOS에서 ip addr 로 확인합니다.

다만 일부 공유기는 절전을 위해 무선 클라이언트로 가는 브로드캐스트를 필터링하거나 지연시킵니다. 확실하게 하려면 아래처럼 IP를 고정하고 유니캐스트로 보내세요.

IP 고정 (권장): 공유기에서 DHCP 예약 부팅 시 UART 로그에 MAC 주소가 찍힙니다:

wifi: mac 28:cd:c1:xx:xx:xx, dhcp hostname "pico2w-wake"

UART가 번거로우면 공유기 DHCP 클라이언트 목록에서 호스트명 pico2w-wake 로 찾아도 됩니다. 그 MAC에 고정 IP를 예약해두면 이후로는 주소가 안 바뀝니다.

UART로 로그를 보려면: GP0 = TX, GP1 = RX, 115200 8N1. USB는 HID 디바이스가 쓰므로 로그는 UART로만 나옵니다. 접속 성공 시 받은 IP도 여기 찍힙니다.


절전 해제가 실제로 되게 하려면

펌웨어만으로는 부족하고, 호스트 쪽 전제가 몇 가지 있습니다. 먼저 확인하세요.

① PC가 잠든 동안에도 USB 포트에 전원이 살아 있어야 합니다. 메인보드 BIOS에서 ErP Ready / Deep Sleep 이 켜져 있으면 절전 시 USB 전원이 끊깁니다. 그러면 Pico 자체가 꺼져서 Wi-Fi 패킷을 받을 수조차 없습니다. 해당 옵션을 끄거나, VSYS에 상시 전원을 따로 물리세요.

② Windows에서 이 장치의 절전 해제를 허용해야 합니다. 이게 꺼져 있으면 호스트가 remote wakeup을 arm하지 않고, tud_remote_wakeup()은 무시됩니다. (UART 로그에 host did not resume 가 찍힙니다.)

장치 관리자에서는 제품 이름이 아니라 드라이버 이름인 HID 키보드 장치 로 보입니다. 같은 이름이 여러 개면 어느 것이 이 보드인지 하드웨어 ID로 구분하세요:

  1. 장치 관리자 → 키보드 → 각 HID 키보드 장치 우클릭 → 속성 → 자세히 탭
  2. 속성 드롭다운을 하드웨어 ID 로 변경 → HID\VID_CAFE&PID_4001 인 것이 이 보드
  3. 그 장치의 전원 관리 탭 → "이 장치를 사용하여 컴퓨터의 대기 모드를 종료할 수 있음" 체크

확인은 PowerShell로:

powercfg /devicequery wake_armed

목록에 HID 키보드 장치 가 뜨면 설정된 것입니다. 보드가 열거되었는지 자체를 확인하려면:

Get-PnpDevice -PresentOnly | Where-Object InstanceId -like "*VID_CAFE*" | Format-List FriendlyName,Class,Status

③ S3 / 최신 대기 모드(Modern Standby)에서만 동작합니다. S4(최대 절전)나 S5(종료) 상태는 USB HID remote wakeup으로 깨울 수 없습니다. 그쪽은 Wake-on-LAN(유선) 영역입니다. 내 PC가 어느 쪽인지는:

powercfg /a

대기 모드(S0 저 전원 유휴) 가 사용 가능하면 모던 스탠바이 PC입니다. 이 경우 시스템이 S0에 머무르므로 USB 포트 전원이 끊기지 않아 ①의 BIOS 설정이 무의미해지고, HID 키 입력이 기본 웨이크 소스이므로 그냥 동작할 가능성이 높습니다. 또 이런 PC에서는 전원 관리 탭의 절전 해제 체크박스가 회색으로 비활성화되어 있는 것이 정상입니다.

참고로 전원 관리 탭은 키보드 노드가 아니라 USB 노드(휴먼 인터페이스 장치 → USB 입력 장치)에 붙습니다. 그리고 "대기 모드를 종료할 수 있음" 항목은 바로 위의 "컴퓨터가 이 장치를 끌 수 있음" 이 체크되어 있어야 활성화됩니다.

④ 전류 관련 규격 위반 (알고 쓰세요). USB 서스펜드 상태의 허용 소비전류는 2.5 mA인데, CYW43439는 수신 대기만으로도 수십 mA를 씁니다. 대부분의 PC는 그냥 넘어가지만, 엄격한 보드는 포트를 차단할 수 있습니다. Wi-Fi를 계속 살려둬야 하는 구조상 피할 수 없는 트레이드오프입니다.

⑤ 5GHz는 안 됩니다. CYW43439는 2.4GHz 전용입니다. WPA2-AES(PSK)로 접속합니다.

보안 메모

UDP 9번에 평문 문자열이 오면 그대로 키를 누릅니다. 인증이 없습니다. 같은 LAN에 있는 누구나 PC를 깨울 수 있고, 공유기에서 9번 포트를 포워딩하면 인터넷 전체에 열립니다. 포트포워딩은 하지 마세요.

USB VID/PID는 TinyUSB 예제값(0xCAFE/0x4001)입니다. 개인 용도로는 문제없지만 하드웨어를 배포할 거라면 정식 VID/PID를 받아야 합니다.

구성

src/main.c              메인 루프: USB task, HID 상태 머신, Wi-Fi 재접속, LED
src/usb_descriptors.c   HID 키보드 디스크립터 (remote wakeup 속성 포함)
src/wifi_config.c/.h    패치 가능한 flash 설정 블록
src/tusb_config.h       TinyUSB 설정
src/lwipopts.h          lwIP 설정 (NO_SYS, IPv4, UDP + DHCP)
tools/uf2-wifi-config.html   브라우저용 .uf2 자격증명 주입기

메인 루프는 블로킹하지 않습니다. Wi-Fi 접속은 cyw43_arch_wifi_connect_async() 로 시작하고 폴링합니다 — 블로킹 API를 쓰면 그동안 tud_task()가 멈춰서 USB 열거가 실패합니다. UDP 수신 콜백은 lwIP 컨텍스트에서 돌기 때문에 플래그만 세우고, 실제 HID 리포트 전송은 메인 루프에서 처리합니다.

설정 블록 레이아웃

tools/uf2-wifi-config.html 와 src/wifi_config.h 가 공유하는 형식입니다.

offset size 내용
0 16 매직 PICO2W-WIFI-CFG1 (NUL 없음)
16 4 version (LE uint32, 현재 1)
20 64 SSID, NUL 패딩
84 64 password, NUL 패딩
148 4 flags (예약, 0)

블록은 const volatile 이라 컴파일러가 값을 코드에 상수 접기(constant folding)하지 못하고, 반드시 flash에서 실제로 읽습니다. 그래서 나중에 바이트를 덮어써도 동작이 바뀝니다. RP2350 이미지에는 해시나 서명이 붙지 않으므로(picotool info로 확인 가능) 패치 후에도 부트롬이 정상적으로 실행합니다.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

0