Skip to content

defib

Universal camera recovery tool - shocking dead devices back to life

Lihan__

Published May 13, 2026

Original author: OpenIPCOriginal source (new tab)

defib

Project description

defib โ€” Defibrillating Dead IP Cameras Back to Life with W5500-Powered Pod TFTP

#W5500 #UDP #TFTP #IoTRecovery #OpenIPC #HiSilicon #EmbeddedNetworking #ZeroSetup #PSRAM #CameraHacking

๐Ÿ“š Open-source infrastructure tooling | OpenIPC ecosystem, professional/hobbyist IP camera recovery Hardware-verified on real HiSilicon/Goke IP cameras with measured end-to-end flash timings published in the PR.


01 โ€” What is this project?

Bricked IP cameras are a fact of life for anyone working in the OpenIPC ecosystem. A failed firmware flash, a corrupt U-Boot environment, or a mismatched SoC image can render a perfectly functional camera completely unresponsive โ€” no display, no SSH, no recovery button. The only path back is through the camera's UART boot ROM, and existing workflows are painful: they require sudo, fight with system services over port 69, demand manual NIC IP assignments on the camera's subnet, and collapse in automated test-rack environments.

defib is a modern, async Python recovery tool for bricked IP cameras โ€” supporting HiSilicon, Goke, and 120+ SoC variants through UART serial, network, and bare-metal agent flash paths. Its name says everything: it shocks dead devices back to life. The tool runs as CLI, TUI, interactive Web UI (via WebSerial in Chrome/Edge), or headless JSON output for CI automation.

The key architectural advance in recent releases is the N8R8 rack pod: a dedicated hardware unit that bridges the host (connected over WiFi) to the camera under recovery (connected via hardwired Ethernet). The pod's W5500 chip provides the isolated camera-side LAN, and a tiny in-pod TFTP server (tftpd.c, RFC 1350) lets the camera's U-Boot fetch firmware directly from the pod at 192.168.1.1:69 โ€” eliminating every host-side setup step.


02 โ€” Why async Python + a dedicated hardware pod?

๐Ÿ”ท Boot ROM timing windows demand async orchestration

Recovering a HiSilicon camera is a multi-phase race: catch the boot ROM's sub-100 ms marker window, negotiate DDR init, send SPL, break into U-Boot console, configure networking, flash each partition with CRC32 verification. A synchronous tool blocks at every step and misses timing windows. defib's asyncio architecture runs UART, network, and power-cycle operations concurrently โ€” and even moves the boot ROM catch loop into hardware (Vectis bridge or the pod itself) when network round-trip latency is too high.

๐Ÿ”ท The port-69 conflict is a real operational problem

Linux reserves port 69. A host-side TFTP server for camera recovery collides with dnsmasq, requires sudo, and requires manually assigning an IP address on the camera's subnet to a host NIC. These steps break silently in CI, conflict in multi-camera racks, and add minutes of manual setup per session. The pod-hosted TFTP path offloads all of this to the pod's W5500 interface โ€” the host simply POSTs firmware bytes over WiFi HTTP, and U-Boot pulls them from 192.168.1.1:69 with zero host configuration.

๐Ÿ”ท Performance tradeoffs are measured and documented

The PR documents real end-to-end timings on hi3516ev300-nor-neo (kernel 2.0 MB + rootfs 4.2 MB):

MethodTotalHost setup
Agent write_flash (fastest)92 snone
Host TFTP + sf write132 ssudo + dnsmasq + NIC IP
Pod TFTP + sf write193 snone

Pod TFTP is slower than host TFTP (WiFi traversed twice) but wins decisively on operational simplicity, making it the natural fallback when the agent path is unavailable for a given SoC.


03 โ€” System Architecture

 

๐Ÿ”ท Three Recovery Paths โ€” defib selects automatically based on camera state

Not all bricked cameras are in the same state. defib detects the camera's condition and chooses the appropriate recovery path automatically.

PathCamera StateNetwork UsedW5500 Role
โ‘  Bare-Metal AgentBootloader alive, agent-capable SoCUART only (921600 baud)Not used
โ‘ก Pod TFTP (W5500)Bootloader (U-Boot) alive, no agent supportEthernet via W5500TFTP server at 192.168.1.1:69
โ‘ข Boot ROM UARTBootloader completely goneUART onlyNot used

Path โ‘  is the fastest (92 s for full 8 MB flash). The bare-metal agent replaces U-Boot entirely and transfers firmware directly over UART using COBS binary protocol.

Path โ‘ก is where W5500 is essential. U-Boot is alive but the firmware is corrupted. U-Boot has a built-in TFTP client โ€” it requests firmware from 192.168.1.1:69 over Ethernet. The W5500 chip on the pod serves as that TFTP server, staging firmware from PSRAM.

Path โ‘ข is for the worst case โ€” even U-Boot is gone. The SoC's boot ROM (hardwired into silicon, cannot be erased) accepts data over UART. Vectis bridge handles the sub-100 ms timing window required to catch the boot ROM.

 
๐Ÿ”ท Three Recovery Paths โ€” defib selects automatically based on camera state
 

04 โ€” Why W5500? โญ

๐Ÿ”ท Hardware TCP/IP offload โ€” UDP socket mode for RFC 1350 TFTP

The pod's TFTP server (tftpd.c) is bound directly to the W5500 interface via UDP socket mode (Sn_MR_UDP). RFC 1350 TFTP is inherently UDP-based: the client (U-Boot) sends a Read Request to port 69, the server responds with data blocks from a random ephemeral port, and the client ACKs each 512-byte block. W5500's hardware UDP/IP stack handles all of this โ€” checksum computation, ARP, IP framing โ€” without consuming MCU cycles. The MCU's job is simply to feed block data from PSRAM into the W5500 transmit buffer.

This is the correct tool for TFTP: TCP's connection overhead and retransmission logic would add unnecessary complexity to a protocol that already has its own ACK mechanism built in.

๐Ÿ”ท Isolated camera-side LAN โ€” the architectural key

W5500 gives the pod a dedicated, hardwired Ethernet interface entirely separate from the host WiFi path. The camera sees a clean local network (192.168.1.0/24) with the pod as its default gateway at 192.168.1.1. There is no NAT in the TFTP data path โ€” U-Boot speaks directly to the W5500 socket. This physical separation is what enables zero host NIC plumbing: the host never needs to appear on the camera's subnet.

๐Ÿ”ท PSRAM staging with zero-copy ownership transfer

The pod firmware uses tftpd_add_file_owned() โ€” a zero-copy file registration that transfers PSRAM buffer ownership directly to the TFTP server. The initial naรฏve double-buffer implementation hit OOM on a 4 MB rootfs with only 8 MB of PSRAM; zero-copy ownership resolved it. W5500 reads directly from those PSRAM buffers during block transmission, keeping the MCU's working memory footprint flat regardless of firmware image size.

 


05 โ€” Key Components

๐ŸŒ WIZnet W5500 โ€” UDP Socket Mode (Sn_MR_UDP) for RFC 1350 TFTP

The camera-side network interface of the N8R8 pod. Operates in hardware UDP socket mode, hosting the pod's TFTP server at 192.168.1.1:69. W5500's hardwired TCP/IP stack manages all IP/UDP framing and ARP resolution autonomously, freeing the pod MCU to focus on PSRAM buffer management and HTTP API serving. The SPI bus between MCU and W5500 carries only application-layer data.

๐Ÿ defib โ€” Async Python Recovery Tool

The host-side orchestrator. RackController (src/defib/power/rack.py) provides tftp_put, tftp_delete, tftp_clear, and tftp_list as async methods wrapping synchronous urllib HTTP calls via asyncio.to_thread. Path-traversal validation on filenames prevents security issues with pod-side file storage. Errors surface as PowerControllerError with the pod's JSON error body, enabling caller-side fallback to alternate flash paths.

๐Ÿ“ฆ N8R8 Pod Hardware

A dedicated recovery appliance: MCU (firmware not public per project policy), W5500 (camera-side Ethernet), PSRAM (firmware staging, 8 MB on prototype), WiFi (host-side connectivity). Designed to sit permanently in a camera test rack with automated power cycling via RouterOS PoE API or UART RTS/DTR lines.

๐Ÿค– Flash Agent (Bare-Metal, 921600 baud)

For supported SoCs, defib's bare-metal agent replaces U-Boot in the boot chain entirely. It uses COBS binary protocol at 921600 baud, achieving full 8 MB OpenIPC firmware flash + CRC32 verify in ~77 s โ€” faster than any TFTP path. The W5500-hosted Pod TFTP is the fallback when the agent is unavailable for a given SoC.

๐ŸŒ Vectis UART Bridge

A companion C tool (OpenIPC/vectis) that exposes camera UART over TCP using RFC 2217 (Telnet COM Port Control). Includes a vendor extension sub-option (BOOTROM-CATCH, sub-option 50) that runs the HiSilicon boot ROM catch loop locally in bridge hardware โ€” eliminating the round-trip latency problem that causes remote clients to miss the <100 ms boot ROM window.


06 โ€” Application Scenarios

01. Automated Camera Recovery Rack

A test rack holds 10 IP cameras. defib runs as a service with RackController managing each pod. Firmware CI pushes a new OpenIPC build; defib automatically stages kernel + rootfs into each pod's W5500 TFTP server, power-cycles each camera via RouterOS PoE API, and confirms successful boot โ€” no human interaction, no sudo, no port conflicts.

02. Field Recovery of Vendor-Firmwared Cameras

An integrator has a batch of HiSilicon cameras with vendor firmware to convert to OpenIPC. defib's restore command takes an ipctool backup file, extracts the partition layout from the embedded YAML, and reflashes โ€” using pod TFTP to transfer partitions when the laptop's NIC cannot be easily placed on the camera's subnet.

03. OpenIPC Development Workflow

A developer iterates on OpenIPC kernel builds. Each cycle: defib install -c hi3516ev300 --firmware openipc.tgz -p /dev/uart-cam --power-cycle. Pod TFTP provides consistent timing without requiring the developer to reconfigure their laptop's network stack between test iterations.

04. Web-Based Recovery (No Install)

A non-technical user opens openipc.github.io/defib/ in Chrome. The WebSerial UI connects to the camera via USB-serial adapter and guides through chip selection, firmware download, and flash โ€” no Python, no CLI, no package manager required.


Conclusion

defib demonstrates that a W5500 chip in a purpose-built recovery pod can eliminate every host-side network setup requirement for embedded firmware flashing โ€” turning a complex multi-step manual process into a single command.

  • โœ… W5500 UDP socket mode hosts a lightweight RFC 1350 TFTP server at 192.168.1.1:69
  • โœ… Camera-side LAN physically isolated from host network โ€” zero NIC plumbing
  • โœ… PSRAM staging with zero-copy ownership transfer eliminates OOM on large firmware
  • โœ… 120+ HiSilicon/Goke SoC variants supported
  • โœ… Three complementary flash paths: agent (fastest), pod TFTP (zero-setup), host TFTP (fallback)
  • โœ… End-to-end verified: 6.2 MB firmware staged and flashed in one command, 193 s total
  • โœ… 486 tests passing across the Python host-side codebase
  • โœ… Cross-platform: Linux, macOS, Windows CLI + WebSerial browser UI

Q&A

Q. Why UDP and not TCP for the pod's TFTP server? RFC 1350 TFTP is a UDP protocol by specification. U-Boot's built-in TFTP client speaks only UDP. W5500's hardware UDP socket mode (Sn_MR_UDP) is a natural fit โ€” no TCP connection state machine overhead for a block-transfer protocol that already includes its own per-block ACK mechanism.

Q. What happens if the pod runs out of PSRAM during staging? POST /tftp/<name> returns 503 with JSON body {"error":"oom","psram_largest_free":<bytes>} when PSRAM allocation fails. RackController.tftp_put surfaces this as PowerControllerError with the body, allowing the caller to fall back to host-side TFTP or implement chunked staging.

Q. Is the pod's tftpd.c firmware publicly available? Not currently โ€” it lives in a private branch of the rack repo per project policy. However, the host-side client interface is fully public in src/defib/power/rack.py, and the W5500 binding and PSRAM architecture are documented in code comments and the PR description.

Q. Can defib work without the N8R8 pod? Yes. defib has four independent recovery paths: direct USB-serial UART, Vectis RFC 2217 bridge, host-side TFTP (requires sudo + NIC setup), and pod TFTP via W5500. The pod is optional but eliminates all host network configuration.

Original Link: https://github.com/OpenIPC/defib



defib โ€” W5500 ํƒ‘์žฌ ๋ณต๊ตฌ Pod๋กœ ๋ฒฝ๋Œ๋œ IP ์นด๋ฉ”๋ผ๋ฅผ ๋˜์‚ด๋ฆฌ๋‹ค

#W5500 #UDP #TFTP #IoT๋ณต๊ตฌ #OpenIPC #HiSilicon #์ž„๋ฒ ๋””๋“œ๋„คํŠธ์›Œํ‚น #๋ฌด์„ค์ •ํ”Œ๋ž˜์‹œ #PSRAM #์นด๋ฉ”๋ผํ•ดํ‚น

๐Ÿ“š ์˜คํ”ˆ์†Œ์Šค ์ธํ”„๋ผ ํˆด๋ง | OpenIPC ์—์ฝ”์‹œ์Šคํ…œ, ์ „๋ฌธ/์ทจ๋ฏธ IP ์นด๋ฉ”๋ผ ๋ณต๊ตฌ ์‹ค์ œ HiSilicon/Goke IP ์นด๋ฉ”๋ผ๋กœ ํ•˜๋“œ์›จ์–ด ๊ฒ€์ฆ ์™„๋ฃŒ โ€” PR์— end-to-end ํ”Œ๋ž˜์‹œ ํƒ€์ด๋ฐ ์ธก์ •๊ฐ’์ด ๊ณต๊ฐœ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.


01 โ€” ์ด ํ”„๋กœ์ ํŠธ๋Š” ๋ฌด์—‡์ธ๊ฐ€?

๋ฒฝ๋Œ(brick)์ด ๋œ IP ์นด๋ฉ”๋ผ๋Š” OpenIPC ์—์ฝ”์‹œ์Šคํ…œ์—์„œ ์ผํ•˜๋Š” ์‚ฌ๋žŒ์ด๋ผ๋ฉด ๋ˆ„๊ตฌ๋‚˜ ๊ฒช๋Š” ํ˜„์‹ค์ž…๋‹ˆ๋‹ค. ํŽŒ์›จ์–ด ํ”Œ๋ž˜์‹œ ์‹คํŒจ, ์†์ƒ๋œ U-Boot ํ™˜๊ฒฝ, ์ž˜๋ชป ๋งค์นญ๋œ SoC ์ด๋ฏธ์ง€ ํ•˜๋‚˜๋กœ๋„ ๋ฉ€์ฉกํ•œ ์นด๋ฉ”๋ผ๊ฐ€ ์™„์ „ํžˆ ๋จนํ†ต์ด ๋ฉ๋‹ˆ๋‹ค โ€” ๋””์Šคํ”Œ๋ ˆ์ด ์—†์Œ, SSH ์—†์Œ, ๋ณต๊ตฌ ๋ฒ„ํŠผ ์—†์Œ. ์œ ์ผํ•œ ๋ณต๊ตฌ ๊ฒฝ๋กœ๋Š” ์นด๋ฉ”๋ผ UART ๋ถ€ํŠธ ROM์„ ํ†ตํ•˜๋Š” ๊ฒƒ๋ฟ์ธ๋ฐ, ๊ธฐ์กด ์›Œํฌํ”Œ๋กœ์šฐ๋Š” ๋„ˆ๋ฌด ๋ฒˆ๊ฑฐ๋กญ์Šต๋‹ˆ๋‹ค: sudo ํ•„์š”, ํฌํŠธ 69 ์„œ๋น„์Šค ์ถฉ๋Œ, ์นด๋ฉ”๋ผ ์„œ๋ธŒ๋„ท์— ์ˆ˜๋™ NIC IP ํ• ๋‹น, ์ž๋™ํ™” ํ…Œ์ŠคํŠธ ๋ž™์—์„œ๋Š” ๋”์šฑ ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค.

defib๋Š” ๋ฒฝ๋Œ IP ์นด๋ฉ”๋ผ ๋ณต๊ตฌ๋ฅผ ์œ„ํ•œ ํ˜„๋Œ€์ ์ธ async Python ๋„๊ตฌ์ž…๋‹ˆ๋‹ค โ€” UART ์‹œ๋ฆฌ์–ผ, ๋„คํŠธ์›Œํฌ, ๋ฒ ์–ด๋ฉ”ํƒˆ ์—์ด์ „ํŠธ ํ”Œ๋ž˜์‹œ ๊ฒฝ๋กœ๋ฅผ ํ†ตํ•ด HiSilicon, Goke ๋“ฑ 120๊ฐœ ์ด์ƒ์˜ SoC ๋ณ€์ข…์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฆ„์ด ๋ชจ๋“  ๊ฒƒ์„ ๋งํ•ด์ค๋‹ˆ๋‹ค: ์ฃฝ์€ ์žฅ์น˜๋ฅผ ๋‹ค์‹œ ์‚ด๋ฆฝ๋‹ˆ๋‹ค(์ œ์„ธ๋™). CLI, TUI, ์›น UI(Chrome/Edge์˜ WebSerial), ๋˜๋Š” CI ์ž๋™ํ™”๋ฅผ ์œ„ํ•œ headless JSON ์ถœ๋ ฅ์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

์ตœ๊ทผ ๋ฆด๋ฆฌ์ฆˆ์˜ ํ•ต์‹ฌ ์•„ํ‚คํ…์ฒ˜ ๊ฐœ์„ ์€ N8R8 ๋ž™ Pod์ž…๋‹ˆ๋‹ค: ํ˜ธ์ŠคํŠธ(WiFi ์—ฐ๊ฒฐ)์™€ ๋ณต๊ตฌ ๋Œ€์ƒ ์นด๋ฉ”๋ผ(์œ ์„  Ethernet ์—ฐ๊ฒฐ)๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ์ „์šฉ ํ•˜๋“œ์›จ์–ด ์œ ๋‹›์ž…๋‹ˆ๋‹ค. Pod์˜ W5500 ์นฉ์ด ๊ฒฉ๋ฆฌ๋œ ์นด๋ฉ”๋ผ ์ธก LAN์„ ์ œ๊ณตํ•˜๊ณ , Pod ๋‚ด์žฅ TFTP ์„œ๋ฒ„(tftpd.c, RFC 1350)๊ฐ€ ์นด๋ฉ”๋ผ์˜ U-Boot์ด 192.168.1.1:69์—์„œ ์ง์ ‘ ํŽŒ์›จ์–ด๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค โ€” ํ˜ธ์ŠคํŠธ ์ธก TFTP ์„œ๋ฒ„, sudo, NIC ํ”Œ๋Ÿผ๋น™์ด ๋ชจ๋‘ ๋ถˆํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.


02 โ€” ์™œ async Python + ์ „์šฉ ํ•˜๋“œ์›จ์–ด Pod์ธ๊ฐ€?

๐Ÿ”ท ๋ถ€ํŠธ ROM ํƒ€์ด๋ฐ ์œˆ๋„์šฐ๋Š” async ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜์„ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค

HiSilicon ์นด๋ฉ”๋ผ ๋ณต๊ตฌ๋Š” ๋ฉ€ํ‹ฐ ํŽ˜์ด์ฆˆ ๋ ˆ์ด์Šค์ž…๋‹ˆ๋‹ค: 100 ms ์ด๋‚ด์˜ ๋ถ€ํŠธ ROM ๋งˆ์ปค ์œˆ๋„์šฐ ์žก๊ธฐ, DDR ์ดˆ๊ธฐํ™” ํ˜‘์ƒ, SPL ์ „์†ก, U-Boot ์ฝ˜์†” ์ง„์ž…, ๋„คํŠธ์›Œํ‚น ์„ค์ •, CRC32 ๊ฒ€์ฆ๊ณผ ํ•จ๊ป˜ ๊ฐ ํŒŒํ‹ฐ์…˜ ํ”Œ๋ž˜์‹œ. ๋™๊ธฐ์‹ ๋„๊ตฌ๋Š” ๋ชจ๋“  ๋‹จ๊ณ„์—์„œ ๋ธ”๋กœํ‚น๋˜์–ด ํƒ€์ด๋ฐ ์œˆ๋„์šฐ๋ฅผ ๋†“์นฉ๋‹ˆ๋‹ค. defib์˜ asyncio ์•„ํ‚คํ…์ฒ˜๋Š” UART, ๋„คํŠธ์›Œํฌ, ์ „์› ์‚ฌ์ดํด ์ž‘์—…์„ ๋™์‹œ์— ์‹คํ–‰ํ•˜๋ฉฐ, ๋„คํŠธ์›Œํฌ ์™•๋ณต ์ง€์—ฐ์ด ๋„ˆ๋ฌด ๋†’์„ ๋•Œ๋Š” ๋ถ€ํŠธ ROM ์บ์น˜ ๋ฃจํ”„ ์ž์ฒด๋ฅผ ํ•˜๋“œ์›จ์–ด(Vectis ๋ธŒ๋ฆฌ์ง€ ๋˜๋Š” Pod)๋กœ ์ด์ „ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”ท ํฌํŠธ 69 ์ถฉ๋Œ์€ ์‹ค์ œ ์šด์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค

Linux๋Š” ํฌํŠธ 69๋ฅผ ์˜ˆ์•ฝํ•ฉ๋‹ˆ๋‹ค. ์นด๋ฉ”๋ผ ๋ณต๊ตฌ์šฉ ํ˜ธ์ŠคํŠธ ์ธก TFTP ์„œ๋ฒ„๋Š” dnsmasq์™€ ์ถฉ๋Œํ•˜๊ณ , sudo๊ฐ€ ํ•„์š”ํ•˜๋ฉฐ, ์นด๋ฉ”๋ผ ์„œ๋ธŒ๋„ท์— ํ˜ธ์ŠคํŠธ NIC IP๋ฅผ ์ˆ˜๋™ ํ• ๋‹นํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋‹จ๊ณ„๋“ค์€ CI์—์„œ ์กฐ์šฉํžˆ ์‹คํŒจํ•˜๊ณ , ๋ฉ€ํ‹ฐ ์นด๋ฉ”๋ผ ๋ž™์—์„œ ์ถฉ๋Œํ•˜๋ฉฐ, ์„ธ์…˜๋งˆ๋‹ค ์ˆ˜ ๋ถ„์˜ ์ˆ˜๋™ ์„ค์ •์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. Pod ํ˜ธ์Šคํ‹ฐ๋“œ TFTP ๊ฒฝ๋กœ๋Š” ์ด ๋ชจ๋“  ๊ฒƒ์„ Pod์˜ W5500 ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์˜คํ”„๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค โ€” ํ˜ธ์ŠคํŠธ๋Š” ๋‹จ์ˆœํžˆ WiFi HTTP๋กœ ํŽŒ์›จ์–ด ๋ฐ”์ดํŠธ๋ฅผ POSTํ•˜๊ณ , U-Boot์€ 192.168.1.1:69์—์„œ ๊ฐ€์ ธ๊ฐ‘๋‹ˆ๋‹ค.

๐Ÿ”ท ์„ฑ๋Šฅ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„๋Š” ์ธก์ •๋˜๊ณ  ๋ฌธ์„œํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค

PR์— hi3516ev300-nor-neo ์‹ค์ธก ํƒ€์ด๋ฐ์ด ๊ณต๊ฐœ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค (์ปค๋„ 2.0 MB + rootfs 4.2 MB):

๋ฐฉ๋ฒ•์ด ์‹œ๊ฐ„ํ˜ธ์ŠคํŠธ ์„ค์ •
Agent write_flash (์ตœ๊ณ ์†)92 s์—†์Œ
ํ˜ธ์ŠคํŠธ TFTP + sf write132 ssudo + dnsmasq + NIC IP
Pod TFTP + sf write193 s์—†์Œ

Pod TFTP๊ฐ€ ํ˜ธ์ŠคํŠธ TFTP๋ณด๋‹ค ๋А๋ฆฐ ์ด์œ ๋Š” WiFi๋ฅผ ๋‘ ๋ฒˆ ๊ฒฝ์œ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์ง€๋งŒ, ์šด์˜ ๋‹จ์ˆœ์„ฑ์—์„œ ์••๋„์ ์œผ๋กœ ์šฐ์œ„๋ฅผ ์ ํ•˜๋ฉฐ ์—์ด์ „ํŠธ ๊ฒฝ๋กœ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•œ SoC์—์„œ์˜ ์ž์—ฐ์Šค๋Ÿฌ์šด ํด๋ฐฑ์ด ๋ฉ๋‹ˆ๋‹ค.


03 โ€” ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜

 

๐Ÿ”ท ์„ธ ๊ฐ€์ง€ ๋ณต๊ตฌ ๊ฒฝ๋กœ โ€” defib๊ฐ€ ์นด๋ฉ”๋ผ ์ƒํƒœ์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค

๋ฒฝ๋Œ ์ƒํƒœ์˜ ์นด๋ฉ”๋ผ๊ฐ€ ๋ชจ๋‘ ๊ฐ™์€ ์ƒํƒœ์ธ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. defib๋Š” ์นด๋ฉ”๋ผ ์ƒํƒœ ๋ฐ ์ œ์กฐ์‚ฌ๋ฅผ ๊ฐ์ง€ํ•˜์—ฌ ์ ํ•ฉํ•œ ๋ณต๊ตฌ ๊ฒฝ๋กœ๋ฅผ ์ž๋™์œผ๋กœ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

๊ฒฝ๋กœ์นด๋ฉ”๋ผ ์ƒํƒœ๋„คํŠธ์›Œํฌ ์‚ฌ์šฉW5500 ์—ญํ• 
โ‘  ๋ฒ ์–ด๋ฉ”ํƒˆ ์—์ด์ „ํŠธ๋ถ€ํŠธ๋กœ๋” ์‚ด์•„์žˆ์Œ, ์—์ด์ „ํŠธ ์ง€์› SoCUART๋งŒ ์‚ฌ์šฉ (921600 baud)๋ฏธ์‚ฌ์šฉ
โ‘ก Pod TFTP (W5500)๋ถ€ํŠธ๋กœ๋”(U-Boot) ์‚ด์•„์žˆ์Œ, ์—์ด์ „ํŠธ ๋ฏธ์ง€์›W5500์„ ํ†ตํ•œ Ethernet192.168.1.1:69 TFTP ์„œ๋ฒ„
โ‘ข ๋ถ€ํŠธ ROM UART๋ถ€ํŠธ๋กœ๋”๊นŒ์ง€ ์™„์ „ํžˆ ๋‚ ์•„๊ฐ„ ์ƒํƒœUART๋งŒ ์‚ฌ์šฉ๋ฏธ์‚ฌ์šฉ

๊ฒฝ๋กœ โ‘  ์ด ๊ฐ€์žฅ ๋น ๋ฆ…๋‹ˆ๋‹ค(์ „์ฒด 8 MB ํ”Œ๋ž˜์‹œ ๊ธฐ์ค€ 92 s). ๋ฒ ์–ด๋ฉ”ํƒˆ ์—์ด์ „ํŠธ๊ฐ€ U-Boot์„ ์™„์ „ํžˆ ๋Œ€์ฒดํ•˜์—ฌ COBS ๋ฐ”์ด๋„ˆ๋ฆฌ ํ”„๋กœํ† ์ฝœ๋กœ UART๋ฅผ ํ†ตํ•ด ํŽŒ์›จ์–ด๋ฅผ ์ง์ ‘ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

๊ฒฝ๋กœ โ‘ก ๊ฐ€ W5500์ด ํ•ต์‹ฌ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. U-Boot์€ ์‚ด์•„์žˆ์ง€๋งŒ ํŽŒ์›จ์–ด๊ฐ€ ์†์ƒ๋œ ์ƒํƒœ์ž…๋‹ˆ๋‹ค. U-Boot์—๋Š” ๋‚ด์žฅ TFTP ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์žˆ์–ด Ethernet์„ ํ†ตํ•ด 192.168.1.1:69์—์„œ ํŽŒ์›จ์–ด๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. Pod์˜ W5500 ์นฉ์ด ๊ทธ TFTP ์„œ๋ฒ„ ์—ญํ• ์„ ํ•˜๋ฉฐ PSRAM์— ์Šคํ…Œ์ด์ง•๋œ ํŽŒ์›จ์–ด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๊ฒฝ๋กœ โ‘ข ์€ ์ตœ์•…์˜ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค โ€” U-Boot๊นŒ์ง€ ์™„์ „ํžˆ ๋‚ ์•„๊ฐ„ ์ƒํƒœ. SoC ์‹ค๋ฆฌ์ฝ˜์— ํ•˜๋“œ์›จ์–ด์ ์œผ๋กœ ๊ณ ์ •๋œ ๋ถ€ํŠธ ROM(์ ˆ๋Œ€ ์‚ญ์ œ ๋ถˆ๊ฐ€)์ด UART๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค. Vectis ๋ธŒ๋ฆฌ์ง€๊ฐ€ ๋ถ€ํŠธ ROM ์บ์น˜์— ํ•„์š”ํ•œ 100 ms ์ด๋‚ด์˜ ํƒ€์ด๋ฐ ์œˆ๋„์šฐ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

 
๐Ÿ”ท ์„ธ ๊ฐ€์ง€ ๋ณต๊ตฌ ๊ฒฝ๋กœ โ€” defib๊ฐ€ ์นด๋ฉ”๋ผ ์ƒํƒœ์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค
 

04 โ€” ์™œ W5500์ธ๊ฐ€? โญ

๐Ÿ”ท ํ•˜๋“œ์›จ์–ด TCP/IP ์˜คํ”„๋กœ๋“œ โ€” RFC 1350 TFTP๋ฅผ ์œ„ํ•œ UDP ์†Œ์ผ“ ๋ชจ๋“œ

Pod์˜ TFTP ์„œ๋ฒ„(tftpd.c)๋Š” W5500 ์ธํ„ฐํŽ˜์ด์Šค์— ์ง์ ‘ ๋ฐ”์ธ๋”ฉ๋œ UDP ์†Œ์ผ“ ๋ชจ๋“œ(Sn_MR_UDP)๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. RFC 1350 TFTP๋Š” ๋ณธ์งˆ์ ์œผ๋กœ UDP ๊ธฐ๋ฐ˜ ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค: ํด๋ผ์ด์–ธํŠธ(U-Boot)๊ฐ€ ํฌํŠธ 69๋กœ ์ฝ๊ธฐ ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด, ์„œ๋ฒ„๊ฐ€ ์ž„์˜์˜ ์—ํ”ผ๋ฉ”๋Ÿด ํฌํŠธ์—์„œ 512๋ฐ”์ดํŠธ ๋ฐ์ดํ„ฐ ๋ธ”๋ก์œผ๋กœ ์‘๋‹ตํ•˜๊ณ , ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ ๋ธ”๋ก์„ ACKํ•ฉ๋‹ˆ๋‹ค. W5500์˜ ํ•˜๋“œ์›จ์–ด UDP/IP ์Šคํƒ์ด ์ฒดํฌ์„ฌ ๊ณ„์‚ฐ, ARP, IP ํ”„๋ ˆ์ด๋ฐ์„ ๋ชจ๋‘ ์ž์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค โ€” MCU ์‚ฌ์ดํด์„ ์†Œ๋ชจํ•˜์ง€ ์•Š๊ณ . MCU์˜ ์—ญํ• ์€ ๋‹จ์ˆœํžˆ PSRAM์—์„œ W5500 ์†ก์‹  ๋ฒ„ํผ๋กœ ๋ธ”๋ก ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต๊ธ‰ํ•˜๋Š” ๊ฒƒ๋ฟ์ž…๋‹ˆ๋‹ค.

TFTP์— ์ •ํ™•ํžˆ ๋งž๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค: TCP์˜ ์—ฐ๊ฒฐ ์˜ค๋ฒ„ํ—ค๋“œ์™€ ์žฌ์ „์†ก ๋กœ์ง์€ ์ด๋ฏธ ์ž์ฒด ACK ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๊ฐ–์ถ˜ ๋‹จ์ˆœ ๋ธ”๋ก ์ „์†ก ํ”„๋กœํ† ์ฝœ์— ๋ถˆํ•„์š”ํ•œ ๋ณต์žก์„ฑ์„ ์ถ”๊ฐ€ํ•  ๋ฟ์ž…๋‹ˆ๋‹ค.

๐Ÿ”ท ๊ฒฉ๋ฆฌ๋œ ์นด๋ฉ”๋ผ ์ธก LAN โ€” ์•„ํ‚คํ…์ฒ˜์˜ ํ•ต์‹ฌ

W5500์€ Pod์— ํ˜ธ์ŠคํŠธ WiFi ๊ฒฝ๋กœ์™€ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ์™„์ „ํžˆ ๋ถ„๋ฆฌ๋œ ์ „์šฉ ์œ ์„  Ethernet ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์นด๋ฉ”๋ผ๋Š” ๊นจ๋—ํ•œ ๋กœ์ปฌ ๋„คํŠธ์›Œํฌ(192.168.1.0/24)๋ฅผ ๋ณด๊ฒŒ ๋˜๋ฉฐ, Pod๊ฐ€ 192.168.1.1์—์„œ ๊ฒŒ์ดํŠธ์›จ์ด ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. TFTP ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ์— NAT๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค โ€” U-Boot์ด W5500 ์†Œ์ผ“์— ์ง์ ‘ ํ†ต์‹ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌผ๋ฆฌ์  ๋ถ„๋ฆฌ๊ฐ€ ํ˜ธ์ŠคํŠธ NIC ํ”Œ๋Ÿผ๋น™ ์ œ๋กœ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค: ํ˜ธ์ŠคํŠธ๋Š” ์นด๋ฉ”๋ผ ์„œ๋ธŒ๋„ท์— ์ ˆ๋Œ€ ๋“ฑ์žฅํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๐Ÿ”ท ์ œ๋กœ์นดํ”ผ ์˜ค๋„ˆ์‹ญ ์ „์†ก์„ ํ†ตํ•œ PSRAM ์Šคํ…Œ์ด์ง•

Pod ํŽŒ์›จ์–ด๋Š” tftpd_add_file_owned()๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค โ€” PSRAM ๋ฒ„ํผ ์˜ค๋„ˆ์‹ญ์„ TFTP ์„œ๋ฒ„๋กœ ์ง์ ‘ ์ด์ „ํ•˜๋Š” ์ œ๋กœ์นดํ”ผ ํŒŒ์ผ ๋“ฑ๋ก ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ดˆ๊ธฐ ๋‹จ์ˆœ ๊ตฌํ˜„์˜ ์ด์ค‘ ๋ฒ„ํผ ๋ฐฉ์‹์€ 4 MB rootfs์—์„œ 8 MB PSRAM OOM์— ๊ฑธ๋ ธ๊ณ , ์ œ๋กœ์นดํ”ผ ์˜ค๋„ˆ์‹ญ์ด ์ด๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. W5500์€ ๋ธ”๋ก ์ „์†ก ์ค‘ PSRAM ๋ฒ„ํผ์—์„œ ์ง์ ‘ ์ฝ์–ด๊ฐ€๋ฏ€๋กœ, ํŽŒ์›จ์–ด ์ด๋ฏธ์ง€ ํฌ๊ธฐ์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ MCU ์ž‘์—… ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ผ์ •ํ•˜๊ฒŒ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.


05 โ€” ์ฃผ์š” ์ปดํฌ๋„ŒํŠธ

๐ŸŒ WIZnet W5500 โ€” UDP ์†Œ์ผ“ ๋ชจ๋“œ (Sn_MR_UDP) for RFC 1350 TFTP

N8R8 Pod์˜ ์นด๋ฉ”๋ผ ์ธก ๋„คํŠธ์›Œํฌ ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค. ํ•˜๋“œ์›จ์–ด UDP ์†Œ์ผ“ ๋ชจ๋“œ๋กœ ๋™์ž‘ํ•˜๋ฉฐ 192.168.1.1:69์—์„œ Pod์˜ TFTP ์„œ๋ฒ„๋ฅผ ํ˜ธ์ŠคํŒ…ํ•ฉ๋‹ˆ๋‹ค. W5500์˜ ํ•˜๋“œ์™€์ด์–ด๋“œ TCP/IP ์Šคํƒ์ด IP/UDP ํ”„๋ ˆ์ด๋ฐ๊ณผ ARP ํ•ด์„์„ ์ž์œจ ์ฒ˜๋ฆฌํ•˜์—ฌ Pod MCU๊ฐ€ PSRAM ๋ฒ„ํผ ๊ด€๋ฆฌ์™€ HTTP API ์„œ๋น™์—๋งŒ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. MCU์™€ W5500 ๊ฐ„์˜ SPI ๋ฒ„์Šค์—๋Š” ์‘์šฉ ๊ณ„์ธต ๋ฐ์ดํ„ฐ๋งŒ ํ๋ฆ…๋‹ˆ๋‹ค.

๐Ÿ defib โ€” Async Python ๋ณต๊ตฌ ๋„๊ตฌ

ํ˜ธ์ŠคํŠธ ์ธก ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ์ž…๋‹ˆ๋‹ค. RackController(src/defib/power/rack.py)๊ฐ€ tftp_put, tftp_delete, tftp_clear, tftp_list๋ฅผ asyncio.to_thread๋กœ ๋ž˜ํ•‘๋œ async ๋ฉ”์„œ๋“œ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ๋ช…์˜ ๊ฒฝ๋กœ ์ˆœํšŒ ๊ฒ€์ฆ์ด Pod ์ธก ํŒŒ์ผ ์ €์žฅ ๋ณด์•ˆ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์—๋Ÿฌ๋Š” Pod์˜ JSON ์—๋Ÿฌ ๋ฐ”๋””์™€ ํ•จ๊ป˜ PowerControllerError๋กœ ํ‘œ๋ฉดํ™”๋˜์–ด, ํ˜ธ์ถœ์ž๊ฐ€ ๋Œ€์ฒด ํ”Œ๋ž˜์‹œ ๊ฒฝ๋กœ๋กœ ํด๋ฐฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“ฆ N8R8 Pod ํ•˜๋“œ์›จ์–ด

์ „์šฉ ๋ณต๊ตฌ ์–ดํ”Œ๋ผ์ด์–ธ์Šค์ž…๋‹ˆ๋‹ค: MCU (ํŽŒ์›จ์–ด๋Š” ํ”„๋กœ์ ํŠธ ์ •์ฑ…์ƒ ๋น„๊ณต๊ฐœ), W5500 (์นด๋ฉ”๋ผ ์ธก Ethernet), PSRAM (ํŽŒ์›จ์–ด ์Šคํ…Œ์ด์ง•, ํ”„๋กœํ† ํƒ€์ž… 8 MB), WiFi (ํ˜ธ์ŠคํŠธ ์ธก ์—ฐ๊ฒฐ). RouterOS PoE API ๋˜๋Š” UART RTS/DTR๋กœ ์ž๋™ ์ „์› ์‚ฌ์ดํด๋ง์„ ์ง€์›ํ•˜๋ฉฐ ์นด๋ฉ”๋ผ ํ…Œ์ŠคํŠธ ๋ž™์— ์ƒ์‹œ ์„ค์น˜ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿค– ํ”Œ๋ž˜์‹œ ์—์ด์ „ํŠธ (๋ฒ ์–ด๋ฉ”ํƒˆ, 921600 baud)

์ง€์›๋˜๋Š” SoC์—์„œ๋Š” defib์˜ ๋ฒ ์–ด๋ฉ”ํƒˆ ์—์ด์ „ํŠธ๊ฐ€ ๋ถ€ํŠธ ์ฒด์ธ์—์„œ U-Boot์„ ์™„์ „ํžˆ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค. COBS ๋ฐ”์ด๋„ˆ๋ฆฌ ํ”„๋กœํ† ์ฝœ์„ 921600 baud๋กœ ์‚ฌ์šฉํ•˜์—ฌ ์ „์ฒด 8 MB OpenIPC ํŽŒ์›จ์–ด๋ฅผ ํ”Œ๋ž˜์‹œ+๊ฒ€์ฆ๊นŒ์ง€ ์•ฝ 77 s์— ์™„๋ฃŒํ•ฉ๋‹ˆ๋‹ค. W5500 ํ˜ธ์Šคํ‹ฐ๋“œ Pod TFTP๋Š” ํŠน์ • SoC์—์„œ ์—์ด์ „ํŠธ ์ง€์›์ด ์—†์„ ๋•Œ์˜ ํด๋ฐฑ์ž…๋‹ˆ๋‹ค.

๐ŸŒ Vectis UART ๋ธŒ๋ฆฌ์ง€

์นด๋ฉ”๋ผ UART๋ฅผ RFC 2217 (Telnet COM Port Control)๋กœ TCP๋ฅผ ํ†ตํ•ด ๋…ธ์ถœํ•˜๋Š” ๋™๋ฐ˜ C ๋„๊ตฌ(OpenIPC/vectis)์ž…๋‹ˆ๋‹ค. ๋ฒค๋” ํ™•์žฅ ์„œ๋ธŒ ์˜ต์…˜(BOOTROM-CATCH, ์„œ๋ธŒ ์˜ต์…˜ 50)์œผ๋กœ HiSilicon ๋ถ€ํŠธ ROM ์บ์น˜ ๋ฃจํ”„๋ฅผ ๋ธŒ๋ฆฌ์ง€ ํ•˜๋“œ์›จ์–ด ๋กœ์ปฌ์—์„œ ์‹คํ–‰ํ•˜์—ฌ ์™•๋ณต ์ง€์—ฐ ๋ฌธ์ œ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.


06 โ€” ํ™œ์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค

01. ์ž๋™ํ™” ์นด๋ฉ”๋ผ ๋ณต๊ตฌ ๋ž™

ํ…Œ์ŠคํŠธ ๋ž™์— IP ์นด๋ฉ”๋ผ 10๋Œ€๊ฐ€ ์žˆ๋Š” ํ™˜๊ฒฝ์„ ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. defib๊ฐ€ ์„œ๋น„์Šค๋กœ ์‹คํ–‰๋˜๋ฉฐ RackController๊ฐ€ ๊ฐ Pod๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ํŽŒ์›จ์–ด CI๊ฐ€ ์ƒˆ OpenIPC ๋นŒ๋“œ๋ฅผ ํ‘ธ์‹œํ•˜๋ฉด defib๊ฐ€ ์ž๋™์œผ๋กœ ์ปค๋„+rootfs๋ฅผ ๊ฐ Pod์˜ W5500 TFTP ์„œ๋ฒ„์— ์Šคํ…Œ์ด์ง•ํ•˜๊ณ , RouterOS PoE API๋กœ ๊ฐ ์นด๋ฉ”๋ผ๋ฅผ ์ „์› ์‚ฌ์ดํด๋งํ•˜๊ณ , ๋ถ€ํŒ… ์„ฑ๊ณต์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค โ€” ์ธ๊ฐ„ ๊ฐœ์ž… ์—†์Œ, sudo ์—†์Œ, ํฌํŠธ ์ถฉ๋Œ ์—†์Œ.

02. ๋ฒค๋” ํŽŒ์›จ์–ด ์นด๋ฉ”๋ผ ํ˜„์žฅ ๋ณต๊ตฌ

๋ฐฐ์น˜ ๋‹จ์œ„์˜ HiSilicon ์นด๋ฉ”๋ผ๋ฅผ OpenIPC๋กœ ์ „ํ™˜ํ•˜๋Š” ์ธํ…Œ๊ทธ๋ ˆ์ดํ„ฐ์—๊ฒŒ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. defib์˜ restore ์ปค๋งจ๋“œ๊ฐ€ ipctool ๋ฐฑ์—… ํŒŒ์ผ์„ ๋ฐ›์•„ ๋‚ด์žฅ YAML์—์„œ ํŒŒํ‹ฐ์…˜ ๋ ˆ์ด์•„์›ƒ์„ ์ถ”์ถœํ•˜๊ณ  ๋ฆฌํ”Œ๋ž˜์‹œํ•ฉ๋‹ˆ๋‹ค โ€” ๋…ธํŠธ๋ถ NIC์„ ์นด๋ฉ”๋ผ ์„œ๋ธŒ๋„ท์— ๋ฐฐ์น˜ํ•˜๊ธฐ ์–ด๋ ค์šด ์ƒํ™ฉ์—์„œ Pod TFTP๋ฅผ ํ†ตํ•ด ํŒŒํ‹ฐ์…˜์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

03. OpenIPC ๊ฐœ๋ฐœ ์›Œํฌํ”Œ๋กœ์šฐ

์ปค๋„ ๋นŒ๋“œ๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์ตœ์ ์ž…๋‹ˆ๋‹ค. ๋งค ๋นŒ๋“œ ์‚ฌ์ดํด: defib install -c hi3516ev300 --firmware openipc.tgz -p /dev/uart-cam --power-cycle. Pod TFTP ๊ฒฝ๋กœ๊ฐ€ ํ…Œ์ŠคํŠธ ๋ฐ˜๋ณต ๊ฐ„ ๋…ธํŠธ๋ถ ๋„คํŠธ์›Œํฌ ์Šคํƒ ์žฌ๊ตฌ์„ฑ ์—†์ด ์ผ๊ด€๋œ ํƒ€์ด๋ฐ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

04. ์›น ๊ธฐ๋ฐ˜ ๋ณต๊ตฌ (์„ค์น˜ ๋ถˆํ•„์š”)

๋น„๊ธฐ์ˆ  ์‚ฌ์šฉ์ž๊ฐ€ Chrome์—์„œ openipc.github.io/defib/๋ฅผ ์—ด๋ฉด ๋ฉ๋‹ˆ๋‹ค. WebSerial UI๊ฐ€ USB-์‹œ๋ฆฌ์–ผ ์–ด๋Œ‘ํ„ฐ๋ฅผ ํ†ตํ•ด ์นด๋ฉ”๋ผ์— ์—ฐ๊ฒฐํ•˜๊ณ  ์นฉ ์„ ํƒ, ํŽŒ์›จ์–ด ๋‹ค์šด๋กœ๋“œ, ํ”Œ๋ž˜์‹œ ๊ณผ์ •์„ ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค โ€” Python ์—†์Œ, CLI ์—†์Œ, ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € ์—†์Œ.


๊ฒฐ๋ก 

defib๋Š” ์ „์šฉ ๋ณต๊ตฌ Pod์— ํƒ‘์žฌ๋œ W5500 ์นฉ์ด ์ž„๋ฒ ๋””๋“œ ํŽŒ์›จ์–ด ํ”Œ๋ž˜์‹ฑ์˜ ๋ชจ๋“  ํ˜ธ์ŠคํŠธ ์ธก ๋„คํŠธ์›Œํฌ ์„ค์ • ์š”๊ตฌ์‚ฌํ•ญ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Œ์„ ์ฆ๋ช…ํ•ฉ๋‹ˆ๋‹ค โ€” ๋ณต์žกํ•œ ๋‹ค๋‹จ๊ณ„ ์ˆ˜๋™ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋‹จ์ผ ์ปค๋งจ๋“œ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • โœ… W5500 UDP ์†Œ์ผ“ ๋ชจ๋“œ๋กœ ๊ฒฝ๋Ÿ‰ RFC 1350 TFTP ์„œ๋ฒ„๋ฅผ 192.168.1.1:69์—์„œ ํ˜ธ์ŠคํŒ…
  • โœ… ์นด๋ฉ”๋ผ ์ธก LAN์ด ํ˜ธ์ŠคํŠธ ๋„คํŠธ์›Œํฌ์™€ ๋ฌผ๋ฆฌ์  ๊ฒฉ๋ฆฌ โ€” NIC ํ”Œ๋Ÿผ๋น™ ์ œ๋กœ
  • โœ… ์ œ๋กœ์นดํ”ผ ์˜ค๋„ˆ์‹ญ ์ „์†ก์œผ๋กœ ๋Œ€์šฉ๋Ÿ‰ ํŽŒ์›จ์–ด OOM ํ•ด๊ฒฐ
  • โœ… 120๊ฐœ ์ด์ƒ์˜ HiSilicon/Goke SoC ๋ณ€์ข… ์ง€์›
  • โœ… ์„ธ ๊ฐ€์ง€ ์ƒํ˜ธ๋ณด์™„ ํ”Œ๋ž˜์‹œ ๊ฒฝ๋กœ: ์—์ด์ „ํŠธ(์ตœ๊ณ ์†), Pod TFTP(๋ฌด์„ค์ •), ํ˜ธ์ŠคํŠธ TFTP(ํด๋ฐฑ)
  • โœ… End-to-end ๊ฒ€์ฆ: ๋‹จ์ผ ์ปค๋งจ๋“œ๋กœ 6.2 MB ํŽŒ์›จ์–ด ์Šคํ…Œ์ด์ง•+ํ”Œ๋ž˜์‹œ, 193 s
  • โœ… Python ํ˜ธ์ŠคํŠธ ์ธก ์ฝ”๋“œ๋ฒ ์ด์Šค ํ…Œ์ŠคํŠธ 486๊ฐœ ํ†ต๊ณผ
  • โœ… ํฌ๋กœ์Šคํ”Œ๋žซํผ: Linux, macOS, Windows CLI + WebSerial ๋ธŒ๋ผ์šฐ์ € UI

Q&A

Q. Pod TFTP ์„œ๋ฒ„์— ์™œ TCP๊ฐ€ ์•„๋‹Œ UDP์ธ๊ฐ€์š”? RFC 1350 TFTP๋Š” ์‚ฌ์–‘์ƒ UDP ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค. U-Boot ๋‚ด์žฅ TFTP ํด๋ผ์ด์–ธํŠธ๋Š” UDP๋งŒ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. W5500์˜ ํ•˜๋“œ์›จ์–ด UDP ์†Œ์ผ“ ๋ชจ๋“œ(Sn_MR_UDP)๊ฐ€ ์ž์—ฐ์Šค๋Ÿฌ์šด ๋งค์นญ์ž…๋‹ˆ๋‹ค โ€” ์ด๋ฏธ ์ž์ฒด ๋ธ”๋ก๋ณ„ ACK ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๊ฐ–์ถ˜ ๋‹จ์ˆœ ๋ธ”๋ก ์ „์†ก ํ”„๋กœํ† ์ฝœ์— TCP ์—ฐ๊ฒฐ ์ƒํƒœ ๋จธ์‹  ์˜ค๋ฒ„ํ—ค๋“œ๋Š” ๋ถˆํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

Q. ์Šคํ…Œ์ด์ง• ์ค‘ PSRAM์ด ๋ถ€์กฑํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋‚˜์š”? POST /tftp/<name>์ด PSRAM ํ• ๋‹น ์‹คํŒจ ์‹œ {"error":"oom","psram_largest_free":<bytes>} JSON ๋ฐ”๋””์™€ ํ•จ๊ป˜ 503์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. RackController.tftp_put์ด ์ด๋ฅผ ๋ฐ”๋”” ํฌํ•จ PowerControllerError๋กœ ํ‘œ๋ฉดํ™”ํ•˜์—ฌ, ํ˜ธ์ถœ์ž๊ฐ€ ํ˜ธ์ŠคํŠธ ์ธก TFTP๋‚˜ ์ฒญํฌ ์—…๋กœ๋“œ๋กœ ํด๋ฐฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Q. Pod์˜ tftpd.c ํŽŒ์›จ์–ด๋Š” ๊ณต๊ฐœ๋˜์–ด ์žˆ๋‚˜์š”? ํ˜„์žฌ๋Š” ํ”„๋กœ์ ํŠธ ์ •์ฑ…์— ๋”ฐ๋ผ rack ๋ ˆํฌ์˜ ๋น„๊ณต๊ฐœ ๋ธŒ๋žœ์น˜์— ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ˜ธ์ŠคํŠธ ์ธก ํด๋ผ์ด์–ธํŠธ ์ธํ„ฐํŽ˜์ด์Šค๋Š” src/defib/power/rack.py์— ์™„์ „ํžˆ ๊ณต๊ฐœ๋˜์–ด ์žˆ์œผ๋ฉฐ, W5500 ๋ฐ”์ธ๋”ฉ๊ณผ PSRAM ์•„ํ‚คํ…์ฒ˜๋Š” ์ฝ”๋“œ ์ฃผ์„๊ณผ PR ์„ค๋ช…์— ๋ฌธ์„œํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Q. N8R8 Pod ์—†์ด๋„ ๋™์ž‘ํ•˜๋‚˜์š”? ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. defib๋Š” ๋„ค ๊ฐ€์ง€ ๋…๋ฆฝ ๋ณต๊ตฌ ๊ฒฝ๋กœ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค: ์ง์ ‘ USB-์‹œ๋ฆฌ์–ผ UART, Vectis RFC 2217 ๋ธŒ๋ฆฌ์ง€, ํ˜ธ์ŠคํŠธ ์ธก TFTP(sudo + NIC ์„ค์ • ํ•„์š”), Pod TFTP(W5500). Pod๋Š” ์„ ํƒ์‚ฌํ•ญ์ด์ง€๋งŒ ๋ชจ๋“  ํ˜ธ์ŠคํŠธ ๋„คํŠธ์›Œํฌ ์„ค์ •์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

Comments

Comments