LuckFox FAQ |
![]() |
Добавил(а) microsin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Решения различных вопросов, возникающих при работе с аппаратной платформой LuckFox (серия плат для разработки на основе процессоров Rockchip RV1103 и RV1106). Инструкция [1], под Ubuntu 24.04.3 LTS: 1. Установка зависимостей: $ sudo apt update
$ sudo apt-get install -y git ssh make gcc gcc-multilib g++-multilib module-assistant expect g++ gawk \
texinfo libssl-v bison flex fakeroot cmake unzip gperf autoconf device-tree-compiler libncurses5-dev \
pkg-config bc python-is-python3 passwd openssl openssh-server openssh-client vim file cpio rsync
2. Клонирование последнего SDK: $ git clone https://gitee.com/LuckfoxTECH/luckfox-pico.git
[Структура каталога SDK (luckfox-pico)] ├── build.sh -> project/build.sh ---- скрипт компиляции SDK Примечание (1): можно компилировать независимо. Директория хранилища образа: output/ [Файл конфигурации SDK] 1. Файлы конфигурации Luckfox-Pico series SDK находятся в папке project/cfg/BoardConfig_IPC. luckfox-pico$ ls project/cfg/BoardConfig_IPC -1BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_86Panel-IPC.mk
BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_86Panel_W-IPC.mk
BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Pi-IPC.mk
BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Pi_W-IPC.mk
BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Ultra-IPC.mk
BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Ultra_W-IPC.mk
BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Zero-IPC.mk
BoardConfig-EMMC-Busybox-RV1106_Luckfox_Pico_Ultra-IPC_FASTBOOT.mk
BoardConfig-SD_CARD-Buildroot-RV1103_Luckfox_Pico-IPC.mk
BoardConfig-SD_CARD-Buildroot-RV1103_Luckfox_Pico_Mini-IPC.mk
BoardConfig-SD_CARD-Buildroot-RV1103_Luckfox_Pico_Plus-IPC.mk
BoardConfig-SD_CARD-Buildroot-RV1103_Luckfox_Pico_WebBee-IPC.mk
BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Pro_Max-IPC.mk
BoardConfig-SPI_NAND-Buildroot-RV1103_Luckfox_Pico_Mini-IPC.mk
BoardConfig-SPI_NAND-Buildroot-RV1103_Luckfox_Pico_Plus-IPC.mk
BoardConfig-SPI_NAND-Buildroot-RV1103_Luckfox_Pico_WebBee-IPC.mk
BoardConfig-SPI_NAND-Buildroot-RV1106_Luckfox_Pico_Pro_Max-IPC.mk
BoardConfig-SPI_NAND-Busybox-RV1106_Luckfox_Pico_Pro_Max-IPC_FASTBOOT.mk
luckfox-buildroot-nocsi-oem-pre.sh
luckfox-buildroot-oem-pre.sh
luckfox-glibc-oem-pre.sh
luckfox-rv1106-tb-emmc-post.sh
luckfox-rv1106-tb-spi_nand-post.sh
luckfox-systemd-off-modem-post.sh
luckfox-userdata-pre.sh
2. Если взять в качестве примера конфиг BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Pro_Max-IPC.mk, то можно рассмотреть его основные ключи. # Размер CMA в окружении Здесь: RK_BOOTARGS_CMA_SIZE: выделение памяти для камеры; если камера не используется, измените это значение на 1M. RK_KERNEL_DTS: указывает файл дерева устройств (device tree file, DTS). RK_BOOT_MEDIUM: указывает носитель загрузки (target boot medium), который может быть emmc (карта SD), sd_card (карта SD), spi_nor (SPI NOR Flash) или spi_nand (SPI NAND Flash). RK_PARTITION_CMD_IN_ENV: эта информация используется для конфигурирования таблицы разделов. Если вам нужно сопоставить дисковое пространство с SD-картой, то вы можете изменить раздел rootfs. LF_TARGET_ROOTFS: указывается корневая файловая система target (Root File System). LF_SUBMODULES_BY: указывается источник субмодулей. RK_BUILDROOT_DEFCONFIG: указывается конфигурационный файл Buildroot. [Компиляция образов] Из описания в предыдущем разделе можно увидеть, что образ Ubuntu поддерживает загрузку только с SD-карточки (SD card boot), в то время как образ Buildroot поддерживает как загрузку с TF-карты (TransFlash), так и загрузку из микросхемы памяти (SPI NAND FLASH boot). 1. Если вам нужно компилировать образ для системы Ubuntu и использовать gitee, то измените соответствующий mk-файл, задающий тип платы, чтобы отредактировать LF_SUBMODULES_BY для gitee, примерно так: LF_SUBMODULES_BY=gitee 2. Если вы хотите компилировать образ Buildroot для загрузки TF card boot, то измените соответствующий файл BoardConfig-EMMC-Ubuntu-xxx.mk, чтобы поменять LF_TARGET_ROOTFS на buildroot, примерно так: export LF_TARGET_ROOTFS=buildroot 3. Установите cross-compilation toolchain: $ cd {SDK_PATH}/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/
$ source env_install_toolchain.sh
4. Скомпилируйте все образы: $ cd luckfox-pico
Примечание: когда компилируется Ubuntu, используйте sudo, чтобы избежать файловых ошибок системы. Следующие инструкции не делают различий между этими двумя вариантами компиляции, но вы действуйте в соответствии с вашей ситуацией. [Компиляция по частям] Отдельная компиляция загрузчика U-Boot: $ ./build.sh clean uboot
$ ./build.sh uboot
Сгенерированные файлы образа: output/image/MiniLoaderAll.bin и output/image/uboot.img Отдельная компиляция ядра: $ ./build.sh clean kernel
$ ./build.sh kernel
Сгенерированный файл образа: output/image/boot.img Отдельная компиляция корневой файловой системы: $ ./build.sh clean rootfs
$ ./build.sh rootfs
Примечание: после компиляции используйте команду ./build.sh firmware для переупаковки. Отдельная компиляция media: $ ./build.sh clean media
$ ./build.sh media
Файлы сохраняются в директории: output/out/media_out. После компиляции используйте команду ./build.sh firmware для переупаковки. Отдельная компиляция образцовых приложений: $ ./build.sh clean app
$ ./build.sh app
Примечания: app зависит от media. После компиляции используйте команду ./build.sh firmware для переупаковки. Упаковка прошивки (firmware packaging): $ ./build.sh firmware
Компиляция busybox/buildroot: $ ./build.sh lunch
$ ./build.sh
Компиляция Ubuntu: $ sudo ./build.sh lunch
$ sudo ./build.sh
Это принципиально разные подходы к сборке операционной системы для вашего Luckfox Pico. Сравнительная таблица:
[Подробное объяснение] 1. Compile busybox/buildrootЭто стандартный способ для embedded-устройств. Buildroot — это инструмент для сборки, который: ls , cp , mv , vi , ifconfig и т.д.) одним бинарным файлом, экономя огромное количество места.Когда использовать: для готовых устройств, где важны размер, скорость загрузки и безопасность. 2. Compile ubuntuЭто способ для тех, кому нужна полноценная и привычная среда. Здесь скрипты не собирают систему с нуля, а кастомизируют и адаптируют готовые образы Ubuntu (чаще всего Ubuntu Base или Core) под архитектуру Luckfox Pico. В результате вы получаете почти ту же Ubuntu, что и на ПК, но собранную для ARM-процессора. В ней есть менеджер пакетов Почему нужен Когда использовать: Для разработки и отладки, когда вам нужен доступ к большому количеству инструментов и библиотек без необходимости их самостоятельной кросс-компиляции. [Итог: Какой вариант выбрать?] Если вы разработчик и хотите быстро протестировать код, использовать привычные инструменты ( На практике часто начинают с Ubuntu для удобства прототипирования, а для финальной версии продукта переходят на Buildroot, чтобы оптимизировать образ. Gitee Source (или Gitee источник) — это серверы-зеркала (репозитории) на платформе Gitee.com, которые хранят копии исходного кода и пакетов с других открытых платформ (в первую очередь — GitHub). Их основная цель — ускорение доступа к этим ресурсам для разработчиков внутри Китая. Если говорить проще, Gitee Source — это "зеркало" или "кэш" для исходного кода. Детальное объяснение:Для чего это нужно?
Как это работает?
Где вы с этим сталкиваетесь? Именно в сценариях, подобных вашему — при сборке прошивок для embedded-устройств (Luckfox Pico, Raspberry Pi, Orange Pi и т.д.) с помощью скриптов вроде
Пример из практики: допустим, скрипту сборки нужен исходный код ядра Linux ( Итог:Gitee Source — это техническое решение для ускорения и стабилизации разработки внутри Китая путем создания локальных копий международных opensource-репозиториев. Когда вы в процессе сборки видите упоминание В вашем случае, при выполнении TF card — это старое название карт microSD. По современным стандартам это одно и то же. Подробности см. в Википедии. В контексте одноплатных компьютеров LuckFox (и других подобных плат на процессорах Rockchip), термин `media` имеет очень конкретное и важное значение. `Media` здесь — это сокращение от "Multimedia" и относится к подсистеме обработки мультимедиа внутри процессора (SoC). Это целый набор аппаратных блоков (IP-ядер) и программного обеспечения, отвечающих за работу с видео и изображениями. Если говорить просто, `media` в LuckFox — это всё, что позволяет плате "видеть" и "показывать". [Что входит в подсистему Media?] Эта подсистема включает в себя два основных направления: 1. Видеозахват (Video Input - VI). Это аппаратные блоки и драйверы, отвечающие за приём видео от камер. ISP (Image Signal Processor): "Мозги" обработки изображения. Он преобразует сырые данные (raw data) с матрицы камеры в привычное нам изображение, выполняя: • Дебейеризацию (Demosaic) — преобразование сырых данных с Bayer-фильтра в цветное изображение. MIPI CSI (Camera Serial Interface): hardware-интерфейс, к которому физически подключаются современные камерные модули (например, ваши камеры LuckFox). VIPP (Video Input Post Processor): блок для дальнейшей обработки уже сформированного изображения (масштабирование, обрезка). 2. Видеовывод и Кодирование/Декодирование (Video Output & Codec). Это аппаратные блоки, отвечающие за сжатие, распаковку и вывод видео. VPU (Video Processing Unit): hardware-энкодер и декодер. Именно он позволяет кодировать (сжимать) видео с камеры в форматы **H.264** или **H.265 (HEVC)** с очень малым потреблением энергии процессора. Это критически важно для видеорегистраторов, камер наблюдения. VOP (Video Output Processor): блок, управляющий выводом изображения на дисплей (например, по HDMI или через LVDS-интерфейс). [Где вы встречаетесь с термином "media" в LuckFox?] 1. В Device Tree (`*.dts`): конфигурация всей подсистемы `media` (какие камеры подключены, их разрешение, режимы работы ISP) прописывается в файле дерева устройств. 2. В ядре Linux (`kernel/`): драйверы, находящиеся в разделах типа `drivers/media/platform/rockchip/isp/`, `.../mipi-csi/`, `.../rkcif/`. 3. В пользовательском пространстве: • Утилита `rkisp_demo`: позволяет тестировать и настраивать работу ISP (задавать параметры цветокоррекции, резкости и т.д.). Пример рабочего потока (pipeline) `media`: Камера (Sensor) -> MIPI CSI-2 Interface Итог: В контексте LuckFox термин `media` — это не абстрактное "медиа", а конкретное название мощной аппаратно-программной подсистемы, которая отвечает за: * Захват видео с камеры Именно эта подсистема является ключевым преимуществом процессоров Rockchip и делает платы LuckFox такими популярными для проектов компьютерного зрения, видеонаблюдения и потокового вещания. Buildroot — это не дистрибутив Linux (как Ubuntu или Debian), а система автоматизации сборки. Её главная задача — собрать всё необходимое для работы встроенной системы (embedded Linux) из исходного кода с помощью инструмента make. Представьте себе конструктор или конвейер, который по вашему заказу: • Скачивает исходные коды нужной версии ядра Linux, библиотек и программ. Главная философия Buildroot — создавать минималистичные и эффективные системы без лишнего софта, что идеально для устройств с ограниченными ресурсами, наподобие плат разработчика Luckfox Pico Mini. Buildroot предоставляется производителем (Luckfox) в составе Software Development Kit (SDK), и внутри этого SDK Buildroot является основным движком для сборки всей операционной системы. Когда вы скачиваете официальный SDK для Luckfox Pico, его структура обычно включает: buildroot/ — Сама система Buildroot с конфигурациями и настройками от Luckfox. Процесс разработки выглядит так: 1. Вы входите в директорию SDK. 2. Запускаете команду ./build.sh (это скрипт-обертка от Luckfox). Он скрипт запускает Buildroot, который, в свою очередь: - Компилирует кросс-компилятор (gcc) для архитектуры ARM. 3. В результате в папке output/ вы получаете файлы rootfs.img, kernel.img и другие, которые можно прошить на вашу плату с помощью инструмента RKDevTool. Buildroot для Luckfox Pico Mini используется по следующим соображениям: • Легковесность: итоговая система получается очень маленькой. Образ rootfs.img может весить всего несколько десятков мегабайт, что идеально для встроенных устройств. [Альтернативы Buildroot] Часто Buildroot сравнивают с Yocto Project. Оба решают одну задачу, но по-разному: Buildroot: Проще в освоении, быстрее собирает систему, идеален для относительно простых устройств и быстрого прототипирования (как в случае с Luckfox Pico). Yocto: Более мощный, гибкий и сложный инструмент, предназначенный для создания промышленных дистрибутивов с поддержкой множества пакетов и архитектур. Его кривая обучения значительно круче. Итог: Buildroot в контексте Luckfox Pico Mini — это "сердце" процесса сборки прошивки. Это инструмент, который превращает исходные коды ядра Linux, загрузчика U-Boot и сотен отдельных программ в единый, готовый к прошивке, минималистичный и оптимизированный образ операционной системы, который превращает голое "железо" Luckfox Pico в работающий мини-компьютер с Linux, способный выполнять ваши задачи. Без Buildroot вам пришлось бы вручную компилировать и компоновать все части ОС, что является невероятно сложной и трудоемкой задачей. Buildroot автоматизирует этот процесс до одной команды. Определить модель платы LuckFox Pico можно несколькими способами, от самого простого (визуальный осмотр) до более сложных (программных). [Способ 1: визуальный осмотр (cамый быстрый и простой)] Это первый и часто самый эффективный шаг. Посмотрите на вашу плату и найдите ключевые отличия. Ниже перечислены ключевые признаки для идентификации. 1. Размер и форма платы: LuckFox Pico: самая маленькая плата (примерно 20x20 мм), квадратной формы. Выглядит как "голый" модуль без портов. 2. Наличие и тип интерфейсов: Ethernet (Сетевой порт RJ45): есть только у LuckFox Pico Mini A и LuckFox Pico Mini B. У модели "A" один порт, у модели "B" два порта. 3. Количество и расположение контактов GPIO: LuckFox Pico: 24 контакта (2 ряда по 12 с каждой стороны). LuckFox Pico: LuckFox Pico Mini A/B: B-версия LuckFox Pico Mini отличается от A-версии только наличием распаянной на плате Flash памяти на 128 Мб. На Flash можно поставить операционную систему, но объема 128 Мб довольно мало (хотя в варианте сборки Buildroot для многих задач может хватить). Если использовать загрузку с карты SD, где памяти может быть намного больше, то Flash на плате можно использовать в качестве резервного хранилища важных данных, например, логов. LuckFox Pico Plus: LuckFox Pico Pro/Max: LuckFox Pico Ultra/Ultra W: [Способ 2: определение через Linux (если плата уже прошита)] Если плата запускается, и у вас есть доступ к её командной строке (через UART, SSH или ADB [4]), то вы можете использовать несколько команд. 1. Посмотреть модель в `proc/device-tree/` (самый точный способ). Проприетарные параметры платы хранятся в Device Tree. Выполните команду: # cat /proc/device-tree/model
Результат будет прямо указывать на модель, например: `luckfox,pico` → LuckFox Pico 2. Посмотреть информацию о процессоре. Следующая команда покажет не модель платы, а модель чипа, это тоже может быть полезно. [root@luckfox ]# cat /proc/cpuinfo
processor : 0
model name : ARMv7 Processor rev 5 (v7l)
BogoMIPS : 26.08
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xc07
CPU revision : 5
3. Проверить наличие определенных устройств (косвенный метод). Проверить сетевые интерфейсы позволяет команда `ifconfig -a` или `ip addr`: [root@luckfox ]# ifconfig -a
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:11948 errors:0 dropped:0 overruns:0 frame:0
TX packets:11948 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:884044 (863.3 KiB) TX bytes:884044 (863.3 KiB)
usb0 Link encap:Ethernet HWaddr 06:2C:70:05:43:2B
inet addr:172.32.0.93 Bcast:172.32.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2043 errors:0 dropped:1563 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:334536 (326.6 KiB) TX bytes:0 (0.0 B)
Если видите `eth0` и `eth1`, то скорее всего это Pico Mini B. Если видите только `eth0`, то скорее всего это Pico Mini A. Если Ethernet-интерфейсов нет вообще, то это базовая Pico (без Ethernet). Проверить наличие аудиоустройства: команда `ls /dev/snd/`. [root@luckfox ]# ls /dev/snd/
Наличие звуковых устройств характерно для моделей Plus и Pro. [Способ 3: по надписям на упаковке или плате] Производитель часто наносит шелкографию с названием модели на саму плату. Ищите надписи типа "Pico", "Pico Mini", "Pico Plus" или "Pico Pro". Коробка или антистатический пакет, в котором пришла плата, почти всегда имеют наклейку с точным указанием модели (например, "LuckFox Pico Mini B"). BusyBox — это единственный исполняемый файл, который заменяет собой сотни маленьких стандартных UNIX-утилит (команд), таких как: `ls`, `cp`, `mv`, `mkdir`, `rm` (команды работы с файлами) И также многие другие команды. Это видно по множеству символических ссылок с команд на единственный исполняемый файл busybox: [root@luckfox ]# ls -la /bin
total 5936
drwxrwxr-x 2 1000 1000 5768 Sep 16 2025 .
drwxr-xr-x 20 1000 1000 1584 Sep 16 2025 ..
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 arch -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 ash -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 base32 -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 base64 -> busybox
-rwxr-xr-x 1 1000 1000 990960 Sep 16 2025 bash
-rwxr-xr-x 1 1000 1000 857296 Sep 16 2025 busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 cat -> busybox
-rwxr-xr-x 1 1000 1000 9304 Sep 16 2025 chattr
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 chgrp -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 chmod -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 chown -> busybox
-rwxr-xr-x 1 1000 1000 1342 Sep 16 2025 compile_et
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 cp -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 cpio -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 date -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 dd -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 df -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 dmesg -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 dnsdomainname -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 dumpkmap -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 echo -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 egrep -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 false -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 fdflush -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 fgrep -> busybox
-rwxr-xr-x 1 1000 1000 3477 Sep 16 2025 gcore
-rwxr-xr-x 1 1000 1000 3486000 Sep 16 2025 gdb
-rwxr-xr-x 1 1000 1000 4045 Sep 16 2025 gdb-add-index
-rwxr-xr-x 1 1000 1000 253404 Sep 16 2025 gdbserver
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 getopt -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 grep -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 gunzip -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 gzip -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 hostname -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 kill -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 link -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 linux32 -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 linux64 -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 ln -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 login -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 ls -> busybox
-rwxr-xr-x 1 1000 1000 9304 Sep 16 2025 lsattr
-rwxrwxr-x 1 1000 1000 17900 Sep 16 2025 memtester
-rwxr-xr-x 1 1000 1000 1102 Sep 16 2025 mk_cmds
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 mkdir -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 mknod -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 mktemp -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 more -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 mount -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 mountpoint -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 mt -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 mv -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 netstat -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 nice -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 nuke -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 pidof -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 ping -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 pipe_progress -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 printenv -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 ps -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 pwd -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 resume -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 rm -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 rmdir -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 run-parts -> busybox
-rwxrwxr-x 1 1000 1000 88 Sep 16 2025 sdkinfo
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 sed -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 setarch -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 setpriv -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 setserial -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 sh -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 sleep -> busybox
-rwxr-xr-x 1 1000 1000 236644 Sep 16 2025 stressapptest
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 stty -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 su -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 sync -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 tar -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 touch -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 true -> busybox
-rwxr-xr-x 1 1000 1000 178592 Sep 16 2025 udevadm
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 umount -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 uname -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 usleep -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 vi -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 watch -> busybox
lrwxrwxrwx 1 1000 1000 7 Sep 16 2025 zcat -> busybox
Таким образом, каждая из этих команд представлена не отдельной программой, а всего лишь "ссылкой" на главный исполняемый файл `busybox`. Например, когда вы вызываете команду `ls`, на самом деле система запускает `busybox ls`, и BusyBox "понимает", что нужно выполнить функцию `ls`. Почему BusyBox КРИТИЧЕСКИ важен для LuckFox Pico Mini? Именно здесь преимущества BusyBox раскрываются в полной мере: 1. Экономия места файловой системы (что крайне важно!): - LuckFox Pico Mini имеет ограниченный объем флеш-памяти (обычно 4GB или 16GB eMMC), часть которой занята ядром Linux и вашими приложениями. 2. Экономия оперативной памяти: запущенные программы занимают оперативную память (RAM). Так как BusyBox — это одна программа, а не множество, она использует меньше RAM при выполнении различных задач. 3. Упрощение сборки и управления: разработчикам встраиваемых устройств проще управлять одним пакетом (BusyBox), который предоставляет весь базовый функционал, вместо того чтобы отслеживать сотни отдельных мелких утилит. При сборке прошивки с помощью Buildroot (см. Q002) просто выбирается конфигурация BusyBox с нужным набором функций. 4. Скорость и эффективность: BusyBox оптимизирован для работы на системах с ограниченными ресурсами, таких как LuckFox Pico Mini. Его код написан с упором на минимализм и скорость. Итак, когда вы подключаетесь к своей плате через UART, SSH или ADB и попадаете в командную строку встраиваемой системы, практически с каждым вашим действием происходит взаимодействие с BusyBox. Проверка, что вы используете BusyBox: введите любую команду с ключом --help, и вы увидите сигнатуру BusyBox. Например: .[root@luckfox ]# ls --help
BusyBox v1.36.1 (2025-09-16 13:42:36 MSK) multi-call binary.
Первая строка четко указывает, что это BusyBox. Можно посмотреть, какие функции встроены в BusyBox. Для этого выполните команду `busybox` без аргументов, и она выведет большой список всех поддерживаемых applets (маленьких приложений-функций). Таким образом, BusyBox в контексте LuckFox — это фундаментальный строительный блок встраиваемой операционной системы. Это минималистичная, невероятно эффективная и универсальная замена всем стандартным UNIX-инструментам, которая позволяет уместить мощную и функциональную командную среду Linux в несколько мегабайт, что идеально соответствует ограниченным ресурсам платы. Без BusyBox встроенные Linux-системы like LuckFox Pico Mini были бы гораздо больше, дороже и менее эффективны. На самой плате поддерживаются busybox, buildroot и Ubuntu 22.04. На машине разработчика для кросс-компиляции может использоваться Ubuntu 24.04 или Docker. Запустите SocToolKit с правами администратора, и затем установите TF-карту. Если она все еще не распознается, закройте ПО антивируса. Попробуйте также загрузить новую версию SocToolKit. Емкость TF-карты слишком маленькая; рекомендуется использовать 8GB или больше. При использовании SocToolKit для прошивки firmware платы Luckfox Pico, утилита показывает, что файл luckfox pico\image\media.img не существует. Причина в том, что Luckfox Pico поддерживает только лишь загрузку с TF-карты (TF card boot), и она должна быть записана с помощью картридера. Облачный диск не предоставляет образ системы buildroot, подходящий для загрузки с карты SD. Вам нужно самостоятельно скомпилировать его в соответствии с секцией SDK. Поскольку емкость SD-карт может быть разной, вам необходимо вручную подстроить емкость раздела. При установке TF-карты в плату Luckfox Pico и подключении к компьютеру SocToolKit показывает режим Maskrom, и программа не может быть прошита. Причина в том, что Luckfox Pico поддерживает только лишь загрузку с TF-карты (TF card boot). Используйте картридер для записи карты, после чего установите карту в слот платы для запуска системы. Попытка подключения не удается с сообщением, что подключенная сторона не ответила должным образом через определенный промежуток времени, или из-за того, что подключенный узел не ответил. Для решения проблемы сконфигурируйте виртуальный сетевой интерфейс RNDIS. Проверьте совместимость уровней логики последовательного интерфейса, и не перепутаны ли прием с передачей (сигналы RX и TX). Luckfox-Pico работает с сигналами уровня логики 3.3V, и требует соответствующей установки уровней на модуле переходника USB - TTL UART. На официальном сайте заявлено, что у Luckfox-Pico и Luckfox-Pico-Mini/Plus установлено 64MB памяти, но фактический объем памяти около 34 MB. Вероятно проблема в том, что память выделена системой и работающим программным обеспечением. Пример вывода: [ 0.000000] Memory: 34328K/65536K available (3452K kernel code, 283K rwdata, 1644K rodata,
144K init, 127K bss, 6632K reserved, 24576K cma-reserved)
После подключения Luckfox-Pico-Plus/Pro/Max через последовательный порт устройство все время посылает сообщение "udhcpc: sending discover". Если сетевой кабель не подключен, то в лог будет выводиться сообщение "udhcpc: sending discover". Подключите сетевой кабель, или используйте команду kill для остановки процесса udhcpc. # ps | grep udhcpc
248 root 1196 S udhcpc -i eth0
311 root 1192 S grep udhcpc
# kill 248
udhcpc: received SIGTERM
Причина в том, что factory image предназначен главным образом для тестирования функционала GPIO. Вам необходимо самостоятельно прошить образ из онлайн-репозитория. Вы должны использовать инструментарий кросс-компиляции из SDK. После кросс-компиляции на хосте Ubuntu или виртуальной машине выгрузите результат компиляции на плату. При загрузке виртуальной машины VirtualBox появляется ошибка "VT-x is disabled in the BIOS for both all CPU modes (VERR_VMX_MSR_ALL_VMX_DI)". Причина ошибки в том, что не разрешена технология виртуализации CPU на материнской плате хоста. Выполните следующие шаги, основываясь на модели вашей материнской платы для доступа к BIOS компьютера: 1. Например, материнские платы ASUS для входа в BIOS используют клавишу F2 во время запуска. Программа VLC по умолчанию использует видеобуфер размером в 1 секунду (1000ms = 1s). Можно умеренно сократить время буферизации для улучшения real-time производительности, но слишком низкая задержка может привести к потере пакетов и заиканию. Не рекомендуется устанавливать размер буфера меньше 300ms. VBUS подключен ко входному напряжению интерфейса Type-C; VSYS это входное напряжение основной системы, с напряжением в диапазоне от 4.5V до 5.5V. $ sudo cp -r luckfox-pico/ ~/Luckfox-test/
$ cd ~/Luckfox-test/luckfox-pico/
$ ./build.sh lunch
ls: cannot access 'BoardConfig*.mk': No such file or directory
Возможная причина ошибки в том, что используется команда sudo в процессе копирования, поэтому могут быть измерены права доступа к файлам в SDK. Удалите и заново выполните копирование с правами обычного пользователя. При компиляции происходит ошибка загрузки модуля драйвера Linux, SDK не компилируется после clean. Случай 1: Решение: используйте ./build.sh для полной перекомпиляции. Случай 2: Решение: выполните команду: $ make ARCH=arm CROSS_COMPILE=/home/luckfox/Luckfox-Pico/luckfox-pico/tools/linux/toolchain/\
arm-rockchip830-linux-uclibcgnueabihf/bin/arm-rockchip830-linux-uclibcgnueabihf-
На платах LuckFox, включая Pico Mini, нет единой универсальной команды, которая бы просто вывела "список разрешенных периферийных устройств". Вместо этого используется комбинация команд для анализа Device Tree (дерева устройств) и состояния ядра Linux. Вот как это правильно сделать: 1. Основной способ: анализ Device Tree Device Tree (DT) — это структура данных, которая описывает аппаратное обеспечение платы ядру Linux. Именно в ней "разрешаются" или "запрещаются" периферийные устройства. Самая важная команда: # cat /sys/firmware/devicetree/base/compatible
Эта команда покажет модель вашей платы, которую ядро использует для загрузки правильной конфигурации. Для LuckFox Pico Mini вы увидите что-то вроде: $ adb shell
[root@luckfox ]# cat /sys/firmware/devicetree/base/compatible
rockchip,rv1103g-38x38-ipc-v10rockchip,rv1103
Чтобы посмотреть, какие устройства "включены" в текущей Device Tree, используйте: a) Просмотр всех узлов (devices) в дереве: [root@luckfox ]# ls /proc/device-tree/
#address-cells pwm@ff350010
#size-cells pwm@ff350020
acodec-sound pwm@ff350030
acodec@ff480000 pwm@ff360000
adc-keys pwm@ff360010
aliases pwm@ff360020
arm-debug@ff200000 pwm@ff360030
arm-pmu pwm@ff490000
chosen pwm@ff490010
clock-controller@ff3a0000 pwm@ff490020
clocks pwm@ff490030
compatible restart-poweroff
cpu0-opp-table rga@ff980000
cpuinfo rkcif-dvp
cpus rkcif-mipi-lvds
csi2-dphy-hw@ff3e8000 rkcif-mipi-lvds-sditf
csi2-dphy0 rkcif-mipi-lvds1
csi2-dphy1 rkcif@ffa10000
csi2-dphy2 rkdvbm@ffa70000
dht11_sensor rkisp-vir0
dma-controller@ff420000 rkisp@ffa00000
ethernet@ffa80000 rkvenc-pp@ffa60000
fiq-debugger rkvenc@ffa50000
i2c@ff310000 rng@ff448000
i2c@ff320000 rockchip-amp
i2c@ff450000 rockchip-suspend
i2c@ff460000 rockchip-system-monitor
i2c@ff470000 rve@ffad0000
i2s@ffae0000 saradc@ff3c0000
interrupt-controller@ff1f0000 serial-number
interrupt-parent serial@ff4a0000
leds serial@ff4b0000
memory serial@ff4c0000
mipi-csi2-hw@ffa20000 serial@ff4d0000
mipi-csi2-hw@ffa30000 serial@ff4e0000
mipi0-csi2 serial@ff4f0000
mmc@ff9a0000 spi@ff500000
mmc@ffa90000 spi@ff510000
mmc@ffaa0000 spi@ffac0000
model sram@ff6c0000
mpp-srv syscon@ff000000
mpp-vcodec syscon@ff388000
name syscon@ff538000
npu@ff660000 thermal-zones
otp@ff3d0000 timer
pinctrl tsadc@ff3c8000
power-management@ff300000 usb2-phy@ff3e0000
psci usbdrd
pvtm@ff240000 vcc-1v8
pvtm@ff390000 vcc-3v3
pwm@ff350000 vdd-arm
Это покажет список всех узлов высокого уровня (например, `gpio@fdd60000`, `serial@ff9c0000`). Это не названия периферии в привычном виде, а технические имена. b) Поиск по ключевым словам (самый практичный метод). Используйте `grep` для поиска упоминаний конкретных интерфейсов в смонтированном дереве устройств. Для UART (последовательный порт): # find /proc/device-tree/ -name "*uart*" | head -5
Для I2C: # find /proc/device-tree/ -name "*i2c*" | head -5
Для SPI: # find /proc/device-tree/ -name "*spi*" | head -5
Для PWM: # find /proc/device-tree/ -name "*pwm*" | head -5
Если команда возвращает пути к файлам (например, `/proc/device-tree/pwm@fdd70000`), значит, этот контроллер активирован в Device Tree. 2. Проверка, загрузились ли драйверы устройств. Даже если устройство разрешено в DT, стоит проверить, увидело ли его ядро и загрузило ли драйвер. a) Просмотр списка зарегистрированных устройств: # ls /sys/devices/platform/
Здесь вы увидите список платформенных устройств, которые были обнаружены ядром. b) Проверка конкретных интерфейсов. I2C: посмотреть, какие I2C адаптеры (шины) доступны в системе. # i2cdetect -l
SPI: проверить, есть ли устройства SPI. # ls /dev/spidev*
PWM: посмотреть, экспортированы ли каналы PWM. # ls /sys/class/pwm/
GPIO: управление GPIO происходит через sysfs. # ls /sys/class/gpio/
UART: последовательные порты. # ls /dev/ttyS*
3. Прямой просмотр исходного файла Device Tree (если есть доступ). Самый полный, но и самый сложный способ — посмотреть исходный файл *.dts. Его обычно нет на самой плате, но он есть в SDK на вашем компьютере. Путь в SDK, на примере платы LuckFox Pico Mini: $ find . -name rv1103g-luckfox-pico-mini.dts
./sysdrv/source/kernel/arch/arm/boot/dts/rv1103g-luckfox-pico-mini.dts
В этом файле вы можете найти все блоки вида: &pwm0 { Строка `status = "okay";` означает, что устройство разрешено. Если стоит `status = "disabled";` — устройство отключено. Краткий итог для быстрой проверки на плате LuckFox Pico Mini: 1. UART: `ls /dev/ttyS*` (должен быть `ttyS0` и другие). Вывод: не существует команды наподобие `list-peripherals`. Чтобы узнать список разрешенных устройств, нужно анализировать дерево устройств через `/proc/device-tree/` и проверять состояние драйверов в `/sys/` и `/dev/`. Предположим, что на плате LuckFox Pico Mini есть директория /oem/spitest, и в ней вы тестируете программу в исполняемом файл spi, который для обновления нужно каждый раз перезаписывать. Тогда скрипт компиляции может выглядеть примерно так: #!/bin/bash В этом примере команда adb shell "rm /oem/spitest/spi" удалит исполняемый файл на плате LuckFox Pico Mini, а команда adb push ./spi /oem/spitest запишет его обновленную версию. Можно посмотреть и отфильтровать лог компиляции, но ИМХО самый простой и надежный способ - внести в файл *.dts намеренную ошибку. Можно временно переименовать измененный вами файл, либо вставить в него что-то недопустимое, например: ... Выполните команду ./build.sh, и если этот исправленный файл компилируется, то скрипт выдаст ошибку: ...
Error: /home/user/luckfox-pico/sysdrv/source/kernel/arch/arm/boot/dts/rv1103g-luckfox-pico-mini.dts:
61.1-45 syntax error
FATAL ERROR: Unable to parse input tree
make[4]: *** [scripts/Makefile.lib:381: arch/arm/boot/dts/rv1103g-luckfox-pico-mini.dtb] Error 1
make[3]: *** [/home/user/luckfox-pico/sysdrv/source/kernel/Makefile:1464: rv1103g-luckfox-pico-mini.dtb]
Error 2
make[3]: *** Waiting for unfinished jobs....
CALL /home/user/luckfox-pico/sysdrv/source/kernel/scripts/atomic/check-atomics.sh
CALL /home/user/luckfox-pico/sysdrv/source/kernel/scripts/checksyscalls.sh
make[2]: *** [arch/arm/Makefile:375: rv1103g-luckfox-pico-mini.img] Error 2
make[2]: Leaving directory '/home/user/luckfox-pico/sysdrv/source/objs_kernel'
make[1]: *** [Makefile:185: __sub-make] Error 2
make[1]: Leaving directory '/home/user/luckfox-pico/sysdrv/source/kernel'
make: *** [Makefile:486: kernel] Error 1
make: Leaving directory '/home/user/luckfox-pico/sysdrv'
При попытке перепрошить образ утилита upgrade_tool выдает сообщение, что не подключено устройство rockusb: $ upgrade_tool uf output/image/update.imgNo found any rockusb device,please plug device in!
Проблема в том, что платка LuckFox Pico не введена в режим программирования. Для входа в режим программирования отключите кабель USB (тем самым обесточите плату), нажмите и удерживайте кнопку BOOT, и снова подключите кабель USB. После этого отпустите кнопку BOOT. Устройство готово к прошивке утилитой upgrade_tool. $ upgrade_tool uf output/image/update.img
Loading firmware...
Support Type:1106 FW Ver:0.0.00 FW Time:2025-09-23 15:00:24
Loader ver:1.01 Loader Time:2025-09-23 14:56:47
Start to upgrade firmware...
Download Boot Start
Download Boot Success
Wait For Maskrom Start
Wait For Maskrom Success
Test Device Start
Test Device Success
Check Chip Start
Check Chip Success
Get FlashInfo Start
Get FlashInfo Success
Prepare IDB Start
Prepare IDB Success
Download IDB Start
Download IDB Success
Download Firmware Start
Download Image... (100%)
Download Firmware Success
Upgrade firmware ok.
Откройте файл luckfox-pico/config/dts_config (это символическая ссылка), отредактируйте: ... После этого осталось перекомпилировать и перепрошить: $ ./build.sh
$ upgrade_tool uf output/image/update.img
[Временная настройка статического адреса (до перезагрузки)] С помощью команд ifconfig и route: # ifconfig eth0 192.168.1.100 netmask 255.255.255.0 up
# route add default gw 192.168.1.1
Или используя команду ip: # ip addr add 192.168.1.100/24 dev eth0
# ip link set eth0 up
# ip route add default via 192.168.1.1
[Настройка через DHCP] Запуск DHCP клиента: # udhcpc -i eth0
Или используя systemd (если доступен): # systemctl restart networking
[Постоянная настройка] 1. Добавьте в конфигурационный файл сетевых интерфейсов /etc/network/interfaces: # Для DHCP: iface eth0 inet dhcp Если выполнить следующую команду, то настройки применятся: # ifdown eth0 && ifup eth0
Однако для того, чтобы эти настройки применялись при перезагрузке, сделайте следующее: 2. Создайте файл S40eth0config в папке /etc/init.d: # touch /etc/init.d/S40eth0config
3. Добавьте в него следующий текст: #!/bin/sh 4. Сделайте этот файл исполняемым: # chmod +x /etc/init.d/S40eth0config
Теперь после перезагрузки будет запускаться скрипт S40eth0config, и настройки будут применяться. 5. Настройте систему разрешения имен DNS: # echo "nameserver 8.8.8.8" > /etc/resolv.conf
# echo "nameserver 1.1.1.1" >> /etc/resolv.conf
# echo "nameserver 192.168.1.1" >> /etc/resolv.conf
[Проверка конфигурации] Проверка IP адреса: # ip addr show eth0
# ifconfig eth0
Проверка маршрутизации: # ip route
# route -n
Проверка разрешения имен DNS: # ping 8.8.8.8
# ping google.com
См. также совет Q082 [2]. Если вам нужно просто выполнить команды при загрузке, используйте /etc/rc.local. 1. Создайте или отредактируйте файл: # vi /etc/rc.local
2. Добавьте в него содержимое: #!/bin/sh 3. Сделайте /etc/rc.local исполняемым: # chmod +x /etc/rc.local
В последней версии плат Luckfox Pico сервис SSH по умолчанию разрешен. [Buildroot] Login: root [Ubuntu] Login: pico Для подключения выполните команду ssh root@IP_адрес, например: $ ssh root@172.32.0.93
После чего введите пароль luckfox. Подключение по Ethernet — это очень удобный способ работы с LuckFox Pico Mini, так как он обеспечивает стабильное и быстрое соединение. Вот пошаговая инструкция, как это сделать. [Предварительные требования] Сетевая инфраструктура: Ваш компьютер и плата LuckFox Pico Mini должны быть подключены к одной локальной сети (к одному маршрутизатору/свитчу). [Пошаговая инструкция] Шаг 1: Первоначальная настройка платы через USBПодключите плату LuckFox Pico Mini к компьютеру с помощью кабеля USB-C (подключите его к порту OTG на плате). Шаг 2: Настройка сети на плате LuckFox Pico MiniТеперь нужно настроить плату на получение IP-адреса по DHCP от вашего роутера или задать статический IP-адрес. Способ А: Настройка DHCP (рекомендуется для большинства случаев) Отредактируйте файл конфигурации сети. Часто для этого используется файл
Способ Б: Настройка статического IP-адреса Если вы хотите задать фиксированный IP-адрес, отредактируйте файл конфигурации.
Шаг 3: Определение IP-адреса платыПосле настройки сети вам нужно узнать, какой IP-адрес получила плата. На плате выполните команду:
Найдите строку Шаг 4: Подключение ADB по TCP/IPПодключитесь к плате по USB и убедитесь, что ADB видит устройство через USB. На компьютере выполните в командной строке (или PowerShell/Terminal):
Должен появиться список устройств. Если ваша плата подключена по USB, она там будет (возможно, с статусом Переведите ADB в режим TCP/IP на указанный порт (по умолчанию 5555): Выполните команду, где
В ответ вы должны увидеть сообщение: Подключитесь к плате по сети с помощью ADB:
Например: Проверьте соединение:
Теперь в списке должно отображаться ваше устройство по сетевому адресу, например: Готово! Теперь вы можете использовать все стандартные команды ADB ( [Важные замечания и советы] Автозапуск ADBD по сети: Чтобы не выполнять Теперь вы можете удобно работать с вашей LuckFox Pico Mini по быстрому и надежному Ethernet-соединению. Когда у вас подключено несколько устройств, нужно явно указывать, к какому из них обращаться. Вот как это делается. [Проверка списка подключенных устройств] Сначала всегда смотрите, какие устройства доступны:
Пример вывода:
[Способы указания устройства для adb shell] Способ А: Использование параметра
|
Технология | Назначение | Уровень |
---|---|---|
RKMPI | Мультимедиа (видео/аудио) | Низкоуровневый |
RKNN | Нейронные сети (AI) | Высокоуровневый |
GStreamer | Мультимедиа пайплайны | Прикладной |
OpenCV | Компьютерное зрение | Библиотека |
В итоге: RKMPI — это фундаментальный инструмент для создания высокопроизводительных мультимедийных приложений на LuckFox Pico Mini, обеспечивающий прямой доступ к аппаратным возможностям чипа Rockchip.
См. также:
Q040. Что такое RKNN?
RKMPI Instance User Guide site:wiki.luckfox.com.
OpenCV (Open Source Computer Vision Library) — это открытая библиотека компьютерного зрения, одна из самых популярных и мощных в своей области.
[Что такое OpenCV?]
OpenCV — это кроссплатформенная библиотека, содержащая более 2500 оптимизированных алгоритмов для:
- Компьютерного зрения
- Обработки изображений
- Машинного обучения
- Анализа видео
Основные возможности OpenCV:
1. Обработка изображений
# python
import cv2
import numpy as np
# Загрузка изображения img = cv2.imread('image.jpg')
# Изменение размера resized = cv2.resize(img, (640, 480))
# Размытие blurred = cv2.GaussianBlur(img, (5, 5), 0)
# Обнаружение краев edges = cv2.Canny(img, 100, 200)
# Пороговая обработка gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, threshold = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
2. Работа с видеопотоком и камерами
# python
# Захват видео с камеры cap = cv2.VideoCapture(0)
while True: ret, frame = cap.read() if not ret: break # Обработка кадра gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) cv2.imshow('Camera', gray_frame) if cv2.waitKey(1) & 0xFF == ord('q'): break
cap.release() cv2.destroyAllWindows()
3. Обнаружение объектов и лиц
# python
# Загрузка классификатора для лиц face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# Обнаружение лиц faces = face_cascade.detectMultiScale(gray, 1.1, 4)
# Рисование прямоугольников вокруг лиц
for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
4. Машинное обучение
# python
# K-mean кластеризация criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) _, labels, centers = cv2.kmeans(data, 3, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
# SVM классификатор svm = cv2.ml.SVM_create() svm.setType(cv2.ml.SVM_C_SVC) svm.setKernel(cv2.ml.SVM_LINEAR) svm.train(training_data, cv2.ml.ROW_SAMPLE, labels)
Ключевые модули OpenCV:
Модуль | Назначение |
---|---|
core | Основные структуры данных и функции |
imgproc | Обработка изображений |
video | Анализ видео и трекинг |
calib3d | Калибровка камер и 3D реконструкция |
features2d | Детекторы и дескрипторы признаков |
objdetect | Обнаружение объектов |
ml | Машинное обучение |
dnn | Глубокие нейронные сети |
[Установка OpenCV]
Для Python:
# Базовая установка
$ pip install opencv-python
# Полная установка (с contrib модулями)
$ pip install opencv-contrib-python
Для Ubuntu:
# Установка из репозитория
$ sudo apt update
$ sudo apt install python3-opencv
# Или компиляция из исходников
$ sudo apt install build-essential cmake git libgtk2.0-dev pkg-config \
libavcodec-dev libavformat-dev libswscale-dev
$ git clone https://github.com/opencv/opencv.git
$ cd opencv && mkdir build && cd build
$ cmake .. && make -j4 && sudo make install
[Практические примеры использования]
1. Распознавание QR-кодов:
# python detector = cv2.QRCodeDetector() data, bbox, _ = detector.detectAndDecode(img)
if data: print("QR Code data:", data)
2. Детектирование движения:
# python
# Фоновая субтракция fgbg = cv2.createBackgroundSubtractorMOG2()
while True: ret, frame = cap.read() fgmask = fgbg.apply(frame) # Анализ маски движения
3. Калибровка камеры:
# python
# Поиск шахматной доски ret, corners = cv2.findChessboardCorners(gray, (9, 6), None)
if ret: cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
[Преимущества OpenCV]
1. Кроссплатформенность
- Windows, Linux, macOS, Android, iOS
- Embedded системы (Raspberry Pi, LuckFox Pico)
2. Поддержка многих языков программирования
- C++, Python, Java, JavaScript
- Интерфейсы для MATLAB, Ruby
3. Высокая производительность
- Оптимизированные алгоритмы
- Поддержка GPU (CUDA, OpenCL)
- Векторизация инструкций
4. Активное сообщество
- Регулярные обновления
- Большая база примеров
- Подробная документация
[OpenCV в embedded-системах (например, LuckFox Pico)]
# python
# Пример для embedded устройства
import cv2
# Использование аппаратного ускорения cv2.setUseOptimized(True)
# Работа с камерой MIPI cap = cv2.VideoCapture(0) # CSI камера
# Экономная обработка для маломощных устройств small_frame = cv2.resize(frame, (320, 240)) gray = cv2.cvtColor(small_frame, cv2.COLOR_BGR2GRAY)
Типовые области применения:
- Робототехника (навигация, SLAM)
- Медицина (анализ снимков)
- Безопасность (распознавание лиц, детектирование движения)
- Автомобильная промышленность (ADAS)
- Дополненная реальность
- Промышленный контроль качества
В итоге: OpenCV — это "швейцарский нож" для разработчиков в области компьютерного зрения, предоставляющий готовые, оптимизированные алгоритмы для самых разнообразных задач обработки изображений и видео.
Например:
$ adb devices
List of devices attached
359238bf91d2b5a8 device
192.168.1.100:5555 device
Чтобы подключиться к нужному устройству из этого списка, используйте опцию -s, например:
$ adb -s 192.168.1.100:5555 shell
[root@luckfox ]#
Чтобы отключить устройство, используйте adb disconnect:
$ adb disconnect 192.168.1.100:5555
disconnected 192.168.1.100:5555
$ adb devices
List of devices attached
359238bf91d2b5a8 device
Чтобы снова подключить устройство, используйте команду adb connect:
$ adb connect 192.168.1.100:5555
connected to 192.168.1.100:5555
$ adb devices
List of devices attached
359238bf91d2b5a8 device
192.168.1.100:5555 device
Отключение всех сетевых устройств, используется adb disconnect без параметров (отключатся только сетевые устройства, USB-устройство останется подключенным):
$ adb disconnect
disconnected everything
$ adb devices
List of devices attached
359238bf91d2b5a8 device
Полная перезагрузка ADB сервера (если нужно):
$ adb kill-server
$ adb start-server
Такая необходимость может возникнуть, если по какой-то причине подключиться через USB/ADB или Ethernet/SSH не представляется возможным. Например, вы собираетесь пересобрать Buildroot в конфигурации, когда порт USB будет использоваться как хост USB.
[Что понадобится]
1. Переходничок USB - TTL UART с уровнями логики 3.3V (на чипе CP2102, CH340, FT232 и т. п.).
2. Программа терминала на компьютере хоста - putty или minicom, или что-то подобное.
3. Плата LuckFox Pico.
[Как определить сигналы RX и TX]
1. Просмотрите список портов tty командой:
[root@luckfox ]# ls -1 /dev | grep tty
Выведется примерно вот такой список:
tty
tty0
tty1
tty10
tty11
..
tty8
tty9
ttyFIQ0
Ищите в этом списке устройства ttyS*, ttyAMA*, ttyFIQ*. Обычно для подключения к консоли используют ttyS0 и ttyFIQ0.
Также можно просмотреть список загрузочных сообщений командой:
[root@luckfox ]# cat /proc/cmdline
user_debug=31
storagemedia=mtd
androidboot.storagemedia=mtd
androidboot.mode=normal rootwait
earlycon=uart8250,mmio32,0xff4c0000
console=ttyFIQ0
root=ubi0:rootfs
snd_soc_core.prealloc_buffer_size_kbytes=16
coherent_pool=0
mtdparts=spi-nand0:256K(env),256K@256K(idblock),512K(uboot),4M(boot),
30M(oem),6M(userdata),85M(rootfs)
ubi.mtd=6 rootfstype=ubifs
rk_dma_heap_cma=24M
androidboot.fwver=uboot-09/23/2025
В этом примере видно, что для консоли используется ttyFIQ0.
2. Запустите в терминале команду:
[root@luckfox ]# echo "hello" > /dev/ttyFIQ0
И с помощью осциллографа смотрите, на каком выводе появится сигнал передачи UART. На моей платке LuckFox Pico Mini B это оказался контакт 4 (порт 42, GPIO1_B2_d, UART2_TX_M1).
Это и будет сигнал TX. По длительности минимального бита видно, что это скорость 115200 бод. Соответственно сигнал RX будет на контакте 5 (порт 43, GPIO1_B3_u, UART2_RX_M1).
3. С помощью программы luckfox-config можно ознакомиться с текущей настройкой выводов:
[root@luckfox root]# luckfox-config show
Luckfox_Pico_MiniA/B
+ -USB- +
- - VBUS | | 1V8 - -
- - GND | | GND - -
- - 3V3 | | GPIO4_C1 - SARADC_M1 -
- FIQtty_TX - GPIO1_B2 | | GPIO4_C0 - SARADC_M0 -
- FIQtty_RX - GPIO1_B3 | | GPIO0_A4 - - PWM1_M0
PWM2_M2 - SPI0_M0_CS0 - GPIO1_C0 | | GPIO1_C7 - - PWM11_M1
PWM4_M2 - SPI0_M0_CLK - GPIO1_C1 | | GPIO1_C6 - - PWM10_M1
PWM5_M2 - SPI0_M0_MOSI - GPIO1_C2 | | GPIO1_D3 - I2C3_M1_SCL - PWM11_M2
PWM6_M2 - SPI0_M0_MISO - GPIO1_C3 | | GPIO1_D2 - I2C3_M1_SDA - PWM0_M1
PWM8_M1 - UART4_M1_RX - GPIO1_C4 | | GPIO1_D1 - UART3_M1_RX - PWM10_M2
PWM9_M1 - UART4_M1_TX - GPIO1_C5 | | GPIO1_D0 - UART3_M1_TX - PWM3_M2
+ - + - +
[Подключение к консоли]
Подключите переходничок адаптера USB - TTL UART к сигналам TX и RX платы:
LuckFox Pico Mini B USB-UART адаптер
UART2_TX_M1 → RX
UART2_RX_M1 ← TX
GND GND
Настройте подключение к порту адаптера USB - TTL UART с помощью программы терминала на скорости 115200, 8 бит данных, 1 стоп-бит, без контроля четности. Можно использовать различные программы терминала.
Windows:
Putty
Tera Term
SecureCRT
Linux/macOS:
Minicom
Screen
Picocom
Putty
Пример подключения с помощью minicom (логин root, пароль luckfox):
$ minicom -D /dev/ttyUSB1
Welcome to minicom 2.9
OPTIONS: I18n
Port /dev/ttyUSB1, 09:40:33
Press CTRL-A Z for help on special keys
Welcome to luckfox pico
luckfox login: root
Password:
[root@luckfox root]#
~/luckfox-pico$ upgrade_tool ul output/image/update.img
Loading loader...
Support Type:RK1106 Loader ver:1.01 Loader Time:2025-09-30 13:58:34
Start to upgrade loader...
Download Boot Start
Download Boot Success
Wait For Maskrom Start
Wait For Maskrom Success
Test Device Start
Test Device Success
Check Chip Start
Check Chip Success
Get FlashInfo Start
Get FlashInfo Success
Prepare IDB Start
Prepare IDB Success
Download IDB Start
Download IDB Success
Upgrade loader ok.
Проблема в том, что upgrade_tool загрузил только загрузчик (loader), но не саму прошивку.
Что произошло:
Загрузчик успешно загружен в RAM.
Утилита перевела устройство в режим Maskrom.
Утилита проверила чип и информацию о flash-памяти.
Но не записала основную прошивку.
Проблема в том, что была ошибочно указана опция ul (upgrade loader) вместо uf (upgrade firmware).
Решения:
1. Используйте параметр uf для полной прошивки:
$ upgrade_tool uf output/image/update.img
2. Или используйте для принудительной записи:
$ upgrade_tool uf output/image/update.img
3. Проверьте режим устройства:
$ upgrade_tool pl
Убедитесь, что устройство в режиме Loader или Maskrom.
4. Альтернативные команды: используйте RKDevTool (графическая утилита) или rkdeveloptool.
$ rkdeveloptool db output/image/update.img
$ rkdeveloptool wl 0 output/image/update.img
$ rkdeveloptool rd
Порядок действий:
- Переведите устройство в режим Maskrom (зажать кнопку Boot и нажать Reset или выдернуть и снова вставить кабель).
- Выполните: upgrade_tool uf output/image/update.img.
- Дождитесь полного завершения процесса.
Ключевое отличие: ul загружает только loader, uf прошивает всю систему.
[Начальная компиляция по умолчанию]
Перейдите в каталог SDK:
$ cd ~/luckfox-pico
Начинать надо с выбора платы:
$ ./build.sh lunch
Теперь можно компилировать:
$ ./build.sh
После этого можно прошить память SPI FLASH командой:
$ upgrade_tool uf output/image/update.img
[Конфигурирование пакетов и ядра Buildroot]
Сборка пакетов и приложений конфигурируется командой:
$ ./build.sh buildrootconfig
Сборка ядра конфигурируется командой:
$ ./build.sh kernelconfig
Подсказка по командам:
$ ./build.sh --help
Usage: build.sh [OPTIONS]
Available options:
lunch -Select Board Configure
env -build env
meta -build meta (optional)
uboot -build uboot
kernel -build kernel
rootfs -build rootfs
driver -build kernel's drivers
sysdrv -build uboot, kernel, rootfs
media -build rockchip media libraries
app -build app
recovery -build recovery
tool -build tool
updateimg -build update image
unpackimg -unpack update image
factory -build factory image
all -build uboot, kernel, rootfs, recovery image
allsave -build all & firmware & save
clean -clean all
clean uboot -clean uboot
clean kernel -clean kernel
clean driver -clean driver
clean rootfs -clean rootfs
clean sysdrv -clean uboot/kernel/rootfs
clean media -clean rockchip media libraries
clean app -clean app
clean recovery -clean recovery
firmware -pack all the image we need to boot up system
ota -pack update_ota.tar
save -save images, patches, commands used to debug
check -check the environment of building
info -see the current board building information
buildrootconfig -config b # EMMCuildroot and save defconfig
kernelconfig -config kernel and save defconfig
Default option is 'allsave'.
По умолчанию интерфейс USB платки LuckFox Pico в сборке Buildroot работает в режиме устройства USB. Это сделано, в частности, чтобы при подключении через USB к компьютеру можно было подключиться к LuckFox Pico командой adb shell.
$ adb devices
* daemon not running; starting now at tcp:5037
* daemon started successfully
List of devices attached
359238bf91d2b5a8 device
Переконфигурировать USB на работу в режиме хоста можно с помощью команды luckfox-config в терминале Buildroot и последующей перезагрузкой.
Примечание: если вы запустите Buildroot, когда USB работает в режиме хоста, нельзя будет подключаться через adb к плате. Восстановить работу adb можно через подключение Ethernet, если оно у вас настроено, см. Q036. Также можно получить доступ к консоли терминала через UART, см. Q044.
Итак, как переконфигурировать сборку Buildroot, чтобы интерфейс USB работал в режиме хоста. Подключитесь к терминалу Buildroot, и введите команду:
[root@luckfox root]# luckfox-config
Откроется меню конфигурации, войдите в раздел Advanced Options -> USB.
Выберите вариант 2 host, нажмите пробел, это соответствует нажатию кнопки OK для подтверждения выбора. Появится окно о необходимости перезагрузки для того, чтобы изменения вступили в силу.
Нажмите еще раз пробел (OK), и несколько раз Esc для выхода из меню конфигурации. Выполните команду перезагрузки:
[root@luckfox root]# reboot
Чтоб можно было подключать устройства USB, необходимо подать питание +5V на контакт 1 (VBUS) платки LuckFox Pico:
Теперь платка LuckFox Pico будет обнаруживать подключаемые к ней устройства. Вам понадобится USB-хаб с коннектором USB Type-C, например T-809A, T-809B, или любой другой:
При подключении хаба T-809A в консоли Buildroot появится сообщение:
[root@luckfox root]# [ 187.785069] usb 1-1: new high-speed USB device
number 2 using xhci-hcd
[ 187.990667] hub 1-1:1.0: USB hub found
[ 187.991568] hub 1-1:1.0: 4 ports detected
v4l_id - это вспомогательная утилита в Linux-системах, которая играет важную роль в автоматическом определении и настройке видеоустройств, которая:
- Принадлежит пакету udev (система управления устройствами).
- Специализируется на идентификации Video4Linux (V4L/V4L2) устройств.
- Вызывается автоматически демоном udevd при обнаружении нового видеоустройства.
[Основные функции v4l_id]
1. Сбор информации о видеоустройстве:
- Определяет возможности устройства (форматы, разрешения)
- Читает технические характеристики через V4L2 API
- Получает идентификаторы устройства (модель, производитель)
2. Создание симлинков в /dev/v4l/:
/dev/v4l/by-id/usb-VIDEO_DEVICE_NAME-video-index0
/dev/v4l/by-path/platform-xxxx.usb-usb-0:1.2:1.0-video-index0
Это позволяет обращаться к устройствам по постоянным именам, а не по меняющимся /dev/video0, /dev/video1 и т.д.
Почему v4l_id отсутствует в вашей Buildroot?
В конфигурации Buildroot для LuckFox Pico Mini B часто включают только минимальный набор компонентов для экономии места. Утилита v4l_id может быть исключена как "необязательная".
Как добавить v4l_id в Buildroot?
Способ 1: Через menuconfig или buildrootconfig.
$ cd ~/luckfox-pico/sysdrv/source/buildroot/buildroot-2023.02.6
$ make menuconfig
Или:
$ cd ~/luckfox-pico
$ ./build.sh buildrootconfig
Перейдите в разделы:
Target packages
→ Hardware handling
→ udev
→ [*] Enable udev support
→ [*] Install udev rules for V4L devices
Способ 2: Проверка существующих пакетов
Некоторые пакеты автоматически включают v4l_id:
$ make menuconfig
И проверьте:
Target packages
→ Multimedia
→ [*] v4l2-utils
Что происходит без v4l_id?
- Устройства создаются: /dev/video0, /dev/video1 и т. д.
- Работоспособность: jсновные функции видео работают нормально
- Недостатки:
- Нет удобных симлинков в `/dev/v4l/by-*`
- В логах появляются ошибки `failed to execute '/lib/udev/v4l_id'`
- Автоматическая классификация устройств не работает
Проверка наличия v4l_id, установлена ли утилита:
# which v4l_id
# ls -la /lib/udev/v4l_id
Проверить наличие симлинков (которые создает v4l_id):
# ls -la /dev/v4l/by-id/
# ls -la /dev/v4l/by-path/
Практическое значение для LuckFox Pico. На платах типа LuckFox Pico, где часто подключаются USB-камеры и устройства видеозахвата, наличие v4l_id полезно для:
1. Стабильности имен - если у вас несколько камер, их порядок в /dev/video* может меняться при перезагрузке.
2. Автоматизации - скрипты могут надежно обращаться к устройствам по постоянным именам.
3. Отладки - проще идентифицировать конкретное устройство в системе.
v4l_id - это не критически важный компонент, но очень полезная утилита для правильной организации видеоустройств в системе. Ее отсутствие не мешает базовой работе с камерами, но создает неудобства и сообщения об ошибках в логах.
eudev - это реализация системы udev (userspace device manager), специально разработанная для встраиваемых систем и дистрибутивов вроде Buildroot. Утилита eudev (Embedded udev) заменяет оригинальную утилиту systemd-udev от Red Hat, которая:
- Работает независимо от systemd
- Оптимизирована для встраиваемых систем с ограниченными ресурсами
- Обеспечивает динамическое управление устройствами в `/dev`
[Основные функции eudev в Buildroot]
1. Динамическое создание узлов устройств в /dev. Без eudev пришлось бы создавать все устройства статически (через `mknod`), что неэффективно для систем с подключаемыми устройствами.
2. Автоматическая загрузка драйверов. При подключении устройства eudev определяет, какой драйвер нужен, и загружает его.
3. Создание симлинков и персистентных имен. Пример того, что создает eudev:
/dev/disk/by-id/usb-SanDisk_Cruzer_Blade_000000000000-0:0
/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A900cePY-if00-port0
/dev/v4l/by-id/usb-VIDEO_DEVICE_NAME-video-index0
4. Запуск скриптов при обнаружении устройств. Eudev выполняет правила из `/etc/udev/rules.d/` при подключении/отключении устройств.
[Конфигурация eudev в Buildroot для LuckFox Pico]
Включение eudev:
$ make menuconfig
System configuration
→ /dev management (Dynamic using eudev)
→ [*] eudev (Dynamic using eudev)
Дополнительные опции:
Target packages
→ Hardware handling
→ [*] eudev
→ [*] Enable udev support
→ [*] Install udev rules for V4L devices # включает v4l_id
→ [*] Install udev rules for devpts
Почему eudev важен для LuckFox Pico?
Для USB-устройств (камеры, флешки, последовательные порты):
- Автоматическое создание /dev/video0, /dev/sda1, /dev/ttyUSB0
- Стабильные имена через симлинки в /dev/disk/by-id/, /de/serial/by-id/
Для встроенных периферийных устройств:
- GPIO, I2C, SPI устройства
- Аудиоустройства
- Сетевые интерфейсы
Что происходит без eudev? Без eudev в Buildroot обычно используются:
1. Статический /dev - все устройства создаются при компиляции
2. mdev - более легковесная альтернатива (устаревшая)
3. devtmpfs - базовая функциональность без сложных правил
[Практический пример с USB-камерой]
С eudev при подключении камеры автоматически:
[ 561.687738] uvcvideo: Found UVC 1.00 device AV TO USB2.0
- Создается /dev/video0
- Создаются симлинки: /dev/v4l/by-id/usb-AV_TO_USB2.0-video-index0
- Загружается драйвер uvcvideo
Без eudev:
- Устройство появится в /dev/videoX (если драйвер загружен)
- Но не будет симлинков и дополнительной метаинформации
- Могут отсутствовать автоматические действия при подключении
Структура каталогов eudev
/etc/udev/rules.d/ # Пользовательские правила
/lib/udev/rules.d/ # Системные правила
/lib/udev/ # Вспомогательные утилиты
├── v4l_id # Для видеоустройств
├── ata_id # Для ATA устройств
└── scsi_id # Для SCSI устройств
[Отладка eudev]
Просмотр событий eudev в реальном времени:
[root@luckfox root]# udevadm monitor
Информация об устройстве:
[root@luckfox root]# udevadm info /dev/video0
P: /devices/platform/usbdrd/ffb00000.usb/xhci-hcd.0.auto/usb1/1-1/1-1.4/
1-1.4:1.0/video4linux/video21
N: video21
S: v4l/by-id/usb-MACROSILICON_AV_TO_USB2.0_20200909-video-index0
S: v4l/by-path/platform-xhci-hcd.0.auto-usb-0:1.4:1.0-video-index0
E: DEVLINKS=/dev/v4l/by-id/usb-MACROSILICON_AV_TO_USB2.0_20200909-video-index0
/dev/v4l/by-path/platform-xhci-hcd.0.auto-usb-0:1.4:1.0-video-index0
E: DEVNAME=/dev/video21
E: DEVPATH=/devices/platform/usbdrd/ffb00000.usb/xhci-hcd.0.auto/usb1/
1-1/1-1.4/1-1.4:1.0/video4linux/video21
E: ID_BUS=usb
E: ID_MODEL=AV_TO_USB2.0
E: ID_MODEL_ENC=AV\x20TO\x20USB2.0
E: ID_MODEL_ID=0021
E: ID_PATH=platform-xhci-hcd.0.auto-usb-0:1.4:1.0
E: ID_PATH_TAG=platform-xhci-hcd_0_auto-usb-0_1_4_1_0
E: ID_REVISION=0121
E: ID_SERIAL=MACROSILICON_AV_TO_USB2.0_20200909
E: ID_SERIAL_SHORT=20200909
E: ID_TYPE=video
E: ID_USB_DRIVER=uvcvideo
E: ID_USB_INTERFACES=:0e0100:0e0200:030000:
E: ID_USB_INTERFACE_NUM=00
E: ID_VENDOR=MACROSILICON
E: ID_VENDOR_ENC=MACROSILICON
E: ID_VENDOR_ID=534d
E: MAJOR=81
E: MINOR=24
E: SUBSYSTEM=video4linux
E: USEC_INITIALIZED=7594482747
Тестирование правил:
[root@luckfox root]# udevadm test /sys/class/video4linux/video0
Выводы. eudev в контексте LuckFox Pico с Buildroot - это система, которая:
- ✅ Обеспечивает автоматическое управление устройствами
- ✅ Создает персистентные имена для USB-устройств
- ✅ Загружает драйверы при подключении оборудования
- ✅ Выполняет пользовательские скрипты через правила udev
Для плат разработки с частым подключением различных USB-устройств (камер, флешек, последовательных адаптеров) eudev практически необходим для удобной работы.
Я добавил в Lunux Buildroot настройку статического адреса для eth0 в файл /etc/network/interfaces:
[root@luckfox root]# cat /etc/network/interfaces
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 192.168.1.100
netmask 255.255.255.0
gateway 192.168.1.1
dns-nameservers 8.8.8.8
Однако после перезагрузки системы интерфейс eth0 не работает. Чтобы он заработал необходимо вручную запускать команду:
[root@luckfox root]# /etc/init.d/S40network restart
Почему настройка eth0 не применяется автоматически?
Проблема связана с порядком инициализации служб в Buildroot. Сеть поднимается до того, как все необходимые компоненты системы готовы.
[Причина проблемы]
В Buildroot существует несколько систем инициализации, и порядок запуска служб может отличаться:
1. Скрипт S40network запускается слишком рано (до полной инициализации драйверов).
2. Драйвер Ethernet может загружаться позже, чем пытается подняться сеть.
3. udev/eudev может не успеть проинициализировать сетевые интерфейсы.
Почему ручной перезапуск работает?
Команда `/etc/init.d/S40network restart` работает, потому что к моменту ее выполнения:
- Драйверы Ethernet уже загружены
- Система полностью проинициализирована
- Все аппаратные ресурсы готовы
Проблема именно в временном соотношении между загрузкой драйверов и запуском сетевого сервиса при старте системы.
[Решение 1: Ручная инициализация скриптами автозагрузки]
Если вы не используете скрипт rc.local, то просто добавьте строчку /etc/init.d/S40network restart в конец файла /etc/init.d/rcS. Мне как раз помог именно этот простой метод.
Если вы хотите использовать скрипт /etc/rc.local, и его запуск настроен в /etc/init.d/rcS, то добавьте в /etc/rc.local:
echo "Sleeping for network initialization..." sleep 5 /etc/init.d/S40network restart
Сделайте файл /etc/rc.local исполняемым:
# chmod +x /etc/rc.local
Перезагрузите систему:
# sync
# reboot
[Решение 2: Проверка и изменение порядка запуска]
Посмотрите порядок служб в /etc/init.d/:
# ls -la /etc/init.d/S*
Сетевой сервис должен запускаться после основных системных сервисов. Попробуйте переименовать S40network в более поздний номер:
# mv /etc/init.d/S40network /etc/init.d/S45network
[Решение 3: Добавление задержки в сетевой сервис]
1. Отредактируйте /etc/init.d/S40network и добавьте задержку перед поднятием интерфейсов:
# vi /etc/init.d/S40network
Добавьте в начало функции `start()`:
start() {
# Добавить задержку для инициализации системы
sleep 3
echo "Starting network..."
# остальной код
}
[Решение 4: Использование системы инициализации BusyBox]
Если вы используете BusyBox init, проверьте /etc/inittab:
# cat /etc/inittab
Убедитесь, что есть строка для сетевой инициализации:
::sysinit:/etc/init.d/rcS
[Решение 5: Альтернативный подход - использование dhcpcd]
Если статический IP не критичен, можно использовать DHCP. Измените настройку eth0 в файле /etc/network/interfaces:
auto eth0 iface eth0 inet dhcp
[Решение 6: Использование systemd (если доступно)]
Если в вашей сборке Buildroot используется systemd:
# systemctl enable network
# systemctl start network
[Диагностика]
Чтобы понять, в чем именно проблема, выполните диагностику.
1. Убедитесь, что драйвер Ethernet загружается. Проверить загруженные модули:
# lsmod | grep eth
Или:
# dmesg | grep eth
2. Проверить логи загрузки:
# dmesg | grep -i eth
# dmesg | grep -i network
3. Проверить статус интерфейса:
# ip link show eth0
4. Проверить, когда поднимается интерфейс:
# ip addr show eth0
5. Проверить наличие драйвера:
# lsmod | grep gmac # для LuckFox обычно gmac или подобный
[Рекомендуемое решение]
Мне помог вариант из Решения 1: просто добавил команду /etc/init.d/S40network restart в конец файла /etc/init.d/rcS. Скорее всего это поможет. Как вариант, попробуйте также Решение 2 и Решение 3.
Я создаю этот файл командой:
[root@luckfox root]# echo "nameserver 8.8.8.8" > /etc/resolv.conf
Этот файл нормально создается и участвует в распознавании DNS-имен, но после перезагрузки оказывается пустым. Почему?
Проблема с сохранением /etc/resolv.conf после перезагрузки связана с тем, как Buildroot управляет этим файлом. Вот основные причины и решения:
Причина 1. Файл /etc/resolv.conf на самом деле это символическая ссылка на временный файл:
Проверить, является ли resolv.conf симлинком:
[root@luckfox root]# ls -la /etc/resolv.conf
lrwxrwxrwx 1 1000 1000 18 Oct 16 2023 /etc/resolv.conf -> ../tmp/resolv.conf
[root@luckfox root]# ls -la /tmp/resolv.conf
-rw-r--r-- 1 root root 0 Jan 1 00:00 /tmp/resolv.conf
Причина 2. tmpfs очищается при перезагрузке. Файл в /tmp/ создается заново при каждой загрузке. Таким образом, Причина 1 и Причина 2 могут быть взаимосвязаны, и дополнить друг друга, что как раз был мой случай.
Причина 3. Сетевые скрипты перезаписывают файл. Сетевые демоны (наподобие connman, dhcpcd, network manager) могут перезаписывать resolv.conf.
Скорее для Linux Buildroot на плате LuckFox Pico скорее всего причина проблемы это комбинация Причины 1 и Причины 2. Решить проблему можно, если заменить символическую ссылку реальным файлом. Как это сделать, по шагам:
1. Удалите символическую ссылку:
[root@luckfox root]# rm -f /etc/resolv.conf
2. Создайте файл /etc/resolv.conf:
[root@luckfox root]# echo "nameserver 8.8.8.8" > /etc/resolv.conf
[root@luckfox root]# echo "nameserver 1.1.1.1" >> /etc/resolv.conf
3. Заблокируйте этот файл от изменений (необязательный шаг):
[root@luckfox root]# chattr +i /etc/resolv.conf 2>/dev/null || echo "chattr not available"
4. Перезагрузите систему:
[root@luckfox root]# sync
[root@luckfox root]# reboot
[Другие способы решения проблемы]
Решение 2: Изменить точку назначения симлинка.
Можно сохранить симлинк, но изменить его назначение. Создайте постоянный файл, на который будет ссылаться симлинк:
[root@luckfox root]# mkdir -p /etc/resolv
[root@luckfox root]# echo "nameserver 8.8.8.8" > /etc/resolv/resolv.conf.perm
[root@luckfox root]# echo "nameserver 1.1.1.1" >> /etc/resolv/resolv.conf.perm
Измените симлинк:
[root@luckfox root]# rm -f /etc/resolv.conf
[root@luckfox root]# ln -s /etc/resolv/resolv.conf.perm /etc/resolv.conf
Решение 3: Добавить в создание /etc/resolv.conf автозагрузку.
Добавьте в конец файла /etc/init.d/rcS строчки:
echo "nameserver 8.8.8.8" > /etc/resolv.conf
echo "nameserver 1.1.1.1" >> /etc/resolv.conf
Перечисленные здесь команды использовались для взаимодействия хоста разработчика на Ubuntu 24.04.3 LTS через сеть Ethernet с Linux Buildroot на платке LuckFox Pico Mini B. На Ubuntu IP-адрес 192.168.1.1, на Buildroot 192.168.1.100.
Запуск подключения к устройству LuckFox Pico Mini B:
$ adb connect 192.168.1.100:5555
connected to 192.168.1.100:5555
Передача файла скрипта videotest.sh из локального каталога хоста в домашний каталог пользователя root на платке LuckFox (почему-то домашнему каталогу root соответствует папка /oem):
$ adb -s 192.168.1.100:5555 push ./videotest.sh /oem
Запуск команды на платке LuckFox:
$ adb -s 192.168.1.100:5555 shell "ls ~"
usr videotest.sh
Описание проблемы. Вывод потока в файл работает, тестовый видеофайл /tmp/test.raw нормально создается:
[root@luckfox root]# v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=10 \
--stream-to=/tmp/test.raw
Но запуск потока на 192.168.1.1:5000 приводит к ошибке, несмотря на то, что связь с хостом 192.168.1.1 есть (ping проходит), на принимающей стороне запущена команда ffplay udp://192.168.1.100:5000.
[root@luckfox root]# v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=10 \
--stream-to=192.168.1.1:5000
could not open 192.168.1.1:5000 for writing
Почему --stream-to=192.168.1.1:5000 приводит к ошибке?
Дело в том, что v4l2-ctl --stream-to не поддерживает сетевые адреса с портами напрямую. Эта опция ожидает только путь к файлу или хост без указания порта. Таким образом, v4l2-ctl --stream-to интерпретирует 192.168.1.1:5000 как имя файла, а не сетевой адрес.
[Решение 1: Использование netcat (nc)]
На отправляющей стороне (luckfox):
# v4l2-ctl -d /dev/video0 --stream-mmap --stream-to=- | nc -u 192.168.1.1 5000
На принимающей стороне (192.168.1.1):
$ nc -ul -p 5000 | ffplay -f rawvideo -pixel_format yuyv422 -video_size 640x480 -i -
[Решение 2: Использование socat]
На отправляющей стороне:
# v4l2-ctl -d /dev/video0 --stream-mmap --stream-to=- | socat - udp-sendto:192.168.1.1:5000
На принимающей стороне:
$ ffplay -i udp://0.0.0.0:5000
[Решение 3: использование ffmpeg для потоковой передачи]
Примечание: этот вариант у меня не заработал на Buildroot, утилита ffmpeg постоянно приводила к критическому сбою.
На отправляющей стороне:
# ffmpeg -f v4l2 -input_format yuyv422 -video_size 640x480 -i /dev/video0 \
-c copy -f mpegts udp://192.168.1.1:5000
На принимающей стороне:
$ ffplay udp://192.168.1.1:5000
[Определение параметров видео]
Для оптимального использования узнайте точные параметры вашего видео. На стороне вывода:
[root@luckfox root]# v4l2-ctl -d /dev/video0 --get-fmt-video
Format Video Capture:
Width/Height : 640/480
Pixel Format : 'MJPG' (Motion-JPEG)
Field : None
Bytes per Line : 0
Size Image : 614400
Colorspace : sRGB
Transfer Function : Rec. 709
YCbCr/HSV Encoding: ITU-R 601
Quantization : Default (maps to Full Range)
Flags :
Пример вывода:
[root@luckfox root]# v4l2-ctl -d /dev/video0 --stream-mmap --stream-to=- \
| socat - udp-sendto:192.168.1.1:5000
<<<<<<<<<<<<<<<<<<<<<<<<< 25.00 fps, dropped buffers: 1
<<<<<<<<<<<<<<<<<<<<<<<<< 25.00 fps
<<<<<<<<<<<<<<<<<<<<<<<<< 25.00 fps
<<<<<<<<<<<<<<<<<<<<<<<<< 25.00 fps
<<<<<<<<<<<<<<<<<<<<<<<<< 25.00 fps
<<<<<<<<<<<<<<<<<<<<<<<<< 25.00 fps
...
Как подавить вывод, возможные варианты ниже.
[1. Перенаправление stderr в /dev/null]
Полностью подавить вывод сообщений с fps можно, если добавить 2>/dev/null к командной строке v4l2-ctl:
[root@luckfox root]# v4l2-ctl -d /dev/video0 --stream-mmap --stream-to=- \
2>/dev/null | socat - udp-sendto:192.168.1.1:5000
Мне подошел этот вариант. Его достоинство: он скрывает только информационные сообщения, но оставляет возможность видеть критические ошибки в консоли.
[2. Более точное подавление только FPS вывода]
# v4l2-ctl -d /dev/video0 --stream-mmap --stream-to=- 2>&1 | grep -v "fps" \
| socat - udp-sendto:192.168.1.1:5000
[3. Использование --silent опции (если доступно)]
Этот вариант у меня не заработал.
# v4l2-ctl -d /dev/video0 --stream-mmap --stream-to=- --silent 2>/dev/null \
| socat - udp-sendto:192.168.1.1:5000
[4. Фильтрация только ошибок]
# v4l2-ctl -d /dev/video0 --stream-mmap --stream-to=- 2>&1 >/dev/null \
| socat - udp-sendto:192.168.1.1:5000
[5. Полностью тихий режим]
# v4l2-ctl -d /dev/video0 --stream-mmap --stream-to=- >/dev/null 2>&1 \
| socat - udp-sendto:192.168.1.1:5000
Но будьте осторожны - это также скроет возможные ошибки!
Предположим, что вам нужно подключиться к платке LuckFox Pico Mini через Ethernet, платка видна по IP 192.168.1.100 (на ней работает сервер SSH).
1. Добавьте хост 192.168.1.100 список доверенных хостов SSH:
$ ssh-keygen -f '/home/имя_пользователя/.ssh/known_hosts' -R '192.168.1.100'
Здесь имя_пользователя это логин пользователя на локальной машине, 192.168.1.100 это IP удаленного сервера SSH (на платке LuckFox Pico Mini).
2. Пример выполнения команды pwd на удаленном хосте 192.168.1.100:
$ ssh root@192.168.1.100 "pwd"
root@192.168.1.100's password:
В ответ на запрос пароля введите luckfox, и команда выполнится:
/root
[sshpass]
Чтобы не надо было каждый раз вводить пароль, необходимо либо сгенерировать ключи SSH, либо воспользоваться утилитой sshpass.
Если утилита sshpass не установлена, установите её:
$ sudo apt install sshpass
Подключение с автоматическим вводом пароля:
$ sshpass -p 'luckfox' ssh user@192.168.1.1 "команда"
Недостаток использования sshpass очевиден, что её область применения пожалуй только в скриптах, потому что пароль в командной строке все равно присутствует, да еще и в открытом виде. Поэтому лучше настроить беспарольный доступ лучше с помощью обмена ключами шифрования SSH.
[Настройка доступа по ключу SSH]
1. На локальной машине выполните генерацию публичного и приватного ключей:
$ ssh-keygen -t rsa -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/home/имя_пользователя/.ssh/id_rsa): 251007luckfox
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in 251007luckfox
Your public key has been saved in 251007luckfox.pub
The key fingerprint is:
SHA256:eUJ6GQ+W2BComCfkuoF7aysNhFkYBf6SG8fJGtOeW0U имя_пользователя@TAG-5779
The key's randomart image is:
+---[RSA 4096]----+
|o=. .o. |
|o.. . + . |
|+* . .EB |
|*oO . .+ * |
|+O B ..S o |
|= X . .. o |
| O o . |
|+ + o |
| +o+ |
+----[SHA256]-----+
Здесь имя_пользователя это логин локального пользователя, 251007luckfox имя файла для генерируемого ключа. После этой команды в локальном каталоге пользователя ~ будут сгенерированы два файла:
$ ls -1 ~ | grep luckfox
251007luckfox # приватный ключ
251007luckfox.pub # публичный ключ
2. Добавьте текст сгенерированного публичного ключа в файл /root/.ssh/authorized_keys на сервере SSH. Дальнейшие действия происходят на сервере SSH платки LuckFox под пользователем root:
# mkdir -p /root/.ssh
# touch /root/.ssh/authorized_keys
# nano /root/.ssh/authorized_keys
Вставьте текст из файла 251007luckfox.pub и сохраните файл /root/.ssh/authorized_keys. Это можно сделать с помощью текстового редактора nano или vi. Проверьте, что публичный ключ сохранился:
# cat /root/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDJdUdHXUwguO8FH0WkSPnts8fauiop
...
k6x+3hwVdJSKEmzIfGAnH6/7qsB1tPewQ8DQOFuk0NCCxUREQEfi3VXVizhvswpngrga
pa7xnuioQZsy88acuiWBfMqffZan6Vdsdq/Q== имя_пользователя@TAG-5779
3. Исправьте конфигурацию сервера SSH, чтобы там правильно был указан путь до файла authorized_keys:
# nano /etc/ssh/sshd_config
Проверьте строчку AuthorizedKeysFile, исправьте её, если она неправильная:
AuthorizedKeysFile /root/.ssh/authorized_keys
4. Проверьте права доступа и владельца на каталоги /root, /root/.ssh и файл /root/.ssh/authorized_keys с помощью команды ls -la:
# ls -la /root
# ls -la /root/.ssh
# ls -la /root/.ssh/authorized_keys
Везде владелец должен быть root:root, права доступа на каталогах /root и /root/.ssh должны быть drwx------, а на файл authorized_keys должны быть права доступа -rw-------.
Доступ | Владелец Группа | Файл или папка |
drwx------ | root root | /root |
drwx------ | root root | /root/.ssh |
-rw------- | root root | /root/.ssh/authorized_keys |
Если это не так, то исправьте командами:
# chown -R root:root /root
# chown -R root:root /root/.ssh
# chown -R root:root /root/.ssh/authorized_keys
# chmod 700 /root
# chmod 700 /root/.ssh
# chmod 600 /root/.ssh/authorized_keys
5. Перезапустите сервер ssh:
# ps | grep ssh
1349 root sshd: /usr/sbin/sshd [listener] 0 of 10-100 startups
1380 root grep ssh
# kill 1349
# /usr/sbin/sshd
После этого вы сможете подключаться к серверу SSH платки LuckFox без пароля.
[Полезные команды для диагностики]
Подсказка по опциям (только на полноценном хосте доступна команда man sshd):
$ ssh root@192.168.1.100 "sshd --help"
unknown option -- -
OpenSSH_9.3p2, OpenSSL 1.1.1v 1 Aug 2023
usage: sshd [-46DdeGiqTtV] [-C connection_spec] [-c host_cert_file]
[-E log_file] [-f config_file] [-g login_grace_time]
[-h host_key_file] [-o option] [-p port] [-u len]
Следующая команда запускает сервер SSH в режиме вывода лога отладки в консоль (опция -d), с использованием конфигурационного файла /etc/ssh/sshd_config (опция -f):
# /usr/sbin/sshd -d -f /etc/ssh/sshd_config
В частности, это помогло мне обнаружить проблему прав доступа к каталогу /root со стороны сервера sshd. Он упорно запрашивал пароль пользователя, несмотря на настроенный доступ по ключу (см. Q055).
См. также:
Q032. Как разрешить Ethernet на плате LuckFox Pico Mini
Q033. Настроить IP интерфейса Ethernet на плате LuckFox Pico Mini
Q035. Как подключиться по SSH?
Наблюдается проблема: несмотря на то, что правильно настроен доступ по паре ключей SSH (см. Q054), сервер все равно запрашивает пароль при попытке подключения.
Запуск сервера SSH в режиме отладки (опция -d) позволил понять, в чем проблема:
# ps | grep ssh
1349 root sshd: /usr/sbin/sshd [listener] 0 of 10-100 startups
1380 root grep ssh
# kill 1349
# /usr/sbin/sshd -d -f /etc/ssh/sshd_config
debug1: sshd version OpenSSH_9.3, OpenSSL 1.1.1v 1 Aug 2023
debug1: private host key #0: ssh-rsa SHA256:TUf2NU/xAfSS8UXJjyrxTkdLbIlYxBe2ZnxgXe9
debug1: private host key #1: ecdsa-sha2-nistp256 SHA256:9wWC2XW74wk5uc4OrrFVyaZAX1+
debug1: private host key #2: ssh-ed25519 SHA256:5b8Z6u5uCWhu0AhfsQTkrRwiyTtBidfSUcm
debug1: rexec_argv[0]='/usr/sbin/sshd'
debug1: rexec_argv[1]='-d'
debug1: rexec_argv[2]='-f'
debug1: rexec_argv[3]='/etc/ssh/sshd_config'
debug1: Set /proc/self/oom_score_adj from 0 to -1000
socket: Address family not supported by protocol
debug1: Bind to port 22 on 0.0.0.0.
Server listening on 0.0.0.0 port 22.
...
Попытка подключения клиента SSH:
...
debug1: rekey in after 134217728 blocks [preauth]
debug1: KEX done [preauth]
debug1: userauth-request for user root service ssh-connection method none [preauth]
debug1: attempt 0 failures 0 [preauth]
debug1: userauth-request for user root service ssh-connection method publickey [preauth]
debug1: attempt 1 failures 0 [preauth]
debug1: userauth_pubkey: publickey test pkalg ssh-ed25519 pkblob ED25519 SHA256:o2n
9di8eVNIKkVNRHUrWpD8yWsnnYhFietm7q2tgOxE [preauth]
debug1: temporarily_use_uid: 0/0 (e=0/0)
debug1: trying public key file /root/.ssh/authorized_keys
debug1: fd 4 clearing O_NONBLOCK
Authentication refused: bad ownership or modes for directory /root
debug1: restore_uid: 0/0
...
Из лога видно, что отказано в попытке доступа к файлу /root/.ssh/authorized_keys (bad ownership or modes for directory /root).
Проблему решила настройка владельца и прав доступа на каталог /root:
# chown -R root:root /root
# chmod 700 /root
Проверьте также права доступа (командой ls -la) на каталог /root/.ssh/ и файл authorized_keys:
Доступ | Владелец Группа | Файл или папка |
drwx------ | root root | /root |
drwx------ | root root | /root/.ssh |
-rw------- | root root | /root/.ssh/authorized_keys |
Перезагрузите сервер командами sync и reboot:
# sync
# reboot
Для копирования файлов на сервер по SSH существует несколько основных способов:
[1. SCP (Secure Copy)]
Утилита scp это наиболее простой и распространенный способ. Общий синтаксис копирования одного файла:
scp источник назначение
Под источником и назначением могут быть как локальный файл, так и подключение к удаленному серверу SSH:
scp localfile remoteuser@IP:/путь/на/сервере
scp remoteuser@IP:/путь/на/сервере localfile
Копирование директории рекурсивно:
scp -r localdir remoteuser@IP:/путь/на/сервере
Здесь localfile это файл, localdir директория на машине, откуда происходит копирование, remoteuser это пользователь на удаленном сервере SSH, IP это адрес сервера SSH (который может быть представлен DNS-именем), /путь/на/сервере это путь в файловой системе сервера SSH.
Пример копирования файла hello.txt на SSH-сервер платки LuckFox, которая подключена через Ethernet. IP-адрес сервера SSH 192.168.1.100:
$ touch hello.txt
$ echo "hi!" > hello.txt
$ scp hello.txt root@192.168.1.100:/oem
hello.txt 100% 4 1.9KB/s 00:00
Здесь каталог /oem это каталог на Linux Buildroot платки LuckFox, соответствующий домашнему каталогу пользователя root. Проверка, что файл успешно скопировался:
$ ssh root@192.168.1.100 "cat /oem/hello.txt"
hi!
Важное замечание: /путь/на/сервере должен быть абсолютным, т. е. нельзя использовать относительные пути и пути, содержащие ~. Иначе это может привести к путанице.
[2. SFTP (SSH File Transfer Protocol)]
С помощью sftp можно организовать интерактивную работу с файловой системой SSH-сервера. Общий синтаксис показан ниже.
Подключение к серверу:
sftp remoteuser@IP
Команды в SFTP:
put локальный_файл # Загрузить файл
get удаленный_файл # Скачать файл
ls # Просмотр файлов
cd папка # Смена директории
[3. Rsync через SSH]
Утилиту rsync часто используют для синхронизации файлов и директорий на сетевых хостах. Например, для зеркалирования каталогов web-сервера на другой web-сервер. При этом копируются только измененные или новые файлы [5]. Ниже показан общий синтаксис использования утилиты rsync.
Синхронизация с прогрессом:
rsync -avz -e ssh localdir/ remoteuser@IP:/remotedir/
Синхронизация с удалением лишних файлов на сервере:
rsync -avz --delete -e ssh localdir/ remoteuser@IP:/remotedir/
[Параметры аутентификации scp]
С паролем, будет запрошен пароль, если не настроена аутентификация по ключу (см. Q054):
scp localfile remoteuser@IP:/путь/на/сервере
С SSH-ключом, использование конкретного ключа:
scp -i ~/.ssh/ключ localfile remoteuser@IP:/путь/на/сервере
[Дополнительные опции scp]
Указание порта подключения(нестандартного):
scp -P 2222 localfile remoteuser@IP:/путь/на/сервере
Сжатие данных при передаче:
scp -C localfile remoteuser@IP:/путь/на/сервере
Сохранение атрибутов файлов:
scp -p localfile remoteuser@IP:/путь/на/сервере
Ограничение скорости передачи 1000 килобит/сек:
scp -l 1000 localfile remoteuser@IP:/путь/на/сервере
Практические примеры. Копирование веб-сайта:
$ scp -r /var/www/mysite/* user@webserver:/var/www/html/
Копирование с прогрессом (rsync):
$ rsync -avz --progress -e ssh backup.tar.gz user@server:/backups/
Копирование через нестандартный порт SSH, с использованием конфигурационного файла config.conf для SSH (напрямую передается в утилиту ssh):
$ scp -P 2022 -F config.conf admin@server:/etc/app/
Советы:
- Используйте SSH-ключи для автоматизации.
- Rsync предпочтительнее для больших файлов/директорий.
- Для частого использования настройте конфигурационный файл для ssh.
Для остановки процесса по имени с помощью kill есть несколько способов:
[С помощью скрипта]
Создайте вот такой скрипт (например, k.sh):
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Использование: $0 < имя_процесса>"
exit 1
fi
PIDS=$(pgrep "$1")
if [ -z "$PIDS" ]; then
echo "Процесс '$1' не найден"
exit 1
fi
echo "Останавливаем процессы: $PIDS"
kill $PIDS 2>/dev/null
# Принудительное завершение, если процессы не отвечают sleep 2
REMAINING=$(pgrep "$1")
if [ -n "$REMAINING" ]; then
echo "Принудительно завершаем: $REMAINING"
kill -9 $REMAINING 2>/dev/null
fi
echo "Готово"
Пример использования:
$ gedit &
[1] 277402
$ ./k.sh gedit
Останавливаем процессы: 277402
Готово
[1]+ Terminated gedit
[killall]
Остановить все процессы с указанным именем:
killall process_name
Принудительная остановка:
killall -9 process_name
Примеры:
$ killall nginx
$ killall -9 python
Пример запуска и остановки видеопотока MPEG с помощью утилиты v4l2-ctl:
$ v4l2-ctl -d0 --stream-mmap --stream-to=- | socat - udp-sendto:192.168.1.1:5000 &
[1] 277805
$ ps | grep v4l2-ctl
277804 pts/1 00:00:00 v4l2-ctl
$ killall v4l2-ctl
$ ps | grep v4l2-ctl
[1]+ Stopped v4l2-ctl -d0 --stream-mmap --stream-to=- | socat - udp-sendto:192.168.1.1:5000
[pkill (самый простой способ)]
Этот способ не подойдет для Linux Buildroot, поскольку по умолчанию в сборке Buildroot нет утилиты pkill.
Остановить процесс по имени (отправляет SIGTERM):
pkill process_name
Принудительная остановка (SIGKILL):
pkill -9 process_name
Примеры использования:
$ pkill firefox
$ pkill -9 chrome
[Комбинация pgrep + kill]
Этот способ не подойдет для Linux Buildroot, поскольку по умолчанию в сборке Buildroot нет утилиты pgrep.
Найти PID и остановить:
kill $(pgrep process_name)
Или с принудительным завершением:
kill -9 $(pgrep process_name)
Пример:
$ kill $(pgrep firefox)
Безопасный способ с проверками (скрипт):
# Проверка существования процесса перед остановкой
PROCESS="firefox"
PID=$(pgrep "$PROCESS")
if [ -n "$PID" ]; then
echo "Останавливаем процесс $PROCESS (PID: $PID)"
kill $PID
else
echo "Процесс $PROCESS не найден"
fi
Для нескольких процессов с одним именем (скрипт):
# Остановить все процессы с указанным именем
PROCESS="python"
PIDS=$(pgrep "$PROCESS")
if [ -n "$PIDS" ]; then
echo "Найдены процессы: $PIDS"
kill $PIDS
else
echo "Процессы $PROCESS не найдены"
fi
Постепенное завершение (скрипт):
# Сначала вежливая остановка, затем принудительная
PROCESS="myapp"
PID=$(pgrep "$PROCESS")
if [ -n "$PID" ]; then
echo "Отправляем SIGTERM процессу $PID"
kill $PID
# Ждем 5 секунд
sleep 5
# Проверяем, жив ли еще процесс
if kill -0 $PID 2>/dev/null; then
echo "Процесс не ответил, отправляем SIGKILL"
kill -9 $PID
fi
fi
[Универсальная функция для .bashrc]
Добавьте в ~/.bashrc:
killp() {
if [ $# -eq 0 ]; then
echo "Использование: killp < имя_процесса>"
return 1
fi
local PIDS=$(pgrep "$1")
if [ -z "$PIDS" ]; then
echo "Процесс '$1' не найден"
return 1
fi
echo "Останавливаем процессы '$1': $PIDS"
kill $PIDS
}
После добавления в .bashrc:
$ source ~/.bashrc
$ killp firefox # Использование функции
[Сигналы для kill]
Вежливое завершение (по умолчанию):
kill -TERM $(pgrep process_name)
Принудительное завершение:
kill -KILL $(pgrep process_name)
Перезапуск процесса:
kill -HUP $(pgrep process_name)
[Практические примеры]
Остановить веб-сервер nginx:
$ sudo pkill nginx
Остановить все Python скрипты:
$ pkill python
Остановить процесс с подтверждением:
$ read -p "Остановить Firefox? (y/n): " ans
[[ $ans == "y" ]] && pkill firefox
Остановить процесс, если он использует много памяти:
if ps aux | grep firefox | grep -v grep | awk '{if ($4 > 50) print $2}' | xargs kill; then
echo "Процессы Firefox с >50% памяти остановлены"
fi
Рекомендации:
- Используйте pkill для простых случаев.
- Используйте pgrep + kill когда нужен больший контроль.
- Сначала пробуйте SIGTERM, и только потом SIGKILL.
- Будьте осторожны с sudo и системными процессами.
Для сохранения кадра в формате BMP с помощью v4l2-ctl есть несколько способов:
[1. Прямое сохранение в BMP через --stream-to]
Сохранение одного кадра:
v4l2-ctl -d0 --stream-mmap --stream-to=frame.bmp --stream-count=1
В этом примере кадр сохраняется как растровая картинка в формате MJPEG.
[2. Сохранение RAW данных и конвертация]
Сохраняем RAW данные (YUV или MJPEG):
v4l2-ctl -d0 --set-fmt-video=width=1920,height=1080,pixelformat=YUYV
v4l2-ctl -d0 --stream-mmap --stream-to=frame.raw --stream-count=1
Затем конвертируем в BMP (требуются дополнительные утилиты). Использование ffmpeg для конвертации:
ffmpeg -f rawvideo -pixel_format yuyv422 -video_size 640x480 -i frame.raw frame.bmp
[Полный скрипт для сохранения BMP]
#!/bin/bash
# Параметры по умолчанию
DEVICE="${1:-0}"
WIDTH="${2:-640}"
HEIGHT="${3:-480}"
PIXELFORMAT="${4:-YUYV}"
OUTPUT="${5:-frame.bmp}"
echo "Захват кадра с /dev/video$DEVICE..."
echo "Разрешение: ${WIDTH}x${HEIGHT}"
echo "Формат: $PIXELFORMAT"
# Устанавливаем формат v4l2-ctl -d$DEVICE --set-fmt-video=width=$WIDTH,height=$HEIGHT,pixelformat=$PIXELFORMAT
# Сохраняем RAW данные
RAW_FILE="${OUTPUT%.*}.raw" v4l2-ctl -d$DEVICE --stream-mmap --stream-to="$RAW_FILE" --stream-count=1
# Конвертируем в BMP используя ffmpeg
if command -v ffmpeg &> /dev/null; then
case $PIXELFORMAT in
YUYV|YUYV422)
ffmpeg -f rawvideo -pixel_format yuyv422 -video_size ${WIDTH}x${HEIGHT} \
-i "$RAW_FILE" "$OUTPUT" -y
;;
MJPG)
ffmpeg -f mjpeg -i "$RAW_FILE" "$OUTPUT" -y
;;
RGB24)
ffmpeg -f rawvideo -pixel_format rgb24 -video_size ${WIDTH}x${HEIGHT} \
-i "$RAW_FILE" "$OUTPUT" -y
;;
*)
echo "Формат $PIXELFORMAT не поддерживается для автоматической конвертации"
echo "RAW данные сохранены в: $RAW_FILE"
exit 1
;;
esac
# Удаляем временный RAW файл
rm "$RAW_FILE"
echo "Кадр сохранен как: $OUTPUT"
else
echo "ffmpeg не найден. RAW данные сохранены в: $RAW_FILE"
echo "Установите ffmpeg для конвертации в BMP: sudo apt install ffmpeg"
fi
[Скрипт с определением доступных форматов]
#!/bin/bash
capture_bmp() {
local device="${1:-0}"
local output="${2:-frame_$(date +%Y%m%d_%H%M%S).bmp}"
# Получаем информацию о поддерживаемых форматах
echo "=== Проверка поддерживаемых форматов ==="
v4l2-ctl -d$device --list-formats-ext
# Запрашиваем параметры у пользователя
read -p "Ширина кадра [640]: " width
width=${width:-640}
read -p "Высота кадра [480]: " height
height=${height:-480}
read -p "Формат пикселей [YUYV]: " pixelformat
pixelformat=${pixelformat:-YUYV}
# Устанавливаем формат
echo "Установка формата: ${width}x${height} $pixelformat"
v4l2-ctl -d$device --set-fmt-video=width=$width,height=$height,pixelformat=$pixelformat
# Захватываем кадр
echo "Захват кадра..."
temp_raw=$(mktemp)
v4l2-ctl -d$device --stream-mmap --stream-to="$temp_raw" --stream-count=1
# Конвертируем в BMP
if command -v ffmpeg &> /dev/null; then
echo "Конвертация в BMP..."
ffmpeg -f rawvideo -pixel_format yuyv422 -video_size ${width}x${height} \
-i "$temp_raw" "$output" -y -loglevel quiet
rm "$temp_raw"
echo "✅ Кадр сохранен: $output"
else
mv "$temp_raw" "${output%.*}.raw"
echo "⚠️ ffmpeg не найден. RAW данные сохранены: ${output%.*}.raw"
fi
}
Использование:
capture_bmp "$@"
[Простая однострочная команда с конвертацией]
Однострочная команда для быстрого сохранения BMP:
v4l2-ctl -d0 --set-fmt-video=width=640,height=480,pixelformat=YUYV --stream-mmap \
--stream-to=/tmp/frame.raw --stream-count=1 && ffmpeg -f rawvideo -pixel_format \
yuyv422 -video_size 640x480 -i /tmp/frame.raw frame.bmp -y && rm /tmp/frame.raw
[Скрипт для периодического сохранения кадров]
#!/bin/bash
# Параметры
DEVICE=0
INTERVAL=5 # секунд между кадрами
COUNT=10 # количество кадров
for i in $(seq 1 $COUNT); do
output="frame_$(printf "%03d" $i)_$(date +%H%M%S).bmp"
echo "Захват кадра $i/$COUNT: $output"
v4l2-ctl -d$DEVICE --stream-mmap --stream-to=/tmp/temp.raw --stream-count=1
ffmpeg -f rawvideo -pixel_format yuyv422 -video_size 640x480 \
-i /tmp/temp.raw "$output" -y -loglevel quiet
rm /tmp/temp.raw
sleep $INTERVAL
done
Как использовать:
1. Сохраните скрипт как capture_bmp.sh.
2. Сделайте исполняемым: chmod +x capture_bmp.sh.
3. Запустите:
$ ./capture_bmp.sh # Использовать значения по умолчанию
$ ./capture_bmp.sh 0 frame1.bmp # Указать устройство и имя файла
Примечания:
- v4l2-ctl сам по себе не умеет сохранять прямо в BMP, только RAW данные
- ffmpeg требуется для конвертации RAW в BMP
- Формат YUYV наиболее распространен для веб-камер
- Для MJPEG камер используйте `pixelformat=MJPG`
Самый простой способ - использовать "3. Полный скрипт для сохранения BMP", который автоматически выполнит все необходимые шаги.
Утилита v4l2-ctl работает на хосте с IP-адресом 192.168.1.100, и передает видеопоток от аналоговой камеры на хост с IP-адресом 192.168.1.1.
[Через UDP]
На передающей стороне:
v4l2-ctl -d0 --stream-mmap --stream-to=- | socat - udp-sendto:192.168.1.1:5000
На принимающей стороне видеопоток можно просмотреть командой:
ffplay -f mjpeg udp://192.168.1.100:5000
Проблема в том, что наблюдается большая задержка между событиями реального времени перед камерой и их появлением на принимающей стороне. Задержка может быть случайная, визуально от 0.2 до 3 секунд. При этом видно, что проигрывание картинки ffplay как раз происходит с этой задержкой.
Причина проблемы заключалась в буферах UDP на стороне приема. Минимизировать эту задержку и сделать её постоянной можно с помощью следующей команды на стороне приема:
ffplay -f mjpeg -fflags nobuffer -flags low_delay -framedrop -analyzeduration 1 \
-probesize 32 -buffer_size 16384 udp://192.168.1.100:5000
[Через TCP]
На передающей стороне:
v4l2-ctl -d0 --stream-mmap --stream-to-host 192.168.1.1:5000
На принимающей стороне:
ffplay -f mjpeg -fflags nobuffer -flags low_delay -framedrop -analyzeduration 1 \
-probesize 32 tcp://0.0.0.0:5000?listen
[Ссылки]
1. SDK Environment Deployment(on the PC) site:wiki.luckfox.com.
2. Ubuntu FAQ.
3. Запускаем Yolo на пятирублёвой монете или Luckfox Pico Mini site:habr.com.
4. man adb.
5. rsync: синтаксис, примеры использования.