Yocto boot2qt para el reTerminal Seeed (Qt 6)

 C Programming >> Programación C >  >> Tags >> Qt
Yocto boot2qt para el reTerminal Seeed (Qt 6)

En esta guía, construiremos una distribución de Linux para Seeed reTerminal, usando el proyecto Yocto y el boot2qt pila proporcionada por Qt. Este boot2qt La imagen se puede escribir en el eMMC interno y, cuando se inicia, Seeed reTerminal ejecuta una pila de software que se integra muy bien con Qt Creator (Qt IDE), por ejemplo, implementación con un solo clic en el dispositivo. Puede ejecutar su propia aplicación Qt en el reTerminal, pantalla completa, se iniciará directamente en él. Esta guía cubre Qt 6.2. La guía también cubre el cambio de la aplicación de inicio predeterminada a su propia aplicación, la integración de Qt Creator y la rotación de su aplicación Qt, tanto Widgets como QML, este último a través de Wayland y Weston.

La principal diferencia entre la guía que proporciona Seeed y esta guía es que esta guía utiliza la propia pila boot2qt Yocto de Qt y ejecuta Qt 6. Seeedguide cubre su propia imagen y Qt 5. Esta guía también le muestra cómo hacer que su propia aplicación Qt sea la predeterminada y te ayuda con la rotación.

Ejecutar su propia distribución de Yocto sobre la imagen predeterminada de Debian provista por Seeed tiene la ventaja de que es reproducible y usted tiene el control total. Usando el boot2qt La pila de Yocto hace que el proceso de configuración de Yocto sea mucho más fácil y rápido. Al usar su propia imagen, ninguna otra aplicación se ejecuta en el dispositivo, por lo que todos los recursos están disponibles para su aplicación. (Ningún entorno de escritorio u otro software, a menos que lo construya en la imagen). Esto también le asegura que en el futuro, digamos como ejemplo, 5 años después, aún puede construir su imagen y software, ya que su servidor de construcción Yocto tiene todas las fuentes localmente.

Divulgación completa:Fui contactado por Seeed, me enviaron este reTerminal a cambio de algunos artículos, siendo este el primero. No se trata de ningún pago monetario y Seeed no ha revisado este artículo antes de publicarlo. Para obtener asistencia oficial, visite la wiki de Seeed.

Seeed en realidad me envió 2 unidades reTerminal. El primero tenía un interruptor de modo de arranque atascado. No se movía, y luego se rompió. Se requiere el interruptor de modo de arranque para mostrar una imagen, lo cual es bastante esencial para esta guía de Yocto. Me puse en contacto con ellos y me enviaron una unidad de reemplazo rápidamente. Por lo tanto, tenga cuidado con su interruptor de modo de arranque. Ahora uso un par de pinzas para cambiarlo, solo para ser más cauteloso.

Registro de cambios del artículo:

  • 04-04-2022:rutas fijas en los comandos de shell
  • 04-04-2022:se corrigió la sintaxis en algunos archivos de recetas, incluidas las barras inclinadas que faltan
  • 04-04-2022:Nota agregada sobre el seeed-linux-dtoverlays al confirmar 7c846e23de9346d318fbdc8ac92dcc72b90fb6ce
  • ¡Gracias a Ryan Bryngelson por los problemas y correcciones anteriores!

¿Qué es el reTerminal

El reTerminal se comercializa como una interfaz hombre-máquina (HMI) preparada para el futuro. El reTerminal funciona con un Raspberry Pi Compute Module 4 (cm4) que es una CPU Quad-Core ARM Cortex-A72 que funciona a 1,5 GHz y una pantalla multitáctil capacitiva IPS de 5 pulgadas con una resolución de 1280x720. 4 GB de RAM y 32 GB de almacenamiento eMMC integrados (no ampliables). Tiene conectividad inalámbrica con Wi-Fi de doble banda de 2,4 GHz/5 GHz y Bluetooth 5.0 BLE.

El reTerminal tiene una interfaz de expansión de alta velocidad y expone muchos puertos y conectores de E/S. El dispositivo tiene funciones de seguridad como un coprocesador criptográfico con almacenamiento seguro de claves basado en hardware. También tiene módulos integrados como un acelerómetro, un sensor de luz y un reloj en tiempo real. La terminal tiene un puerto Gigabit Ethernet para conexiones de red más rápidas y también tiene dos puertos USB 2.0 tipo A. El encabezado GPIO compatible con Raspberry Pi de 40 pines permite que la mayoría o todos los proyectos existentes funcionen con el reTerminal.

Puedes comprar el reTerminal aquí, el precio actual es de USD 195. Eso incluye un módulo de cómputo 4.

Se podría decir sin rodeos que el reTerminal es una placa de soporte para el módulo de cómputo 4 con una pantalla multitáctil y un estuche conveniente. En mi opinión, es mucho más que eso.

Carece de una batería incorporada al momento de escribir este artículo. Lo alimenta a través de un cable USB-C o suministrando 5 V y conexión a tierra a los pines GPIO correctos.

Detrás de una pequeña almohadilla de cubierta hay una interfaz de alta velocidad, en la imagen de arriba está etiquetada como Industrial High Speed Interface . En las preguntas frecuentes escriben lo siguiente:

Entonces, en cuanto al hardware, el reTerminal es sólido y está preparado para el futuro. Si compra uno, viene precargado con un módulo de cómputo y Raspbian, incluidos los controladores y una aplicación de demostración, para que pueda comenzar de inmediato. Aquí no hay problemas complicados con la cadena de suministro, solo un poco de espera para enviar un paquete desde China.

Qué es Yocto

Hay mucho terreno por cubrir, si no está familiarizado con el proyecto Yocto, aquí hay una forma rápida y simplificada , resumen de todos los términos.

Seeed tiene sus propias preguntas frecuentes sobre Yocto para el reTerminal aquí . Esas preguntas frecuentes cubren los conceptos básicos y tienen consejos y trucos para usar Yocto. Le recomiendo que lea esa guía también, ya que explica diferentes partes. Mi guía está diseñada para (arranque 2) Qt en el reTerminal.

Yocto es un proyecto de código abierto que proporciona un marco de construcción y metadatos para ayudar a crear una imagen personalizada para su tablero de destino. Yocto utiliza las llamadas (meta) capas y recetas. Las recetas son .bb (para bitbake) los archivos que contienen instrucciones de construcción y capas son una colección de recetas, clases y archivos de configuración específicos. Podrías tener una capa llamada meta-raspberry (todas las capas, por convención, comienzan con meta- ) que tiene recetas aplicables solo para Raspberry Pi.

Yocto te ayuda a construir una distribución de Linux, su distribución de referencia se llama poky . La herramienta de compilación principal es una herramienta de línea de comandos de Python llamada bitbake .Analiza todas las recetas y luego, una por una, reúne el código fuente y compila todo el software, luego lo empaqueta en una imagen para su tablero.

Yocto está dirigido a dispositivos linux integrados, en el trabajo lo usamos para crear nuestra propia distribución de Linux (no boot2qt ) para funcionar en las máquinas de café. Se admiten muchas placas diferentes, la mayoría de los proveedores proporcionan el llamado paquete de soporte de placa (bsp). A menudo, esto contiene un núcleo y controladores para su placa. Hay un paquete de soporte de placa para Raspberry Pi, que usaremos.

boot2qt es un conjunto de capas para Yocto que crea un sistema Linux simple que se inicia sin un escritorio, directamente en una aplicación Qt. También crea un SDK de compilación cruzada para su escritorio, que puede usar en Qt Creator para compilar de forma cruzada su aplicación para el dispositivo de destino. A menudo, el dispositivo para el que desarrolla no tiene la misma arquitectura de CPU que su estación de trabajo de escritorio. Para complementar todo esto, también se integra en Qt Creator, lo que le permite implementar y ejecutar su aplicación con un solo clic, a través de la red, en su dispositivo.

boot2qt también proporciona un conjunto de scripts para hacer el yocto la configuración es muy fácil, por lo que el proceso que ve en esta guía no es el mismo que un yocto predeterminado configuración. Es específicamente para boot2qt y para el reTerminal.

Para resumir, boot2qt proporciona una capa en la parte superior de yocto que agrega integración entre su dispositivo Linux integrado y el conjunto de herramientas Qt, ahorrando una gran cantidad de tiempo en el trabajo manual.

Configuración del host de desarrollo Yocto

La máquina que va a construir tu boot2qt image (el host que ejecuta bitbake ) necesita algunos paquetes antes de que podamos comenzar a construir. Necesita al menos 50 GB de espacio libre, pero mi host tiene 300 GB. La compilación cruzada de todos los paquetes requiere una gran cantidad de tiempo, por lo que cuantos más núcleos y RAM tenga, mejor. Mi máquina de compilación de prueba tiene 4 núcleos y 8 GB de RAM, la compilación de la imagen completa tomó más de 2 días. En el trabajo, tenemos algunos servidores robustos, allí la compilación demora aproximadamente 2 horas. Yocto admite compilaciones incrementales, por lo que si cambia una receta, solo se debe reconstruir esa parte, no todas las demás.

Mi máquina de compilación ejecuta Debian 11, pero también se sabe que Ubuntu 20.04 funciona. Instale primero los paquetes necesarios:

apt-get install gawk wget git diffstat unzip texinfo gcc build-essential
chrpath socat cpio python3 python3-pip python3-pexpect xz-utils
debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa
libsdl1.2-dev pylint3 xterm python3-subunit mesa-common-dev python
git-lfs g++-multilib gcc-multilib libxkbcommon-dev
libxkbcommon-x11-dev libwayland-cursor++0 libwayland-cursor0

Estos son un poco más paquetes de los que recomienda el sitio de Qt, tuve problemas de compilación al compilar el qbsp capa, que es de donde provienen la mayoría de los paquetes adicionales.

Repositorio de Google

A continuación, necesita repo , una herramienta de gestión de git de Google. Oculta la mayor parte de la complejidad de los submódulos y diferentes repositorios al colocar toda esa información adicional en un archivo de manifiesto. Puedes instalarlo usando apt:

apt install repo

Si no está en el repositorio, consulte las instrucciones, el proceso de instalación es solo una copia simple de un ejecutable.

Configuración inicial de boot2qt

Cree una carpeta donde residirá todo yocto:

mkdir b2qt
cd b2qt

Utilice el repo herramienta para clonar todos los repositorios git del proyecto Yocto y boot2qt En seguida. Primero inicialice para la versión correcta de Qt:

# for Qt 6.2:
repo init -u git://code.qt.io/yocto/boot2qt-manifest -m v6.2.3.xml

Luego sincroniza los repositorios:

repo sync

Debe indicar para qué placa desea crear y luego obtener el script de origen:

export MACHINE=raspberrypi4-64 && source ./setup-environment.sh 

Este paso debe repetirse en cada inicio de sesión .

Note que especificamos raspberrypi-64 . Esto se debe a que el reTerminal usa un módulo de cómputo 4 de Raspberry Pi. El meta-raspberry capa usa ese nombre tanto para el Pi 4 normal como para el módulo Compute. La capa Yocto de Seeed tiene una placa específica para el reTerminal desde hace 3 días (al momento de escribir este artículo), pero boot2qt no tiene soporte para eso, por lo que en esta guía transferiremos los requisitos específicos a nuestra imagen de compilación.

Salida:

### Shell environment set up for builds. ###

You can now run 'bitbake <target>'

Common targets are:
b2qt-embedded-qt6-image
meta-toolchain-b2qt-embedded-qt6-sdk

QBSP target is:
meta-b2qt-embedded-qbsp

For creating toolchain or QBSP for Windows, set environment variable before running bitbake:
SDKMACHINE=x86_64-mingw32

For more information about Boot to Qt, see https://doc.qt.io/QtForDeviceCreation/

Ahora debería estar en una carpeta llamada build-raspberrypi4-64 . Usando el repo herramienta y obtener este script ha creado una estructura de carpetas ingeniosa para yocto:

  • build-raspberrypi4-64 :directorio de compilación para la placa, se encuentra en esta carpeta después de obtener el setup-environment.sh archivo.
  • sources :tiene todos los bitbake capas y recetas
  • download :carpeta donde se descarga todo el código fuente (git repo's, archivos tar.gz)

En el build-* directorio hay un conf carpeta, que tiene dos archivos importantes. bblayers.conf y local.conf . El primero define las capas que usa su compilación y el segundo tiene opciones de configuración específicas para esta compilación específica. Comenzaremos agregando la capa reTerminal, el archivo de configuración se trata más adelante.

Añadiendo la capa reTerminal de Seeed

Necesitamos la capa reTerminal para el árbol de dispositivos y algunos controladores.

cd ../sources
git clone -b main https://github.com/Seeed-Studio/meta-seeed-reterminal.git

He probado esta guía con commit 7c846e23de9346d318fbdc8ac92dcc72b90fb6ce y con confirmación 57d1b68d73e625fe6a4cb14372a0cb7c42bae9c5 . Si el seeed-linux-dtoverlays el paquete da un error del enlazador como el siguiente:

| aarch64-poky-linux-ld: internal error in set_address, at ../../gold/output.h:322

Luego, elimina el ld-is-gold opción que el boot2qt distro.conf archivo habilitado, como lo hacemos en nuestra configuración local más adelante:

DISTRO_FEATURES_remove = "ld-is-gold"

He hecho un informe de errores aguas arriba para ello. Si usa cometer 7c846e23de9346d318fbdc8ac92dcc72b90fb6ce , el error no aparecerá.

Debes agregar la versión de Yocto que boot2qt utiliza para la configuración de la capa. Edite el siguiente archivo:

vi meta-seeed-reterminal/conf/layer.conf

Agregar hardknott al LAYERSERIES_COMPAT línea:

LAYERSERIES_COMPAT_meta-reterminal = "honister hardknott"

Guardar y cerrar. Cambie a nuestra carpeta de compilación:

cd ../build-raspberrypi4-64

Agregue la capa a nuestra configuración:

bitbake-layers add-layer ../sources/meta-seeed-reterminal

Hacer nuestra propia capa para anular imágenes de b2qt

Para anular algunas partes del b2qt-embedded-qt6-image predeterminado , debemos hacer nuestra propia capa. Esta capa incluirá más personalización más adelante, pero para la compilación inicial, solo anularemos partes de la imagen. ¿Por qué no sobrescribimos simplemente el contenido del archivo original? Usando un .bbappend archivo, podemos mantener nuestros cambios separados, para saber más adelante cuáles son nuestros cambios específicos. También facilita la aplicación de cambios ascendentes.

Comience creando algunas carpetas para su capa, en el b2qt carpeta:

mkdir -p sources/meta-raymii/conf/
mkdir -p sources/meta-raymii/recipes-qt/images/

Edite el siguiente archivo:

sources/meta-raymii/conf/layer.conf

Coloque los siguientes contenidos:

BBPATH .= ":${LAYERDIR}"

BBFILES += "${LAYERDIR}/recipes*/*/*.bb \
            ${LAYERDIR}/recipes*/*/*.bbappend \
            "
BBFILE_COLLECTIONS += "raymii"
BBFILE_PATTERN_raymii := "^${LAYERDIR}/"
BBFILE_PRIORITY_raymii = "1"

LAYERSERIES_COMPAT_raymii = "thud zeus dunfell gatesgarth hardknott"

Agregue nuestra capa a la compilación de Yocto para el reTerminal:

cd build-raspberrypi4-64
bitbake-layers add-layer ../sources/meta-raymii

Ahora pasemos a los cambios en el boot2qt predeterminado. imagen. El siguiente archivo es un .bbappend que, si tiene el mismo nombre, ruta y versión, como es de esperar, agregará cosas al original. En este caso, extenderemos el b2qt-embedded-qt6-image predeterminado imagen para incluir nuestro myapp receta en la instalación. Edite este archivo:

vi sources/meta-raymii/recipes-qt/images/b2qt-embedded-qt6-image.bbappend

Agrega lo siguiente:

SUMMARY = "reTerminal changes for Qt image"

SPLASH = "psplash-raspberrypi"

IMAGE_FEATURES_append = " \
        splash \
        "

IMAGE_INSTALL_append = " \
        kernel-modules \
        evtest \
        iperf3 \
        i2c-tools \
        util-linux \
        "

Los cambios, como puedes ver, están relacionados con la imagen de reTerminal. Más adelante agregaremos nuestra aplicación aquí, pero por ahora esto es solo lo esencial para crear una imagen de arranque.

Ajustando nuestro local.conf para el reTerminal

Necesitamos agregar algunas variables al archivo de configuración local (conf/local.conf ). Todos estos tienen que ver con el hardware de reTerminal, excepto uno, la eliminación de webengine . Si su aplicación Qt usa webengine, déjelo, de lo contrario, elimínelo. No incluirlo le ahorra un montón de tiempo de compilación y la imagen es más pequeña.

Las funciones relacionadas con reTerminal se extraen de la capa oficial, pero se modifican para boot2qt . Puede ver el backport aquí, una adición bastante reciente a la capa reTerminal Yocto, hace 3 días al escribir este artículo.

La diferencia entre local.conf y el b2qt-embedded-qt6-image.bbappend es que local.conf es solo para este dispositivo. En mi caso también tengo un raspberrypi4 carpeta machinebuild para el módulo de cómputo 4. También puede crear su propio distro.conf o defina un nuevo dispositivo con anulaciones específicas de la máquina, pero para este artículo, local.conf es bastante simple.

Edite el siguiente archivo:

# in the folder: build-raspberrypi4-64   
vi conf/local.conf

Agrega lo siguiente:

RPI_KERNEL_DEVICETREE_OVERLAYS_append = " overlays/reTerminal.dtbo overlays/i2c3.dtbo overlays/vc4-kms-v3d-pi4.dtbo"
ENABLE_UART = "1"
ENABLE_I2C = "1"

KERNEL_MODULE_AUTOLOAD_rpi += "i2c-dev"

MACHINE_EXTRA_RRECOMMENDS += "\
    seeed-linux-dtoverlays \
"

VC4DTBO ?= "vc4-kms-v3d"

PACKAGECONFIG_append_pn-qtbase = " eglfs "

DISTRO_FEATURES_remove = "webengine ld-is-gold"

PREFERRED_VERSION_linux-raspberrypi ?= "5.10.%" 

Ya está todo listo para la compilación inicial de boot2qt . Te recomiendo que empieces un screen o tmux sesión ya que la compilación llevará mucho tiempo. Mi compilación inicial en el hardware descrito anteriormente tomó más de 2 días.

Si usa cometer 7c846e23de9346d318fbdc8ac92dcc72b90fb6ce , no necesita agregar el MACHINE_EXTRA_RRECOMMENDS += "seeed-linux-dtoverlays" . Las superposiciones del árbol de dispositivos son un parche en esa confirmación, más tarde se convirtieron en un submódulo de git.

Bitbaking de la imagen

Con boot2qt y la configuración de la capa de hardware reTerminal, podemos hacer nuestra compilación inicial.

Asegúrate de tener source -ed el script y están en la carpeta correcta:

cd ~/b2qt
export MACHINE=raspberrypi4-64 && source ./setup-environment.sh 

Inicie la construcción de la imagen:

bitbake b2qt-embedded-qt6-image

La salida variará. Primero enumera todas sus capas y configuraciones, en la parte inferior muestra la tarea actual. Salida de ejemplo:

WARNING: Host distribution "debian-11" has not been validated with this version of the build system; you may possibly experience unexpected failures. It is recommended that you use a tested distribution.
Loading cache: 100% |################################################################################################| Time: 0:00:00
Loaded 4374 entries from dependency cache.
Parsing recipes: 100% |##############################################################################################| Time: 0:00:00
Parsing of 2813 .bb files complete (2809 cached, 4 parsed). 4377 targets, 611 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.50.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "raspberrypi4-64"
DISTRO               = "b2qt"
DISTRO_VERSION       = "3.3.4"
TUNE_FEATURES        = "aarch64 armv8a crc crypto cortexa72"
TARGET_FPU           = ""
SDKMACHINE           = "x86_64"
meta
meta-poky            = "HEAD:c40ac16d79026169639f47be76a3f7b9d8b5178e"
meta-raspberrypi     = "HEAD:b4ec97e4eb8e36efd1f7e2f8ae020a9e55cfc239"
meta-oe
meta-python
meta-networking
meta-initramfs
meta-multimedia      = "HEAD:f72a73b42fa740130b388ba8555cdbefdee8d37d"
meta-python2         = "HEAD:810d6d842f103eb59f18b06426106462b15de7e2"
meta-boot2qt
meta-boot2qt-distro  = "HEAD:e59a2e20697e0afc2a0b068835cd90e102dec589"
meta-mingw           = "HEAD:422b96cb2b6116442be1f40dfb5bd77447d1219e"
meta-qt6             = "HEAD:eb3719266fc03b96d5056980b135b371f31811f4"
meta-seeed-reterminal = "main:57d1b68d73e625fe6a4cb14372a0cb7c42bae9c5"
meta-raymii          = "master:84123f093be34a9a4d73de545132cffc3e210c19"

Initialising tasks: 100% |###########################################################################################| Time: 0:00:10
Sstate summary: Wanted 1706 Local 49 Network 0 Missed 1657 Current 1441 (2% match, 47% complete)
Removing 375 stale sstate objects for arch raspberrypi4_64: 100% |#################################################| Time: 0:00:02
Removing 6 stale sstate objects for arch allarch: 100% |###########################################################| Time: 0:00:00
Removing 956 stale sstate objects for arch cortexa72: 100% |#######################################################| Time: 0:00:02
NOTE: Executing Tasks
Currently  8 running tasks (2488 of 9043)  27% |######################                                                           |
0: libunistring-0.9.10-r0 do_configure - 27s (pid 1946515)
1: libpciaccess-0.16-r0 do_configure - 22s (pid 1949317)
2: icu-68.2-r0 do_compile - 15s (pid 1959678)
3: libpam-1.5.1-r0 do_compile - 15s (pid 1959794)
4: tslib-1.22-r0 do_configure - 13s (pid 1961800)
5: nettle-3.7.3-r0 do_configure - 10s (pid 1963210)
6: libpcre2-10.36-r0 do_configure - 8s (pid 1963889)
7: libogg-1.3.4-r0 do_configure - 5s (pid 1964770)

Ahora es un buen momento para ir a hacer otra cosa y volver en unos días. Si tiene una máquina robusta, la compilación será más rápida, pero aún llevará un tiempo.

Una vez finalizada la construcción, la imagen se encuentra en la carpeta:

build-raspberrypi4-64/tmp/deploy/images/raspberrypi4-64/

La imagen es un bmap expediente. bmap es un formato especial que debería ser más rápido para flashear y verifica los datos durante flash, creado inicialmente por Intel para su proyecto Tizen. Si ejecuta Ubuntu, debe instalar el bmap-tools paquete.

Parpadeo de la imagen

Debido a que el reTerminal tiene un Compute Module 4 con eMMC, la ranura para tarjeta SD no funcionará. Debe actualizar la imagen al eMMC, utilizando una herramienta proporcionada por Raspberry Pi. Esta herramienta se llama rpiboot , que debe construir usted mismo. Comience instalando una dependencia:

sudo apt install git libusb-1.0-0-dev

A continuación, clone el repositorio

git clone --depth=1 https://github.com/raspberrypi/usbboot
cd usbboot

Inicie el proceso de compilación:

make

Los pasos anteriores son una sola vez. Ahora tienes el rpiboot herramienta en esta carpeta. Cada vez que muestra una imagen, debe repetir el siguiente proceso.

Activa el interruptor de modo de arranque. Tenga mucho cuidado, mi primera unidad tenía un interruptor de modo de arranque atascado. Uso un par de pinzas para accionar con cuidado el pequeño interruptor.

Mientras juegas con el reTerminal y las imágenes parpadean constantemente, te recomiendo que dejes el dispositivo abierto, no atornilles la refrigeración ni la cubierta de plástico. De esta manera, se puede acceder fácilmente al interruptor de arranque. Mi dispositivo se calentó un poco, pero no demasiado.

Conecta el cable USB C y ejecuta el rpiboot utilidad como root:

$ sudo ./rpiboot 
RPIBOOT: build-date Feb 22 2022 version 20220208~181027 042cd145
Waiting for BCM2835/6/7/2711...
Loading embedded: bootcode4.bin
Sending bootcode.bin
Successful read 4 bytes 
Waiting for BCM2835/6/7/2711...
Loading embedded: bootcode4.bin
Second stage boot server
Loading embedded: start4.elf
File read: start4.elf
Second stage boot server done

Desmontar las carpetas, de lo contrario, la imagen parpadeante fallará:

sudo umount /dev/sda1; sudo umount /dev/sda2

Destella la imagen, usando bmaptool :

cd TO_THE_YOCTO_IMAGE_FOLDER
# cd b2qt/build-raspberrypi4-64/tmp/deploy/images/raspberrypi4-64/


sudo bmaptool copy b2qt-embedded-qt6-image-raspberrypi4-64-20220316191856.rootfs.wic.bz2 --bmap b2qt-embedded-qt6-image-raspberrypi4-64-20220316191856.rootfs.wic.bmap /dev/sda

Salida:

bmaptool: info: block map format version 2.0
bmaptool: info: 698368 blocks of size 4096 (2.7 GiB), mapped 367758 blocks (1.4 GiB or 52.7%)
bmaptool: info: copying image 'rootfs.wic.bz2' to block device '/dev/sda' using bmap file 'rootfs.wic.bmap'
bmaptool: info: 100% copied
bmaptool: info: synchronizing '/dev/sda'
bmaptool: info: copying time: 5m 6.5s, copying speed 4.7 MiB/sec

El parpadeo toma un tiempo, para mí con la imagen predeterminada toma alrededor de 5 minutos. El nombre del archivo de la imagen varía, la fecha y la hora están ahí. Vuelva a cambiar el interruptor de modo de arranque (tenga cuidado), retire el cable de alimentación USB C y vuelva a enchufarlo.

Primer inicio y resumen rápido

Siéntese, relájese y disfrute de su propio arranque de imagen de cosecha propia. ¡Bien hecho!

Juega con la aplicación de ejemplo, puedes hacer clic en "Más información" y desplazarte un poco.

Puede notar que la aplicación está girada. En realidad, la orientación predeterminada de la pantalla es vertical, pero el terminal es horizontal. Las preguntas frecuentes abordan esto para Ubuntu y Debian, lo arreglaremos más adelante cuando implementemos nuestra propia aplicación Qt. La solución depende del tipo de aplicación Qt que desee ejecutar y si tiene acceso al código fuente de dicha aplicación.

También puede conectar un cable de red y ssh en la máquina, la dirección IP se mostrará en la pantalla.

Para resumir lo que ya has logrado:

  • Yocto instalado
  • Instalado el boot2qt pila
  • Yocto personalizado creando tu propia capa
  • Se agregó la capa de hardware reTerminal
  • Crea tu propia imagen
  • Lo mostré en el reTerminal.

Si realiza cambios en Yocto, las compilaciones posteriores serán más rápidas, ya que solo tiene que volver a hacer las cosas que cambiaron. Los pasos que siempre tienes que hacer en el Yoctoside son:

  • cd b2qt/
  • export MACHINE=raspberrypi4-64 && source ./setup-environment.sh
  • (haz tus cambios)
  • bitbake b2qt-embedded-qt6-image

En el lado del reTerminal para flashear:

  • Voltea el boot mode switch y conecte un cable USB C
  • ./rpiboot para poder flashear la imagen
  • bmaptool copy b2qt-embedded-qt6-image-raspberrypi4-64-2022*.rootfs.wic.bz2 --bmap b2qt-embedded-qt6-image-raspberrypi4-64-2022*.rootfs.wic.bmap /dev/sda
  • Gire hacia atrás el interruptor de modo de arranque
  • Retire el cable de alimentación y vuelva a enchufarlo

Ahora que ha configurado su dispositivo, es hora de hacer uso de todas las funciones útilesboot2qt nos ofrece, lo más importante, la integración con el IDE de Qt, Qt Creator. Permite un rápido desarrollo y prueba, directamente desde dentro del IDE que puede implementar en el dispositivo y probar sus cambios. Ese flujo de trabajo es realmente agradable y rápido, incluida la depuración, los puntos de interrupción, etc.

Integración de Qt SDK y Qt Creator

En mi otro artículo sobre Yocto sobre el Pi Compute Module 4 normal, he escrito todos los pasos necesarios para crear el SDK de Qt e integrarlo con Qt Creator. Debido a que el proceso es bastante largo, he decidido no duplicarlo aquí, sino referirlo a mi otra guía, que está llena de capturas de pantalla y explica todo el proceso.

Consulte ese artículo para obtener la guía completa. Lo único que cambia es el primer comando a source el archivo de instalación, estamos exportando el MACHINE variable para la versión de 64 bits, así:

export MACHINE=raspberrypi4-64 && source ./setup-environment.sh 

A continuación, crea el SDK, lo que lleva un tiempo:

bitbake meta-toolchain-b2qt-embedded-qt6-sdk

Cuando haya completado todos los pasos en mi otra guía, debería tener un nuevo kit Qt configurado en Qt Creator y un nuevo dispositivo para implementar.

Haciendo que su propia aplicación sea la predeterminada

Ahora que tiene la imagen funcionando y su integración Qt configurada, debería poder ejecutar e implementar su aplicación en el reTerminal a través de Qt Creator.

Si, y solo si ese es el caso, continúe con la guía. Vamos a reemplazar el predeterminado b2qt startupscreen app con nuestro propio programa compilado.

En mi caso, es una aplicación de demostración de arrastrar y soltar. Se modificó un poco para mostrar también la dirección IP actual, lo cual es útil al depurar en el dispositivo.

Esta aplicación de demostración es genial porque también me permite verificar la pantalla táctil. Más adelante en la guía, en el caso de una aplicación Qt Widgets, la rotación de la pantalla y la rotación de la pantalla táctil deben coincidir; de lo contrario, se rotará la aplicación, pero no el toque. Entonces suceden cosas muy raras.

Comience por hacer una nueva receta para su aplicación. Lo llamaremos myapp para este ejemplo:

    mkdir -p sources/meta-raymii/recipes-myapp/myapp/files/

En la carpeta files/ que acabamos de crear, coloque el binario compilado para su aplicación, asígnele el nombre myapp para este ejemplo de guías. Asegúrate de que la arquitectura coincida con la compilación Pi de 64 bits:

$ file myapp
myapp: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.14.0, BuildID[sha1]=f2d876e1fe62e2eec1d5c0ead27a99c74a1f77ca, with debug_info, not stripped

A continuación, cree el archivo de receta real con el nombre de archivo myapp_1.0.bb (no en el files carpeta, pero una carpeta arriba). El guión bajo y el número de versión son importantes, si aumenta ese número, Yocto creará un nuevo paquete. Pegue los siguientes contenidos:

DESCRIPTION = "My Custom Qt App"
AUTHOR = "[email protected]"
LICENSE = "CLOSED"
PR = "r0"

SRC_URI =+ "file://myapp \
           "

DEPENDS += "qtbase qtdeclarative qtdeclarative-native"

do_install() {
    install -d ${D}/${bindir}
    install -m 0755 ${WORKDIR}/myapp ${D}/${bindir}/myapp

    lnr ${D}/${bindir}/myapp ${D}/${bindir}/b2qt

}

FILES_${PN} = "${bindir}/myapp \
               ${bindir}/b2qt \
              "

La línea que comienza con lnr reemplaza la compilación en b2qt aplicación de pantalla de inicio (que es un enlace simbólico) a su propia aplicación. boot2qt se envía con un lanzador simple que, al arrancar, lanza el enlace simbólico actual en /usr/bin/b2qt y tiene algunas utilidades más (como iniciar/detener o reemplazar el enlace simbólico)

Agregue el nuevo myapp receta a nuestra imagen personalizada .bbappend archivo:

vi sources/meta-raymii/recipes-qt/images/b2qt-embedded-qt6-image.bbappend

Edite el IMAGE_INSTALL_append sección y agregue myapp justo encima del kernel-modules línea:

        myapp \

Toda la sección se ve así ahora:

IMAGE_INSTALL_append = " \
        myapp \
        kernel-modules \
        evtest \
        iperf3 \
        i2c-tools \
        util-linux \
        "

Después de los cambios, crea una nueva imagen:

bitbake b2qt-embedded-qt6-image

Flashea eso usando bmaptool como se describe arriba.

Porque estamos agregando al predeterminado b2qt imagen, y porque estamos vinculando nuestro propio binario donde el b2qt lanzador lo espera, la próxima vez que inicie después de crear y mostrar una imagen, su propia aplicación debería iniciarse.

Aquí hay una imagen de mi aplicación personalizada después del inicio, todavía girada incorrectamente:

Si desea cargar una nueva versión de su aplicación, reemplace el myapp binario en el files carpeta e incrementar el PR = "r0" línea a r1 . Luego bitbakea una nueva imagen y flashea. Enjuague y repita para cada lanzamiento.

Si solo desea probar una nueva versión, también puede bitbake myapp , solo creará la aplicación sin una imagen nueva. Habrá un nuevo IPK paquete en el tmp/deploy/ipk carpeta:

$ file tmp/deploy/ipk/cortexa72/myapp_1.0-r2_cortexa72.ipk
tmp/deploy/ipk/cortexa72/myapp_1.0-r2_cortexa72.ipk: Debian binary package (format 2.0), with control.tar.gz, data compression xz

scp este archivo en el dispositivo e instálelo usando el administrador de paquetes opkg :

opkg install myapp_1.0-r2_cortexa72.ipk

Luego reinicie o reinicie el startupscreen servicio para cargar la nueva aplicación.

Sin embargo, si solo desea probar nuevas compilaciones de su aplicación, use la integración de creador de Qt incorporada que configuró anteriormente. Funciona mucho más rápido y directamente desde Qt Creator, incluida la depuración remota.

Rotación de su aplicación en b2qt

Las siguientes secciones cubrirán el aspecto de la rotación. Es diferente para las aplicaciones Qt Widgets y Qt QML y, en mi opinión, es un gran lío. Las preguntas frecuentes cubren la rotación y encontré un blog de JapaneseSeeed que cubre la rotación, pero eso es todo para el X11 servidor de visualización

boot2qt usa eglfs para ejecutar directamente su aplicación. EGLFS es un complemento de plataforma para ejecutar aplicaciones Qt sobre EGL y OpenGL ES 2.0, sin un sistema de ventanas real como X11 o Wayland .

Usando eglfs , puede configurar una variable de entorno para rotar su aplicación, pero eso solo funcionará si tiene una aplicación Qt Widgets. Para una aplicación QML, debe agregar un transform: Rotation {} a su programa o ejecute un servidor de visualización como weston en wayland y deja que maneje la rotación. Cubriremos todas las opciones en las siguientes secciones, comenzando con Qt Widgets.

Rotación de widgets Qt

La opción más simple es para una aplicación Qt Widget, puede definir 2 variables de entorno, una para rotación y otra para rotación de pantalla táctil, eso es todo:

QT_QPA_EGLFS_ROTATION=-90
QT_QPA_GENERIC_PLUGINS=evdevtouch:/dev/input/event0:rotate=270

¿Por qué se usa -90? y uno usa 270 ? Porque cuando traté de usar 270 en lugar de -90 , al iniciar la aplicación dio un error:Invalid rotation 270 specified in QT_QPA_EGLFS_ROTATION . Probé QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS , pero no funcionó para la rotación de la pantalla táctil.

Ahora bien, ¿cómo aplicamos esto a Yocto? Hay un archivo de entorno qt predeterminado en /etc/default/qt , que debemos anular en nuestra compilación de Yocto. Comience por crear una carpeta donde nuestra anulación .bbappend residirá:

mkdir -p sources/meta-raymii/recipes-qt/boot2qt-addons/default-qt-envs/

Copie el archivo de entorno predeterminado del boot2qt capa a esa carpeta:

cp sources/meta-boot2qt/meta-boot2qt/recipes-qt/boot2qt-addons/default-qt-envs/defaults sources/meta-raymii/recipes-qt/boot2qt-addons/default-qt-envs/

Edite el defaults archivo:

vim sources/meta-raymii/recipes-qt/boot2qt-addons/default-qt-envs/defaults

Agregue las dos líneas debajo de las existentes:

QT_QPA_EGLFS_ROTATION=-90
QT_QPA_GENERIC_PLUGINS=evdevtouch:/dev/input/event0:rotate=270    

En mi caso, las teclas programables por el usuario no aparecen, por lo que la pantalla táctil es /dev/input/event0 . Podría ser event1 , pero puedes verificar usando el evtest comando:

root@b2qt-raspberrypi4-64:~# evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:      seeed-tp
/dev/input/event1:      vc4
/dev/input/event2:      vc4
Select the device event number [0-2]: 

seeed-tp es la pantalla táctil (tp significa panel táctil).

Crea un .bbappend archivo, que anulará la receta predeterminada:

vim sources/meta-raymii/recipes-qt/boot2qt-addons/default-qt-envs.bbappend

Agrega lo siguiente:

FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

Esta línea agrega la carpeta en nuestra propia capa al paquete, por lo que buscará los archivos en esa carpeta, así como en la carpeta original. Su nueva carpeta se comprueba primero. El manual de Yocto explica esta variable y por qué usar := es importante.

Puedes comprobar que tu .bbappend se usa usando el siguiente comando:

bitbake-layers show-appends default-qt-envs

Salida:

=== Matched appended recipes ===
default-qt-envs.bb:
  /home/remy/b2qt/sources/meta-raymii/recipes-qt/boot2qt-addons/default-qt-envs.bbappend
  /home/remy/b2qt/sources/meta-boot2qt/meta-boot2qt-distro/dynamic-layers/raspberrypi/recipes-qt/boot2qt-addons/default-qt-envs.bbappend

bitbake la imagen y flashearla, ahora su aplicación Qt Widgets debe girarse correctamente. Aquí hay una imagen del ejemplo rotado incorrectamente de la aplicación de demostración de controles de widgets Qt:

Y aquí está la aplicación con las variables de entorno configuradas, rotadas como era de esperar:

Rotación Qt QML

Para una aplicación QML, la rotación es un poco más difícil. Debe realizar cambios en el código fuente o usar wayland y weston , un administrador de pantalla y un servidor que manejan la rotación. La última solución es solo si no puede cambiar el código fuente de su aplicación.

Si puedes cambiar tu QML código fuente, agregue un Rotation transformación:

transform: Rotation {
    angle: 270 
    origin.x: parent.width / 2
    origin.y: parent.width / 2
}

En este caso, asumo que la rotación está en su elemento raíz. No el Window , pero el Loader o StackLayout , o Rectangle en la ventana, cualquiera que sea su elemento raíz.

No se requieren cambios en el entorno, simplemente cargue una nueva versión de su aplicación como se describe anteriormente.

Weston y Wayland

Si no puede cambiar su código fuente, debe instalar un administrador de pantalla. Usamos Wayland y Weston, no X11 . La documentación de Qt tiene un artículo que explica por qué no X11. Aquí hay una cita que resume las partes importantes:

Qt también tiene un Wayland Compositor, pero no lo vamos a usar. Vamos a ejecutar nuestro myapp programa como aplicación cliente en Weston . Weston es el compositor de referencia, algo así como el administrador de ventanas en X11. ¿Por qué Weston? Se envía con el boot2qt Yocto stack y puede ejecutar un programa a pantalla completa sin decoraciones ni paneles (usando el kiosk complemento).

Actualmente estamos en la versión 9 de Weston. En la versión 10 habrá soporte para programas de inicio automático, pero por ahora debemos hacerlo nosotros mismos usando un systemd Servicio.

Como hemos hecho varias veces en esta guía, haremos un .bbappend file para anular las recetas predeterminadas con nuestros cambios. Comience creando una estructura de carpetas:

mkdir -p sources/meta-raymii/recipes-graphics/wayland/weston-init/

En esa carpeta, crea un archivo llamado weston.ini y pon lo siguiente:

# configuration file for Weston

[core]
shell=kiosk-shell.so
require-input=false

[output]
name=DSI-1
mode=720x1280@60
transform=rotate-270

[screen-share]
command=/usr/bin/weston --backend=rdp-backend.so --shell=fullscreen-shell.so --no-clients-resize

[shell]
panel-position=none

La configuración enviada por defecto inicia un escritorio, pero estamos cambiando eso. El kiosk-shell.so El complemento ejecuta una aplicación a pantalla completa sin ninguna decoración de ventana. El output sección, incluido el transform=rotate-270 es la sección mágica que necesita para rotar su aplicación QML.

Crea un .bbappend receta:

FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

SRC_URI += " file://weston.ini "

do_install_append() {
    # Remove upstream weston.ini to avoid conflict with weston-ini-conf package
    rm -f ${D}${sysconfdir}/xdg/weston/weston.ini

    install -D -p -m0644 ${WORKDIR}/weston.ini ${D}${sysconfdir}/xdg/weston/weston.ini
}

SYSTEMD_AUTO_ENABLE_${PN} = "enable"

Esto se parece a lo que hicimos anteriormente para anular el entorno predeterminado de Qt. FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" agrega la carpeta actual en nuestra propia capa, donde acabamos de colocar el archivo de configuración. Tuve algunos problemas vagos donde el weston.ini predeterminado el archivo no se reemplazó, razón por la cual existe un do_install_append tan explícito sección. Normalmente eso no es necesario, pero en mi caso, el archivo no sería reemplazado a menos que lo hiciera de esta manera.

SYSTEMD_AUTO_ENABLE_${PN} = "enable" habilita el weston servicio systemd.

Ahora, para asegurarse de que weston comienza y no b2qt o el startupscreen , debemos hacer algunos más .bbappend recetas para deshabilitar esos servicios systemd. Solo puede haber un servicio de visualización en ejecución, si b2qt se ejecuta, luego weston no podrá iniciar.

Igual que antes, cree el siguiente archivo:

sources/meta-raymii/recipes-qt/boot2qt-addons/boot2qt-startupscreen_%.bbappend 

Ponga en la línea de abajo:

SYSTEMD_AUTO_ENABLE_${PN} = "disable"

Esto deshabilita el startupscreen servicio.

Repita lo anterior para el b2qt servicio, que, de manera confusa, está en el default-qt-envs archivo de recetas:

sources/meta-raymii/recipes-qt/boot2qt-addons/default-qt-envs.bbappend

La misma línea entra para deshabilitar el servicio systemd:

SYSTEMD_AUTO_ENABLE_${PN} = "disable"

La siguiente parte involucra nuestra imagen personalizada .bbappend archivo, donde necesitamos agregar weston a las características de distribución, para asegurarse de que systemd arranca hasta el graphical objetivo y no el multiuser objetivo:

sources/meta-raymii/recipes-qt/images/b2qt-embedded-qt6-image.bbappend

Añadir weston \ al IMAGE_FEATURES_append sección:

IMAGE_FEATURES_append = " \
        splash \
        weston \
        "

Incluya el weston-init paquete en el IMAGE_INSTALL_append sección:

IMAGE_INSTALL_append = " \
        myapp \
        kernel-modules \
        evtest \
        iperf3 \
        i2c-tools \
        util-linux \
        weston-init \
        "

La última parte consiste en actualizar nuestro myapp receta para incluir un systemd service, que iniciará nuestra aplicación después de weston Está empezado. Crear un nuevo archivo:

vim sources/meta-raymii/recipes-myapp/myapp/files/myapp.service 

Coloque los siguientes contenidos:

[Unit]
Description=MyApp on Weston
After=weston.service

[Service]
User=weston
Restart=always
Type=simple
Environment=QT_QPA_PLATFORM=wayland
ExecStartPre=/bin/sh -c 'echo XDG_RUNTIME_DIR="$(loginctl show-user --property=RuntimePath --value \"$USER\")" > /tmp/qtenv'
EnvironmentFile=-/tmp/qtenv
ExecStopPost=/bin/rm /tmp/qtenv
ExecStart=/usr/bin/myapp
WorkingDirectory=/home/weston

[Install]
WantedBy=multi-user.target

Si ejecuta una aplicación Qt en Wayland, se requiere el XDG_RUNTIME_DIR Variable ambiental. Podríamos codificar esto a /run/user/1000 , que funcionaría para esta configuración específica, pero también podemos usar el loginctl Comando para consultar la ruta real, que funciona para todos los dispositivos y configuraciones futuras.

systemd no tiene opción para evaluar un comando de shell como un Environment opción, así que usamos un truco para hacer eso. Primero, ejecuta el ExecStartPre comando, que inicia una subcapa para ejecutar el comando y escribe la salida en un archivo en /tmp . Luego especificamos la línea EnvironmentFile , pero, importante , comience con un guión (- ). Esto asegura el orden correcto, primero el comando, luego el archivo. No está bien documentado, encontré una publicación de stackoverflow que lo explica, pero ya no puedo encontrar eso para citar como fuente. Una vez que la aplicación se detiene, el archivo de entorno se elimina.

Cambia nuestro myapp_1.0.bb receta para incluir esta receta systemd:

DESCRIPTION = "My Custom Qt App"
AUTHOR = "[email protected]"
LICENSE = "CLOSED"
PR = "r1"

SRC_URI =+ "file://myapp \
            file://myapp.service \
           "

inherit systemd

DEPENDS += "qtbase qtdeclarative qtdeclarative-native"

do_install() {
    install -d ${D}/${bindir}
    install -m 0755 ${WORKDIR}/myapp ${D}/${bindir}/myapp

    lnr ${D}/${bindir}/myapp ${D}/${bindir}/b2qt

    install -m 0755 -d ${D}${systemd_unitdir}/system
    install -m 0644 ${WORKDIR}/myapp.service ${D}${systemd_unitdir}/system/
}

FILES_${PN} = "${bindir}/myapp \
               ${bindir}/b2qt \
              "
SYSTEMD_SERVICE:${PN} = "myapp.service"

Especificando SYSTEMD_SERVICE , se habilitará de forma predeterminada en el arranque.

Cree una nueva imagen y, después de todo ese esfuerzo, el resultado debería ser una aplicación QML rotada correctamente:

En mi opinión personal, esta rotación para QML es un área que Qt Company podría mejorar, más bien, hacerla tan fácil como Qt Widgets.

Puede ejecutar cualquier aplicación Qt de esta manera manualmente, compilarla y copiarla a través de Qt Creator, o si no puede compilarla, simplemente cópiela. Set the correct environment variables and run it. For example, the Qt built in Bear Whack example (fun game, under quick/touchinteraction ):

XDG_RUNTIME_DIR=/run/user/1000 QT_QPA_PLATFORM=wayland /usr/share/examples/quick/touchinteraction/touchinteraction 

Here's a picture of Bear Whack:

And here's a picture of the SameGame demo running. Particles and effects arevery smooth on the reTerminal: