Це не Raspberry Pi. І саме тому це цікаво. Luckfox Pico Pro: від ATmega8 до живого відеостріму
Повна історія: хто я, як дійшов до embedded Linux, прошивка, статичний IP і перший RTSP стрім
Зміст
- Вступ — Хто я і звідки (про проєкти і шлях до Luckfox)
- Частина 1 — Прошивка: коли upgrade_tool.exe зустрічає Linux
- Частина 2 — Статичний IP на Buildroot: як не і як все-таки
- Частина 3 — Go HTTP сервер: 523MB VSZ, Samba і живий JSON
- Частина 4 — Діагностика RTSP: коли стрім зник наступного дня
Ще не осів пил від коліс Хижака мого проєкту на Pi Pico RP2040 Arm Cortex-M0+, яку я програмував на Arduino платформі, з радіокерованою машинкою на приймачі FS iA6B, а я вже дивився на нову плату на столі. Хижак їздить, працює, гештальт закрито (Читати що за Хижак на Ардуїно). Та Arduino за 12 років освоєно вздовж і поперек і подєлки на ньому вже давно стали прототипами справжніх бізнес проектів, які суттєво допомогли мені в свій час в автоматизації, та за ці роки багато що змінилось.

Є моменти в житті, коли ти стоїш між двома світами. Один знайомий, швидкий, передбачуваний. Інший — складний, незрозумілий, але так дивно притягує, саме таким світом став для мене Embedded Linux. Колись програмування жило у браузері та на серверах.
Сьогодні воно переїжджає у реальні речі:
- камери, які думають;
- дрони, які бачать;
- пристрої, які приймають рішення без хмари;
- маленькі комп’ютери, що працюють автономно.
Де код стає фізичною реальністю, а пристрій не просто плата, а: власний сервер, власна камера, власний експериментальний комп’ютер, лабораторія, яка завжди поруч. Я вже можу створити пристрій з нуля від живлення до веб-інтерфейсу і це дає відчуття творення, яке складно отримати в абстрактному коді, там де не loop(), а kernel, драйвери і /dev/video0.
Сьогодні розповім вам про новий гештальт — власну IP-камеру і шлях дослідження, як воно працює зсередини. Не купити готову. Не взяти Raspberry Pi з туторіалом. А взяти $15 embedded плату і пройти шлях з нуля від голого залізa до веб-інтерфейсу в браузері. Без романтики і магій, з потом, реальними командами, реальними помилками і реальним результатом в браузері наприкінці.
Що за плата і навіщо
Luckfox Pico Pro, це embedded Linux плата на чіпі Rockchip RV1106. Розміром з великий палець, ціною ~$15, але всередині справжній Linux з Ethernet, ISP процесором для камери і NPU для нейромереж.
Характеристики:
- CPU: ARM Cortex-A7 @ 1.2GHz
- RAM: 128MB DDR2
- Storage: 256MB SPI NAND
- Мережа: 10/100M Ethernet + USB RNDIS
- OS: Buildroot Linux (kernel 5.10.110)
Мета проєкту: зробити DIY IP-камеру. Але сьогодні — просто підключитись і запустити дашборд.

Та почнемо все з самого початку.
Вступ: Хто я і звідки
Як я дійшов до Автобота, або шлях від паяльника до Linux на ARM
Кожна серія статей, як і цікава історія про подорож потребує вступу. Особливо якщо в коментарях до першої статті є питання «а хто ти взагалі такий, чи варто тебе читати».
Мене звуть Алекс, мені далеко за 40, і я живий доказ того, що ефект Дюнінга-Крюгера має зворотній бік: якщо довго паяти, рано чи пізно починаєш розуміти, що паяєш, тут це моя особиста думка.
Все починається з паяльника
Перший паяльник з’явився коли мені було трохи за 30. До цього — юридична освіта, арбітражне управління, фінансовий консалтинг. Типовий шлях людини яка в дитинстві мріяла бути інженером, але алгебра не склалась. Зате геометрія — на відмінно, що в підсумку виявилось корисним при розводці плат.
Arduino прийшов десь у
Проєкт 1: газовий вузол, Modbus і Arduino Mini
Контекст: сервісний центр з ремонту газового обладнання, проблема з крадіжками при зливі газу. Лічильники давали похибку, дані вносились вручну, людський фактор він такий, де є люди і цінності, які важко обліковувати завжди виникне спокуса трохи відщипнути.
Рішення просте, замінити механічні лічильники на лічильники Emerson на ефекті Коріоліса — електронні, точні, з Modbus RTU. Завдання, зчитувати дані, передавати онлайн, фіксувати геолокацію газовоза. Легко сказати, та важко реалізувати, якщо взяти до уваги ціну цих лічильників, але якщо сісти і усе порахувати, то цифри переконують краще за будь які слова.
Інструменти, прості Arduino ProMini, GSM модуль, GPS, принтер для чеків. І Modbus RTU, який довелось реалізовувати самостійно на мікроконтролері з кількома кілобайтами RAM.
Якщо ви ніколи не реалізовували Modbus RTU вручну, то скажу, що це такий собі медитативний досвід. Тайминги, CRC, RTU фрейми, відповіді на запити майстра, відлагодження через Serial.print коли у тебе немає осцилографа. Моя родина в той період бачила мене рідко і переважно зі скляними очима направленими в монітор.
Результат, прототип якого розробили на Arduino mini запустили в продакшн. Це було неймовірно, 4 UARTA на пристрої який фізично підтримує лише один (Arduino Mini (та Pro Mini) має 1 апаратний UART). Станом на початок 2022 року працювало ~20 таких пристроїв. Генеральний директор побачив демо і виділив фінансування включно на переобладнання усіх газовозів на нові лічильники, а це, мабуть, найкращий код-рев’ю який може бути. А коли я виступив на конференції і продемонстрував результати, то ще декілька компаній вирішили зробити теж саме.
Проєкт 2: NFC скидочна система і SMS сервер на Arduino Mega
На хвилі успіху з газовим проєктом прийшло усвідомлення: «а зроблю-но я ще скидочну систему для мережі заправок». Мережа невелика — ~10 заправок, тому промислові рішення не підходили ні за ціною ні за гнучкістю. Окрім того на датчиках хола реалізував передачу залишків газу в ємностях, зараз це вимагає податкова і повно промислових рішень на будь який смак, а тоді це було революційно.
Що зробив:
- Термінал на Arduino з NFC зчитувачем карток — на кожній заправці
- Кабінет користувача, сервер і адмін-панель на чистому php, MySql та jQuery.
- SMS сервер для розсилки акцій — теж на Arduino, що «повно промислових модулів» я тоді ще не знав
- Диспетчерська для збору даних по приходу і реалізації газу — замість передачі по телефону
Інженер-електронщик виготовив термінали на компонентах з AliExpress, провів навчання операторів. Система реально працювала і вирішувала реальну задачу бізнесу — облік та рух товару, як виявилось суми втрачались колосальні, що породило деякі управлінські проблеми, але то інша історія і навряд чи туту вона доречна.
Оглядаючись назад — SMS сервер на Arduino це, звичайно, «наївно» як я писав у статті на Хабрі. Але, як на мене краще наївність, яка працює в продакшні ніж елегантність яка існує тільки в голові.
Від Arduino до Linux: чому Luckfox Pico Pro
Після декількох серйозних проєктів на Arduino, зокрема після спроби реалізації СКУД (Система Керування Управління Доступом) прийшло розуміння меж, хоча проект був навіть дуже цікавий — зчитувачі (Slave): Модуль Arduino RFID-RC522, плата ProMini, з використанням Rs485. Master Arduino mega, усе працювало, але дуже повільно, тож переробив на Orange Pi, досвід дуже цікавий, адже це був перший досвід використання Linux у проектах, які звик робити на мікроконтроллерах. Звісно ж, не Arduino погана, як багато хто вважає, це просто неймовірна платформа, яка дозволяє отримати дзен від процесу, та просто задачі ростуть, хоча для передавання даних про тиск з насосної станції все одно актуально. Але коли тобі потрібен HTTP сервер, JSON API, відеострім і нейронна мережа одночасно то 32 КБ RAM вже не вистачає.
До того моменту, як взяв у руки Luckfox Pico Pro з ARM Cortex-A7 та 128MB RAM з повноцінним Linux, вбудованим ISP для камери і NPU на 0.5 TOPS, за розміром трохи більше Arduino Nano та ще й не за всі гроші, відчув особливий приплив енергії та ентузізму хоча до цього вже мав досвід з одноплатними компютерами не один рік. Покрутивши плату в руках, почав шукати орієнтир, з якого боку підійти, загуглив, почитав трохи, трохи засмутився статею «LuckFox pico — одноплатник в форм факторе Arduino» де автор на Хабрі написав що для серйозних проєктів цю плату не варто брати бо «мало RAM і все на китайському софті». Я подивився на свій список реалізованих проєктів де Modbus RTU крутився на 2 КБ RAM і вирішив що спробую. До того ж ця плата повністю сумісна з Pi pico, а це теоретично означає що мій дашборд зроблений для останньої, про що я писав в своїй статті «IoT PowerHub. Як я створив промислову IoT-систему з нуля» може знайти ширше використання. Так і вийшло, дашборд сумісний і в ньому платка працює, що дуже зручно)
Частина 1: Прошивка: коли upgrade_tool.exe зустрічає Linux
Як я перепрошив Luckfox Pico Pro — або «в інструкції написано exe, а в мене Linux»
Все почалось невинно: приїхала камера MIS5001, підключив і нічого. Система робила вигляд що камери не існує. Після діагностики виявилось що прошивка просто не знає про такий сенсор. Рішення очевидне — перепрошити. Але, як завжди, дрібниці перетворились на пригоду.
Як зрозуміти що прошивка не підтримує твою камеру
Перший симптом — камера підключена, система її «бачить» через v4l2, але rkipc не запускається і файл rkipc.ini в /userdata/ не з’являється. Дивимось в dmesg і бачимо:
sc3336 4-0030: Unexpected sensor id(000000), ret(-5) sc4336 4-0030-1: Unexpected sensor id(000000), ret(-5) rockchip-csi2-dphy0: No link between dphy and sensor
Система знає про sc3336 і sc4336, але не знає про mis5001, хоча в wiki.luckfox написано, що підтримує. Перевіряємо IQ файли (це файли калібрування ISP для конкретних сенсорів):
ls /etc/iqfiles/ # CAC_sc4336_OT01_40IRC_F16 # sc3336_CMK-OT2119-PC1_30IRC-F16.json # sc4336_OT01_40IRC_F16.json
І супер висновок — прошивка з коробки підтримує тільки sc3336 і sc4336, а MIS5001 відсутнє в списку, отже це означає нову пригоду, бо треба перепрошити новішим образом, що само по собі має бути цікаво.
Скачуємо правильний образ
Офіційні образи лежать на Google Drive — посилання є на wiki.luckfox.com в розділі Downloads. Нас же цікавить папка firmware → buildroot → Flash (бо у нас Pico Pro з SPI NAND Flash).
Завантажуємо Luckfox_Pico_Pro_Flash_250429.zip (112 МБ). Розпаковуємо і бачимо:
boot.img env.img oem.img rootfs.img uboot.img download.bin idblock.img update.img userdata.img
Головне тут те, що є update.img. Саме він потрібен для прошивки через upgrade_tool.
«Інструмент тільки для Windows», але ми на Linux
Офіційна документація одразу показує SocToolKit — .exe файл. Супер, але якщо гортати далі, в розділі «Image Flashing (Linux Environment)» є upgrade_tool закрите CLI від Rockchip, яке підтримує Linux (Ubuntu 22.04×86_64).
Встановлення:
# Скачати upgrade_tool_v2.17 з wiki.luckfox.com unzip upgrade_tool_v2.17.zip cd upgrade_tool_v2.17_for_linux/ sudo cp upgrade_tool /usr/local/bin sudo chmod +x /usr/local/bin/upgrade_tool # Перевірка sudo upgrade_tool -v # Upgrade Tool v2.17
Maskrom режим — ось де починається магія
Для прошивки плата має бути в режимі Maskrom, це спеціальний завантажувальний режим вбудований в чіп RV1106 на апаратному рівн і в цьому режимі плата не завантажує систему, а чекає команд від комп’ютера через USB.
Як увійти в Maskrom:
- Затиснути кнопку BOOT на платі
- Підключити USB до комп’ютера
- Відпустити BOOT
Перевіряємо:
lsusb | grep -i rock # Bus 003 Device 018: ID 2207:110c Fuzhou Rockchip Electronics Company
Якщо бачимо Rockchip — все добре. Якщо нічого то перевірте кабель (так, знову кабель 😄). Експеременти показали, що то був не кабель, просто зєднання по usb чомусь нестійке.
Прошивка — одна команда
cd ~/Downloads/Luckfox_Pico_Pro_Flash_250429/ sudo upgrade_tool uf update.img
Весь процес займає ~2 хвилини. Після завершення плата автоматично перезавантажується в нову систему.
Після прошивки обов’язково повертаємо налаштування
Нова прошивка це чиста система. Всі наші налаштування скинулись, і це нормально і передбачувано. Підключаємось через USB RNDIS (я використовую bash скрипт для запуску тому у мене адреса 172.32.0.93 є незмінною). І тут починається окрема пригода зі статичним IP.
Епілог: пішов до спортзали, повернувся і оп
Після того як upgrade_tool видав «Upgrade firmware ok» я пішов на тренування. Повернувся, підключив USB, запустив скрипт підключення, SSH на 172.32.0.93, відкрив VLC і написав rtsp://172.32.0.93/live/0.
Жива картинка з датою в кутку, з підсвіченою клавіатурою в кадрі, але трохи розфокусована, ага просто лінза на різьбі і треба підкрутити вручну.
Найкращий спосіб вирішувати проблеми і не вигоріти, це тягати залізо). А ви, як вирішуєте проблему вигорання?
Частина 2: Статичний IP на Buildroot: як не і як все-таки
Бонус-рівень: як налаштувати статичний IP (чи все-таки не налаштувати)
Здавалось би звичайний Linux, стандартний /etc/network/interfaces, що може піти не так?
Пишемо конфіг:
auto eth0 iface eth0 inet static address 192.168.1.102 pre-up killall udhcpc 2>/dev/null; true post-up killall udhcpc 2>/dev/null; true
Перезавантажуємось. Підключаємось. І бачимо... 192.168.1.101. Знову.
Чому не працює
Buildroot на Luckfox запускає udhcpc ще під час старту системи ще до того як будь-який наш скрипт може зреагувати. pre-up і post-up хуки виконуються, але udhcpc просто стартує знову після них. BusyBox ifupdown так влаштований: він запускає DHCP-клієнт паралельно навіть для «inet static».
Діагностика через логи підтвердила: udhcpc отримує 192.168.1.101 на
cat /var/log/messages | grep -i 'udhcpc\|eth0'
Рішення: S99staticip
Офіційне рішення з wiki.luckfox.com виявилось елегантно брутальним, пропонують не боротись з udhcpc, а прийти після нього. Створюємо /etc/init.d/S99staticip це скрипт з найвищим номером пріоритету (S99 виконується останнім):
cat > /etc/init.d/S99staticip << 'EOF' #!/bin/sh case $1 in start) sleep 5 ifconfig eth0 192.168.1.102 netmask 255.255.255.0 route del default 2>/dev/null route add default gw 192.168.1.1 ;; stop) ;; *) exit 1 ;; esac EOF chmod +x /etc/init.d/S99staticip
Чекаємо поки udhcpc завершить свою роботу, і тільки тоді приходимо і мовчки переписуємо результат. Елегантно? Ні. Працює? ip addr show eth0 виводить в консоль так.
Що я дізнався
- dmesg — незамінний при діагностиці камери. Якщо драйвер не знаходить сенсор він чесно про це повідомить
- /etc/iqfiles/ — каталог підтримуваних сенсорів. Нема файлу — нема підтримки
- upgrade_tool існує для Linux. Просто треба гортати документацію до кінця
- Maskrom режим — це не страшно. BOOT + USB лише два кроки і плата готова до прошивки
- Після прошивки все скидається. Тому звичка вести довідник з командами відновлення, забезпечить, щоб повторний шлях зайняв менше часу
- /etc/network/interfaces на Buildroot може просто не працювати. udhcpc стартує раніше. Рішення — S99staticip
* * *
Частина 3: Go HTTP сервер: 523MB VSZ, Samba і живий JSON
523MB VSZ, Samba з коробки і живий JSON — що я знайшов всередині embedded Linux
Дашборд працює, SSH підключений, Python сервер крутиться на платі. Але метрики захардкоджені — цифри в браузері статичні і не мають нічого спільного з реальним станом системи. Час це виправити.
Чому Go, а не Python або Node.js?
Python вже є на платі і для прототипу і він ідеальний. Але для сервера який буде крутитись постійно хочеться щось легше. перший кандидат для мене Node.js , адже я стільків років з тим працюю, але на жаль не в embedded, не цього разу старий, не цього разу і ось, чому:
- Node.js runtime важить ~50MB — при доступних 33MB RAM це проблема ще до старту
- Крос-компіляція Node для armv7 — окремий квест на кілька днів
- Buildroot не має Node в дефолтній конфігурації
Go вирішує всі ці проблеми одразу. Головна суперсила Go для embedded — statically linked бінарник. Компілятор пакує все — runtime, стандартну бібліотеку, залежності — в один файл. Копіюєш один бінарник на плату і він просто працює. Без apt install, без .so бібліотек.
І найголовніше — вбудований крос-компілятор. Одна змінна оточення і Go сам зберет бінарник для будь-якої архітектури:
GOOS=linux GOARCH=arm GOARM=7 go build -o server main.go
Docker — ізольоване середовище для крос-компіляції
Можна встановити Go прямо на комп’ютер. Але Docker дає чисте ізольоване середовище — не забруднюєш систему, легко відтворити. Dockerfile мінімальний:
FROM golang:1.23-alpine RUN apk add --no-cache git curl vim bash openssh-client file WORKDIR /go-dev CMD ["tail", "-f", "/dev/null"]
Alpine замість Debian, тут менше пакетів, менше вразливостей.
docker build -f Dockerfile.go-luckfox -t go-arm-dev . docker run -it --rm -v $(pwd):/go-dev go-arm-dev bash
Hello World на платі — перевірка крос-компіляції
GOOS=linux GOARCH=arm GOARM=7 go build -o hello-luckfox main.go file hello-luckfox # → ELF 32-bit LSB executable, ARM, EABI5, statically linked ✅
Три ключових слова: ARM — правильна архітектура,
scp -o PubkeyAuthentication=no ./hello-luckfox [email protected]:/root/ # на платі: chmod +x /root/hello-luckfox && /root/hello-luckfox # → Hello from Go on Luckfox! ✅
HTTP сервер з JSON API
Три endpoint:
- GET / — список доступних endpoint
- GET /api/stats — системні метрики у JSON
- GET /metrics — сирі дані з /proc
Запускаємо у фоні:
/root/http-server & # → Listening on :8080
Відкриваємо в браузері 192.168.1.102:8080/api/stats:
{ "hostname": "luckfox",
"arch": "arm",
"uptime_seconds": 4500.48,
"mem_total_kb": 55852,
"mem_available_kb": 37504 }
Сюрпризи від Luckfox
loadavg завжди ~6.x при порожній системі
Дивлюсь top тут loadavg 6.37 при одному ядрі, катастрофа, але ні %CPU у всіх процесів 0%. Дослідження через dmesg показало:
RKNPU: rknpu iommu device-tree entry not found!, non-iommu mode RKNPU: no regulator (rknpu) found: -19
NPU драйвер ініціалізувався з помилками і тримає kernel threads у стані очікування. Система реально вільна, але просто ядро рахує hardware wait як навантаження. Особливість цієї прошивки.
На платі з коробки крутиться Samba
В списку процесів є smbd і nmbd. Luckfox з коробки шарить файли по мережі як Windows сервер. Навіщо це на embedded, для мене загадка.
killall smbd nmbd # звільняє ~3MB RAM
Після killall — MemAvailable виріс з 33.9MB до 37.3MB. Невелика але реальна різниця на системі з 54MB RAM.
http-server з’їв 523MB VSZ
top показав для нашого сервера VSZ 523MB при RAM всього 54MB. Це не баг, видно Go runtime резервує великий віртуальний адресний простір наперед, тре покопати що там до чого. Реальна резидентна пам’ять (RSS) нормальна. Але виглядає лякаюче якщо не знаєш особливості Go.
* * *
Частина 4: Діагностика RTSP: коли стрім зник наступного дня
Епілог: стаття була готова, але embedded так і не працює
Стаття була написана. Камера працювала. Стрім йшов. Все добре.
Наступного дня я сів за розробку і стрім не запустився. Ось воно — «Ласкаво просимо в embedded розробку», походу тут все працює, точно так як і всюжи, рівно до моменту коли ти хочеш показати результат.
Квест виглядав так
ps aux | grep rkipc # rkipc є ✓ netstat -tln | grep 554 # порту нема ✗ → запустив вручну, почекав 15 сек netstat -tln | grep 554 # порт є ✓ telnet 192.168.1.102 554 # з’єднання є ✓ vlc rtsp://192.168.1.102/live/0 # не працює ✗ ffplay rtsp://192.168.1.102/live/0 # працює ✓
Попередні висновки
- rkipc потребує ~15 секунд після старту щоб підняти RTSP це мабуть нормально, просто зачекати
- VLC 3.0.16 не дружить з цим RTSP сервером — тре використовувати ffplay (sudo apt install ffmpeg)
- telnet host 554 — швидкий спосіб перевірити чи порт взагалі відповідає
- Не ведеш документацію, то танцюєш з бубном кожного разу заново
Алгоритм діагностики RTSP
- ps aux | grep rkipc — rkipc запущений?
- netstat -tln 2>/dev/null | grep 554 — порт прослуховується?
- telnet 192.168.1.102 554 — порт доступний ззовні?
- ffplay rtsp://192.168.1.102/live/0 — стрім іде?
Якщо на кроці 2 порту нема — тре запустіть rkipc вручну і зачекати 15 сек:
killall rkipc 2>/dev/null; sleep 1 rkipc -a /oem/usr/share/iqfiles 2>&1 & sleep 15 && netstat -tln 2>/dev/null | grep 554
* * *
P.S. — модульна філософія
Так, я знаю що Modbus можна було реалізувати через готову бібліотеку. SMS сервер можна було зробити на нормальному сервері. Статичний IP можна було налаштувати інакше.
Але реалізувавши вручну, я тепер знаю як воно працює. Це, мабуть, і є різниця між хобіїстом і інженером: інженер знає як скористатись бібліотекою, хобіїст — чому вона так написана.
Автобот — ардуїновий Хижак завдяки вашим коментарям вдосконалюється та тестується. Довідники поповнюються. Наступна стаття обовязково буде, тож додавайтесь щоб не загубитись.
Дякую за увагу. Коментарі про ефект Дюнінга-Крюгера приймаються , але тільки з прикладами коду 😄
Сподобалась стаття? Підписуйтесь на автора, щоб отримувати сповіщення про нові публікації на пошту.
70 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів