tag 标签: linux

相关帖子
相关博文
  • 热度 2
    2020-11-20 09:39
    669 次阅读|
    0 个评论
    By Toradex 秦海 1). 简介 嵌入式平台多屏显示是比较常见的功能,在 NXP iMX6 上面,由于使用了基于 fbdev/X11 的显示接口驱动和显示服务,可以比较方便的通过 framebuffer 方式来实现多屏显示, Qt 也提供了想 eglfs 或者 linuxfs 这样的组件来对接。而基于 NXP 新的 iMX8 平台,由于使用了 DRM/KMS 显示接口驱动和 Wayland 显示服务,多屏显示的实现思路可能有如下几种,而本文就演示基于 Qtwayland 组件来实现双屏独立显示。 ./ 通过底层 IPU 驱动来实现,主要可以比较灵活的实现如 clone 模式等,但难度比较大,需要对 iMX8 底层 IPU 驱动有比较深入的了解 ./ 如果是通过 iMX8 双通道 LVDS ,连接两个单通道的 LVDS 屏幕,可以通过 device tree ldb 节点 ”dual-mode” 来实现 clone 显示 ./ iMX8 默认的 wayland/Weston compositor 默认支持多屏扩展模式显示,但是 9.0 以下版本无法对应用程序窗口进行定位, 9.0 以后引入了 Kiosk shell 支持,则可以通过应用程序窗口定位到不同屏幕实现多屏独立显示的效果 ./ 使用 Qtwayland 组件构建 wayland compositor ,可以方便的实现多屏独立显示,在多屏都是同样分辨率前提下,也可以实现 clone 显示 本文所使用的 ARM 嵌入式平台来自于 Toradex 基于 NXP 最新的 iMX8 SoC (基于 Cortex-A72+A53 和 Coretex-M4 架构)的 ARM 计算机模块 Apalis iMX8QM 4GB WB IT 。 2). 准备 a).Apalis iMX8QM4GB WB IT ARM 核心版配合 Ioxra 载板 ,连接调试串口 UART1 (载板 X22 )到开发主机方便调试。 b). Apalis iMX8 支持 HDMI 和 LVDS 显示接口,分别连接如下两个屏幕 ./ 13.3 inch HDMI panel 显示屏,分辨率 1920x1080 ,支持 USB 接口电容式触摸,将触摸接口连接到 Ixora 载板 USB 接口 ./ 10.1 inchLVDS 显示屏 ,分辨率 1280x800 ,支持 I2C 接口电容式触摸,将触摸接口连接到 Ixora 载板 X24 连接器 c). USB UVC 标准摄像头连接到 Ixora 载板用于 Gstreamer 测试 3). Apalis iMX8 Ycoto Linux 编译部署以及配置 a). Apalis iMX8 Ycoto Linux 通过 Ycoto/Openembedded 框架编译,具体的配置方法请参考 这里 ,参考如下修改后编译 Reference-Multimedia image 镜像 ------------------------------- # local.conf ,增加 eglfs 和 kms 支持 + PACKAGECONFIG_append_pn-qtbase = " sql-sqlite eglfs kms" + PACKAGECONFIG_append_pn-qtmultimedia = " gstreamer" + ACCEPT_FSL_EULA = "1" # layers/meta-toradex-demos/recipes-images/images/tdx-reference-multimedia-image.bb ,增加 SDK populate + inherit populate_sdk populate_sdk_qt5 # compile Reference-Multimedia image $ bitbake bitbake tdx-reference-multimedia-image # compile SDK bitbake tdx-reference-multimedia-image -c populate_sdk ------------------------------- b). Ycoto Linux image 部署 参考 这里 通过 Toradex Easy installer 将上面编译好的 image 更新部署到模块,版本为目前最新的 Ycoto Linux V5.1 c). 显示配置 ./ HDMI 默认即可正常显示,如果有显示器 EDID 读取问题不能成功显示,可以通过下面方法通过软件 firmware 方式手动加载 EDID ,更多关于显示的配置请参考 这里 ------------------------------- # cp EDID binary file to rootfs $ mkdir /lib/firmware/edid $ cp 1920x1080.bin /lib/firmware/edid # set uboot kernel command line # setenv defargs ‘pci=nomsi drm.edid_firmware=HDMI-A-1:edid/1920x1080.bin’ # saveenv && reset ------------------------------- ./ LVDS 显示, Ycoto Linux V5.1 默认 device tree 下 LVDS 是 disable 的,需要通过下面方式加载对应 device tree overlay 来 enable , device tree overlay 的更多说明请参考 这里 ------------------------------- # overlay files path root@apalis-imx8:~# ls /media/mmcblk0p1/overlays/ apalis-imx8_atmel-mxt_overlay.dtbo apalis-imx8x_parallel-rgb_overlay.dtbo apalis-imx8_lvds_overlay.dtbo display-edt5.7_overlay.dtbo apalis-imx8x_ad7879_overlay.dtbo display-edt7_overlay.dtbo apalis-imx8x_atmel-mxt_overlay.dtbo display-fullhd_overlay.dtbo apalis-imx8x_display-lt161010_overlay.dtbo display-lt161010_overlay.dtbo apalis-imx8x_display-lt170410_overlay.dtbo display-lt170410_overlay.dtbo # add lvds and i2c touch(atmel) related overlay file to /media/mmcblk0p1/overlays.txt fdt_overlays=overlays/apalis-imx8_lvds_overlay.dtbo overlays/display-lt170410_overlay.dtbo overlays/apalis-imx8_atmel-mxt_overlay.dtbo ------------------------------- ./ 触摸设备测试,通过 ”evetst” 命令 ------------------------------- # list all devices root@apalis-imx8:~# evtest No device specified, trying to scan all of /dev/input/event* Available devices: /dev/input/event0: sc-powerkey /dev/input/event1: gpio-keys /dev/input/event2: HID 27c0:0818 /dev/input/event3: USB 2.0 Camera: HD USB Camera /dev/input/event4: Atmel maXTouch Touchscreen # from above output ./ event2 is HDMI display USB HID capacitive touch device ./ event4 is LVDS display I2C capacitive touch device ------------------------------- 4). Qtwayland compositor 编译部署 a). Qt Qtwayland 组件可以非常方便的使用 QML 语言开发定制化的 wayland compositor ,详细说明请见 这里 ,也提供了很多 sample project 供参考 b). 本文测试所使用的 qtwayland compositor 来自于 Toradex Europe FAE Stefan Eichenberger ,源代码请参考 这里 ,这是一个用于双屏显示的 qtwayland compositor c). 参考 这里 说明使用上面章节 3.a 编译出的 SDK 文件配置 qtcreator 交叉编译环境,下载 dual-screen qtwayland compositor 代码后进行编译,生成 dual-screen 可执行二进制文件上传到 Apalis iMX8 系统中 d). 使用编译好的 dual-screen qtwayland compositor 替换系统默认的 weston compositor ./ 创建 dual-screen.sh 执行脚本文件 ------------------------------- # copy dual-screen binary to /usr/bin $ cp dual-screen /usr/bin/ # create dual-screen.sh script, detailed content in below $ vi /usr/bin/dual-screen.sh # add executable permission $ chmod +x dual-screen.sh ------------------------------- ./ dual-screen.sh – 由于系统包含三个 input 设备,两个触摸设备和一个 USB 摄像头,在启动过程中,其对应的 event 号码可能会变化,因此脚本前面先对 “kms.conf” 文件里面的设置和系统启动后的设备 event 进行比对,如果一致则直接启动 compositor ,如不一致则需要先修改 ”kms.conf” 文件后再启动 compositor 。这里使用的 ts0/ts1 symbol 链接则是在下面 udev rule 文件中定义的。 ------------------------------- # get system touch device event number while do sleep 0.1 done ts0=$(readlink /dev/input/ts0) while do sleep 0.1 done ts1=$(readlink /dev/input/ts1) # compare with kms.conf settings while do sleep 0.1 done ts_hdmi=$(sed -n 8p /etc/kms.conf|cut -d '"' -f4|cut -d '/' -f4) ts_lvds=$(sed -n 13p /etc/kms.conf|cut -d '"' -f4|cut -d '/' -f4) # modify kms.conf if seetings is not consistent with system event if ;then sed -i "8 s/event.*/$ts0\"\,/g" /etc/kms.conf fi if ;then sed -i "13 s/event.*/$ts1\"\,/g" /etc/kms.conf fi # execute qtwayland compositor /usr/bin/dual-screen & ------------------------------- ./ 创建 systemd service 文件 ------------------------------- # /lib/systemd/system/qtwayland@.service Description=Qt Wayland Compositor RequiresMountsFor=/run Conflicts=plymouth-quit.service After=systemd-user-sessions.service plymouth-quit-wait.service User=%i PAMName=login Environment="QT_QPA_EGLFS_KMS_CONFIG=/etc/kms.conf" Environment="QT_QPA_EGLFS_INTEGRATION=eglfs_kms" Environment="QT_QPA_PLATFORM=eglfs" Environment="QT_QPA_EGLFS_KMS_ATOMIC=1" Environment="QT_QPA_EGLFS_NO_LIBINPUT=1" StandardError=journal PermissionsStartOnly=true IgnoreSIGPIPE=no ExecStart=/usr/bin/dual-screen.sh # 通过 /etc/kms.conf 文件来配置 KMS 显示接口设备, ”touchDevice” 参数对应 3.c 章节中测试的 event ,更多关于 Qt eglfs DRM/KMS 的配置说明请参考 这里 。 $ vi /etc/kms.conf { "device": "/dev/dri/card0", "hwcursor": true, "pbuffers": false, "outputs": } ------------------------------- ./ 创建新的 udev rule 替换系统默认的 weston udev rule ------------------------------- # remove default weston udev rule $ rm /etc/udev/rules.d/71-weston-drm.rules # add qtwayland rule $ vi /etc/udev/rules.d/71-qtwayland-drm.rules # connect HDMI HID touchscreen and LVDS I2C touchscreen with fix symlink SUBSYSTEM=="input" KERNEL=="event*" ATTRS{name} =="HID 27c0:0818", SYMLINK+="input/ts0" SUBSYSTEM=="input" KERNEL=="event*" ATTRS{name} =="Atmel maXTouch Touchscreen", SYMLINK+="input/ts1 # start qtwayland compositor ACTION=="add", SUBSYSTEM=="graphics", KERNEL=="fb0", TAG+="systemd", ENV{SYSTEMD_WANTS}+="qtwayland@root.service" ACTION=="add", SUBSYSTEM=="drm", KERNEL=="card0", TAG+="systemd", ENV{SYSTEMD_WANTS}+="qtwayland@root.service" ------------------------------- e). 测试 qtwayland compositor ------------------------------- # disable default wayland qt demo app systemd service $ systemctl disable wayland-app-launch $ reboot ------------------------------- 重启后,可以看到下面双屏显示结果, qtwayland compositor 启动成功 5). Gstreamer 测试 a). 分别运行两个 gstreamer pipeline ,然后 qtwayland compositor 会将第一个运行的 pipeline 显示在 HDMI 显示器上面,第二个运行的显示在 LVDS 显示器上面 b). Gstreamer pipeline 1 - USB 摄像头播放,关于 gstreamer 使用的更多说明请参考 这里 ------------------------------- $ gst-launch-1.0 v4l2src device=/dev/video2 ! 'image/jpeg,width=1920,height=1080,frame rate=30/1' ! jpegdec ! videoconvert ! waylandsink fullscreen=1 sync=false & ------------------------------- c). Gstreamer pipeline 2 – gstreamer 测试 pipeline ------------------------------- $ gst-launch-1.0 videotestsrc ! waylandsink fullscreen=1 ------------------------------- d). 实际运行效果如下 6). Qt 应用测试 a). 分别使用一个 Qt Widget 应用和一个 Qt Quick 应用进行测试 ./ Qt Widget 应用 – 读取系统时间和 CPU 温度,同时调用 sqlite 数据库进行保存的应用,详细说明请参考 这里 ,将编译好的可执行 binary “qt-sqlite” 上传到 Apalis iMX8 ./ Qt Quick 应用 – 调用 qtmultimedia 组件播放视频以及摄像头,详细说明请参考 这里 ,将编译好的可执行 binary “videotest” 上传到 Apalis iMX8 b). 创建应用启动脚本 ------------------------------- $ vi /usr/bin/qtwayland-app-launch.sh #!/bin/sh if test -z "$XDG_RUNTIME_DIR"; then export XDG_RUNTIME_DIR=/run/user/`id -u` if ! test -d "$XDG_RUNTIME_DIR"; then mkdir --parents $XDG_RUNTIME_DIR chmod 0700 $XDG_RUNTIME_DIR fi fi # wait for qtwayland while ; do sleep 0.1; done sleep 1 /home/root/videotest -url file:///home/root/ready-player-one-trailer-2_h720p.mov & sleep 1 /home/root/qt-sqlite & ------------------------------- c). 创建开机自启动 systemd service 文件 ------------------------------- $ vi /lib/systemd/system/qtwayland-app-launch.service Description=Start a Qt wayland application After=qtwayland@root.service Requires=qtwayland@root.service Restart=on-failure Type=forking Environment="QT_QPA_PLATFORM=wayland" ExecStart=/usr/bin/qtwayland-app-launch.sh RestartSec=1 WantedBy=multi-user.target ------------------------------- d). enable service 并测试 ------------------------------- $ systemctl enable qtwayland-app-launch $ reboot ------------------------------- e). 重启后效果如下,两个屏幕的触摸都可以分别正常使用 5). 总结 本文在 iMX8 嵌入式平台下使用 Qtwayland 工具测试了 HDMI/LVDS 双屏独立显示功能。 参考文档 https://developer.toradex.cn/knowledge-base/display-output-resolution-and-timings-linux https://doc.qt.io/qt-5/embedded-linux.html#embedded-eglfs https://github.com/eichenberger/qt-dual-screen-compositor
  • 热度 3
    2020-11-17 10:46
    142 次阅读|
    0 个评论
    By Toradex 胡珊逢 在使用嵌入式 Linux 系统的时,会出现由于设备意外断电引起文件系统损坏而最终使该设备无法启动的现象。为了应对这种情况,通常会从硬件设计如采用备用电源,无论是锂电池还是超级电容等,或者从系统软件设上加以规避。本文接下来将介绍如何使用 squashfs 只读文件系统制作 Linux 系统文件,并采用 overlayfs 为用户目录增加可写权限。演示采用 Colibri iMX6 计算机模块,该方法同样也适用于 Toradex 其他产品,如 iMX8 计算机模块。 Squashfs 是一种只读压缩文件系统,通常被用于数据备份或者系统资源受限的计算机系统上使用,如 Linux 发行版的 LiveCD , OpenWRT 系统也采用 squashfs 。 OverlayFS 一个结合其他文件系统的联合挂载,将多个挂载点叠加为一个目录。常见的应用是在一个只读的分区上叠加可读写的另一个分区。嵌入式 Linux 设备通常的功能都是被设计好的,极少需要在后期安装其他软件或更改 Linux 系统软件,更多的是更新设备应用程序和相关数据。因此基于 squashfs 的只读文件系统,结合 overlayfs 为用户应用和数据提供读写操作,能够提高嵌入式 Linux 文件系统可靠性。 在 Colibri iMX6 的 eMMC 上我们将使用以下分区规划。 BootFS 为 FAT32 格式,该分区上包含 Linux 内核文件, device tree 等启动文件,如果是 iMX8 ,则还包含一些其他固件文件。该分区通常只在文件系统烧写阶段被写入。 RootFS 分区是 Linux 运行的文件系统, usr, bin, lib, etc, home 等目录都在上面。一般该分区是 EXT3 , EXT4 格式,支持文件的写入和删除。而文件系统的损坏也常发生于此,最终导致设备启动失败。因此我们这里会采用只读格式的 squashfs 。 UserData 是能够读写的 EXT4 分区。该分区通过 overlayfs 会被挂载到原本位于只读 squashfs 中的 /home/root 目录。用户应用可以毫无察觉得使用该目录,在上面写入和删除文件,但不破坏只读 squashfs 文件系统,所有的操作都会被转移到 UserData 分区上。用户的应用也会存在 UserData 分区上,启动的时候从这里加载应用程序。该分区是可写的,所有这上面的文件是可以被更新。 ​ 下面我们会具体说明如何在 Yocto 环境生成符合上面规划的 BSP ,并通过 Toradex Easy Installer 工具实现这些分区和写入文件。 首先需要在 Yocto 环境中生成 squashfs 格式的系统文件 rootfs 。修改 build/conf/local.conf ,结尾添加以下内容。 ------------------------------------ IMAGE_FSTYPES_append = " squashfs" ------------------------------------ 默认 Linux 内核配置下 squahfs 是通过加载内核驱动模块实现对其支持,而模块驱动文件位于 rootfs 中,为了保证 Linux 内核在启动时能够正确处理该格式,需要将 squahfs 内核驱动模块配置为静态驱动,直接编译进内核中。为内核配置的文件系统支持添加 squahfs 和 overlay 格式。 ------------------------------------ $ MACHINE=colibri-imx6 bitbake -c menuconfig virtual/kernel → File systems Overlay filesystem support → File systems → Miscellaneous filesystems SquashFS 4.0 - Squashed file system support ------------------------------------ EXT4 格式的 UserData 分区会通过 overlay 机制挂载到只读的 rootfs 上的 /home/root ,但这之前需要通过 fstab 将该分区挂载到系统中, /home/root 。在 Yocto 中, layers/meta-toradex-demos/recipes-core/base-files/base-files/fstab 会被编译到 Colibri IMX6 BSP 中,在该文件中添加: ------------------------------------ /dev/mmcblk0p3 /media/data auto defaults,sync,noauto 0 0 ------------------------------------ 然后再添加一个开机自启动脚本,将 /media/data 使用 overlay 挂载到 /home/root 。 在 layers/meta-toradex-bsp-common/recipes-core 目录中添加 mount-overlayfs 文件夹,里面包含编译需要的 bb 文件和 systemd service 。 mount-overlayfs.bb 中 install -d ${D}/media/data 会在 /media 目录中创建 data 文件夹, FILES_${PN} = "/media/data" 将该空文件夹添加到 BSP 中。 mount-overlayfs.service 通过 RequiresMountsFor 保证 /media/data 目录通过 fstab 挂载后才运行。 Overlay 的目录结构如下, lowerdir 为 /home/root upperdir 为 /media/data/home/root/upper , workdir 为 /media/data/home/root/work 。这样应用可以在 /home/root 下直接读写文件, overlayfs 对应用和用户都是透明的。 ------------------------------------ Type=simple ExecStart=/bin/sh -c 'mount -t overlay -o lowerdir=/home/root,upperdir=/media/data/home/root/upper,workdir=/media/data/home/root/work overlay /home/root' ------------------------------------ 在 build/conf/local.conf 中将 mount-overlayfs 添加到 BSP 中。 ------------------------------------ IMAGE_INSTALL_append = " mount-overlayfs" ------------------------------------ 由于 rootfs 是只读格式,无法像之前一样直接在开发板上运行 systemctl 命令添加开机自启动脚本。我们需要像上面一样,在 Yocto 中增加一个 test-app 来开机自动运行位于 UserData 分区(该分区通过 overlay 会被最终挂载到 /home/root 目录)上的测试程序 test 。在 layers/meta-toradex-bsp-common/recipes-core 目录中添加 test-app 文件夹,里面包含编译需要的 bb 文件和 systemd service 。 在 build/conf/local.conf 中将 test-app 添加到 BSP 中。 ------------------------------------ IMAGE_INSTALL_append = " mount-overlayfs test-app" ------------------------------------ 至此我们已经通过修改 Yocto 能够生成所需结构的 BSP ,执行下面命令完成编译任务。 ------------------------------------ $ MACHINE=colibri-imx6 bitbake tdx-reference-minimal-image ------------------------------------ 在 build/deploy/images/colibri-imx6 有相关文件生成,我们需要下面两个文件,文件名字中的时间戳对应具体编译的日期。 Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0.tar Colibri-iMX6_Reference-Minimal-Image.rootfs.squashfs 解压 Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0.tar 。因为 rootfs 是 squahfs 格式,需要使用定制的 boot.src 来启动。 ------------------------------------ $ cd ~/ $ tar vxf Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0.tar $ cd Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0 $ tar vxf Reference-Minimal-Image-colibri-imx6.bootfs.tar.xz ------------------------------------ 修改其中的 emmcargs_set 参数。 ------------------------------------ env set emmcargs_set 'env set rootfsargs root=/dev/mmcblk0p2 rootfstype=squashfs ro rootwait' ------------------------------------ 可以使用该 boot.cmd 直接生成对应的 boot.src, 替换解压目录中同名文件 , 重新打包 Reference-Minimal-Image-colibri-imx6.bootfs.tar.xz ------------------------------------ $ cd Reference-Minimal-Image-colibri-imx6.bootfs $ rm boot.src $ mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "Distro boot script" -d boot.cmd boot.scr $ cd .. $ tar cJf Reference-Minimal-Image-colibri-imx6.bootfs.tar.xz -C Reference-Minimal-Image-colibri-imx6.bootfs . ------------------------------------ 将 squashfs 的 rootfs 文件系统复制到 Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0 目录中。 ------------------------------------ $ cp Colibri-iMX6_Reference-Minimal-Image.rootfs.squashfs Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0 ------------------------------------ 接下来创建需要复制到 UserData 分区中的文件。如上面提到的 overlay 挂载需要有对应目录结构,依次创建以下目录,并将测试程序 test 复制到 upper 目录中。这里的测试程序 test 是一个非常简单的 C 应用,它会输出“ Hello Toradex! ”到系统日志中。 ------------------------------------ $ cd ~/Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0 $ mkdir rootfs $ cd rootfs $ mkdir -p home/root/upper $ mkdir -p home/root/work $ cp ~/test home/root/upper $ tree ------------------------------------ 打包为 rootfs.tar.xz 。 ------------------------------------ $ cd .. $ sudo tar cJf rootfs.tar.xz -C rootfs . ------------------------------------ 修改 image.json 文件,在 blockdevs 中增加 RAW 格式分区用于直接写入 squashfs 系统文件,以及 EXT4 格式的 DATA 分区用于写入上面生成的 rootfs.tar.xz 。 Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0 目录下最终包含以下文件。 将上面的 BSP 通过 Toradex Easy Installer 重新安装到 Colibri iMX6 上,安装的时候注意需要点击 Erase 擦除 eMMC 上的内容。 烧写后重启模块。可以通过 mount 命令查看挂载分区的情况。 ------------------------------------ root@colibri-imx6:~# mount /dev/mmcblk0p2 on / type squashfs (ro,noatime) …… /dev/mmcblk0p3 on /media/data type ext4 (rw,relatime,sync) overlay on /home/root type overlay (rw,relatime,lowerdir=/home/root,upperdir=/media/data/home/root/upper,workdir=/media/data/home/root/work) ------------------------------------ mmcblk0p2 为写入 squashfs 只读文件系统的分区,例如在 /etc 目录无法创建文件。 ------------------------------------ root@colibri-imx6:/etc# mkdir test-folder mkdir: can't create directory 'test-folder': Read-only file system ------------------------------------ EXT4 格式的 /dev/mmcblk0p3 分区上是用户文件,被挂载到 /media/data 。而 /home/root 会通过 overlay 具有可读写权限。 ------------------------------------ root@colibri-imx6:~# cd ~/ root@colibri-imx6:~# pwd /home/root root@colibri-imx6:~# mkdir test-folder root@colibri-imx6:~# ls test test-folder root@colibri-imx6:~# ls -lh -rwxrwxr-x 1 1000 1000 11.3K Nov 11 2020 test drwxr-xr-x 2 root root 4.0K Feb 7 16:25 test-folder ------------------------------------ 位于 UserData 上的测试程序 test 也在开机的时候自动运行。 ------------------------------------ root@colibri-imx6:~# journalctl -u test-app -- Logs begin at Fri 2020-02-07 15:50:53 UTC, end at Fri 2020-02-07 16:11:49 UTC. -- Feb 07 15:50:57 colibri-imx6 systemd : Started start a demo on overlay mount folder. Feb 07 15:50:57 colibri-imx6 test : Hello Toradex! Feb 07 15:50:57 colibri-imx6 systemd : test-app.service: Succeeded. ------------------------------------ 总结 上面我们演示结合使用 squashfs 和 overlay ,将系统文件放在一个只读分区,把读写操作在单独的分区上进行。降低系统文件因意外断电受损从而导致无法启动的风险。在使用只读 squashfs 只读文件系统时需要保证 rootfs 尽量精简,建议在 Reference-Minimal-Image 基础上构建用户自己的 BSP ,甚至对其进行裁剪。
  • 热度 10
    2020-9-30 15:13
    1633 次阅读|
    1 个评论
    By Toradex 胡珊逢 1). 简介 通常当编译 Linux 、 U-Boot 相关源代码时,由于编译工具或者文件系统限制,这些任务需要在 Linux 发行版中完成,如常见的 Ubuntu 、 Fedora 、 Linux Mint 、 Arch Linux 等。在电脑安装双系统,或者虚拟机,是使用 Linux 发行版的主要方式。 Windows 推出的 WSL ( Windows Subsystem for Linux )则提供了另外一种方式来使用 Linux 系统。本文接下来将介绍如何在 Windows 10 电脑上使用 WSL 来编译使用 NXP iMX8 ARM 平台的 Linux 、 U-Boot 和 Device tree overlays 。 本文所演示的 ARM 平台来自于 Toradex 基于 NXP iMX8QM ARM 处理器的 Apalis iMX8QM ARM 嵌入式平台。 2). 编译流程 WSL 有两个版本,这里我们将使用 WSL 2 。在开始安装 WSL 之前,推荐先安装 Windows Terminal 。这是微软新推出的终端工具,可以很好的兼容 WSL 。并且还直接集成了一些 Linux 的命令工具,如 ssh 、 scp 。 WSL 具体的安装方法请参考微软官方的适用于 Linux 的 Windows 子系统安装指南 (Windows 10) 。安装完毕后我们将使用 Ubuntu-20.04 为例进行编译演示。 打开 Windows Terminal 点击标签页旁边的 + ,可以看到刚才安装的 Ubuntu-20.04 WSL 已经自动出现在其中。点击后即可启动 Ubuntu 。目前的 WSL 还不支持图形,所以接下来的操作会在 Windows Terminal 以命令行的形式完成。 进入 Ubuntu-20.04 WSL 后,命令操作的形式和通常的 Ubuntu 没有区别。首先安装一些编译所需的软件。 sudo apt update sudo apt install make bison flex sudo apt install build-essential sudo apt install libncurses-dev sudo apt install libssl-dev 交叉编译工具 gcc 的安装可以通过两种形式。在 Ubuntu-20.04 WSL 中通过 wget 等命令直接下载。另外还可以在 Windows 电脑上通过浏览器下载,然后使用 Windows 的文件浏览器直接访问 Ubuntu-20.04 WSL 的文件系统,将编译工具复制进去。交叉编译工具的选择可以参考 这里 。 在文件浏览器中输入 \\wsl$\ ,其会显示电脑上可以用的 WSL 实例文件系统。例如将适用于 Apalis iMX8QM Linux BSP 5.0 的 gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz 复制到 Ubuntu-20.04/home/ben 目录下。 重新回到 Windows Terminal 命令行终端,解压该工具,并设置环境变量。 tar vxf gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz export ARCH=arm64 export DTC_FLAGS="-@" export PATH=/home/ben/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/:$PATH export CROSS_COMPILE=aarch64-none-linux-gnu- 使用 git 工具下载 Linux 、 U-Boot 源码。 git config --global user.name "XXX" git config --global user.email your_email git clone -b toradex_imx_v2020.04_5.4.24_2.1.0 git://git.toradex.cn/u-boot-toradex.git git clone -b toradex_5.4-2.1.x-imx git://git.toradex.cn/linux-toradex.git git clone -b toradex_5.4-2.1.x-imx git://git.toradex.cn/device-tree-overlays.git 详细的编译步骤和说明可以参考我们开发者中心的相关 网页说明 。 例如编译 U-boot make apalis-imx8_defconfig &1 | tee build.log 例如编译 Linux 和 device tree make defconfig &1 | tee build.log make DTC_FLAGS="-@" freescale/fsl-imx8qm-apalis-ixora-v1.1.dtb 编译 Device tree overlays cpp -nostdinc -I ../../linux-toradex/arch/arm64/boot/dts/freescale -I ../../linux-toradex/include -undef -x assembler-with-cpp apalis-imx8_atmel-mxt_overlay.dts apalis-imx8_atmel-mxt_overlay.dts.preprocessed dtc -@ -Hepapr -I dts -O dtb -i ../../linux-toradex/arch/arm64/boot/dts/freescale -o apalis-imx8_atmel-mxt_overlay.dtbo apalis-imx8_atmel-mxt_overlay.dts.preprocessed 当这些都编译好以后,生成的文件都可以通过文件浏览器将其复制出来。 在完成编译工作后, Windows Terminal 命令行终端输入 exit 命令即可退出 WSL ,但其仍在后台运行。通过以下命令来查看仍在运行的 WSL 实例,并将其关闭。 wsl --list --running 适用于 Linux 的 Windows 子系统分发版 : Ubuntu-20.04 ( 默认 ) wsl --terminate Ubuntu-20.04 3). 总结 借助 WSL 运行 Linux 发行版,为 Linux 开发人员提供一种简便的方式,免去双系统的切换,或者安装庞大的虚拟机系统。 WSL 是直接运行在 CPU 上,避免了虚拟化技术的开销。目前该技术也有限制,如 WSL 还无法使用图形界面,从而使得一些需要借助图形化界面 IDE 如 Eclipse 完成的 C/C++ 应用开发还不是很适合。当然网络上也有关于如何在 WSL 安装 X11 并通过远程桌面的方式来开启图形界面的说明,但这会影响到 WSL 的性能。 WSL 的方式比较适合不需要借助图形界面的编译任务,如 make 、 cmake 编译,甚至是 Yocto 编译等。 ​
  • 热度 3
    2020-5-2 17:43
    1932 次阅读|
    2 个评论
    【MYC-C8MMX物联网开发板】+ Hello Android!!!
    上期测试遇到了一些问题,我重新买了个新的USB摄像头,想测试一下是否可以,接下来看一看。 新买的USB摄像头。 插上摄像头,输入lsusb,依然是能够找打硬件的,如图。 打开chees,依然是无法发现设备,很郁闷。什么问题不必深究,毕竟时不我待,测评还要继续哦。 go,go,go转战android,按照广泛体验说明,要把板子烧成android的步骤我们先要准备一根microUSB线。 然后准备好镜像,并且解压完毕。 管理员方式打开cmd,进入到android_p9.0.0_2.3.0-ga_image_myd-c8mmx目录下输入命令uuu_imx_android_flash.bat-fimx8mm-ddr4-a-e-c7。 然后插上microusb即可进入到adb烧录模式了,很遗憾,我的电脑居然报错了,烧录失败了。 怎么回事,倒推上去看一看,原来是USB驱动问题。 查了一下,NXP UUU模式更新镜像,win7用户是要更新一下USB驱动的,很幸运,我是win7,又学习到了新知识。 https://community.nxp.com/docs/DOC-342719 这个网址有简单教程,也可以下载uuu.pdf系统的看一看,教程说了win10无需更新驱动的,言下之意,win7自己看着办吧。 去指定的驱动网址,下载zadig2.5,下载完成后安装。 安装成功后,按照之前烧录的步骤再来一次,就会开始烧录了,如图。 烧录成功,长出一口气。 忘记了烧录过程要把boot模式改一改老规矩了。 把boot模式改回eMMC启动模式,等待一会,android开始启动。 开机画面居然还有小企鹅,咳咳。 这才是开机画面,大大大的android。 ok等待一会就进入到了待机面,没有触屏,接上鼠标一样用,按住左键一拉就进入到了主界面了。 接下来连接一下wifi。 搜索并输入密码,ok很顺利连接上了,硬件是好的。 登陆一下百度测试一下。 最后献上板卡的美照,别流口水。 好了android测评暂时先到这里。 声明:转载请经过本人同意,图片版权归个人和面包板以及米尔科技共同所有。
  • 热度 2
    2019-10-21 11:05
    1507 次阅读|
    1 个评论
    By Toradex 秦海 1). 简介 随着 Python 在互联网人工智能领域的流行,大家也慢慢感受到 Python 开发的便利,本文就基于嵌入式 ARM 平台,介绍使用 Python 配合 PyQT5 模块来开发图形化应用程序。 本文所演示的 ARM 平台来自于 Toradex 基于 NXP iMX6 ARM 处理器的 Apalis iMX6 ARM 嵌入式平台。 2. 准备 a). Apalis iMX6Q ARM 核心版配合 Apalis Evaluation Board 载板 ,连接调试串口 UART1 (载板 X29 )到开发主机方便调试。更多关于 Apalis iMX6 配合 Apalis Evaluation Board 载板的说明请参考 Datasheet 和 开发上手指南 。 b). Apalis iMX6Q 默认的 Linux BSP 是不包含 Python , QT 等支持的,需要重新编译。 ./ 基于 Toradex Linux BSP release V2.8 ./ 参考 这里 搭建 Openembedded 编译环境,然后适配下面 patch ,用于使本文测试需要的 libsoc 适配 Python3 。 https://github.com/simonqin09/libsoc-examples/blob/master/python/0005-libsoc-python3-support.patch ./ 修改 build/conf/local.conf 文件,增加需要的组件 -------------------------- #IMAGE_INSTALL_append = " python3 python3-pip python3-libsoc python3-pyqt5 rng-tools " -------------------------- ./ 适配下面 patch ,在标准 image bb 文件中增加 QT5 的支持 https://github.com/simonqin09/libsoc-examples/blob/master/python/0003-angstrom-qt5-lxde-image.patch ./ 重新编译 image -------------------------- $ bitbake -k angstrom-qt5-lxde-image -------------------------- ./ 新生成的 image 位于 deploy/images/apalis-imx6/ 目录,参考 这里 的说明更新到 Apalis iMX6 模块上面 3). Python GPIO 中断测试程序 a). 首先我们先不包含图形界面,单独通过 Python 来完成简单的 GPIO 中断测试程序,本程序通过调用 libsoc 来完成 GPIO 控制,关于 libsoc 的使用和说明请参考 这里 。 b). Apalis Evaluation Board 载板硬件连接配置如下, X4 GPIO05(MXM3_11) 对应系统中的 GPIO 号码是 170 ,作为按键输入使用; X4 GPIO06(MXM3_13) 对应系统中的 GPIO 号码是 169 ,作为输出驱动 LED 使用。 X4 GPIO05 X34 SW5 X4 GPIO06 X34 LED1 c). 源代码请参考如下,分别实现了阻塞模式和非阻塞模式中断相应,实现功能就是按键交替点亮和关闭 LED 灯。 ./ 阻塞模式 – https://github.com/simonqin09/libsoc-examples/blob/master/python/gpiotest_block.py // main 函数作为主函数,实现打开 GPIOs ,同时设定初始化状态为高电平输出; test_interrupt_handler 函数实现中断相应,采用 gpio_in.wait_for_interrupt 为阻塞式中断,捕获中断才会继续进行,捕获中断后做了简单的防误触处理。 ./ 非阻塞模式 – https://github.com/simonqin09/libsoc-examples/blob/master/python/gpiotest_nonblock.py // main 函数作为主函数,实现打开 GPIOs ,同时设定初始化状态为高电平输出;另外,在 main 函数里面采用 gpio_in.start_interrupt_handler 来使能中断相应,为非阻塞式;在 main 函数最后通过 while 来接收键盘输入实现退出应用; gpio_in.wait_for_interrupt 依然作为中断处理函数相应中断并驱动 LED 状态改变。 d). 将 Python 代码直接复制到 Apalis iMX6 上面测试运行结果如下: ./ 阻塞模式下,最后是通过 Ctrl-C 强制退出程序 ----------------------- root@apalis-imx6:~# ./gpiotest_block.py The LED initial status is ON The LED turns OFF interrupt times is 1 The LED turns ON interrupt times is 2 ^Clibsoc-gpio-debug: Interrupted system call Traceback (most recent call last): File "./gpiotest_block.py", line 54, in main(gpio_input_id, gpio_output_id) File "./gpiotest_block.py", line 45, in main test_interrupt_handler(gpio_in, gpio_out) File "./gpiotest_block.py", line 12, in test_interrupt_handler gpio_in.wait_for_interrupt(-1) File "/usr/lib/python3.5/site-packages/libsoc/gpio.py", line 118, in wait_for_interrupt if api.libsoc_gpio_wait_interrupt(self._gpio, timeout) != 0: KeyboardInterrupt ----------------------- ./ 非阻塞模式下 ----------------------- root@apalis-imx6:~# ./gpiotest_nonblock.py The LED initial status is ON please enter 'Q' to quit The LED turns OFF The LED turns ON The LED turns OFF Q Do you really want to quit? yes or no yes root@apalis-imx6:~# ----------------------- 4). 使用 PyQt5 实现图形化界面 GPIO 中断程序 a). 硬件配置和连接和上面的测试场景一致。 b). 为了方便开发 PyQt5 界面,首先通过 Qtcreator 创建如下 QWidget 项目 UI 界面 // LED Status 右边的 QFrame 方框以及 QLable 用于显示 LED 当前的状态 // ‘Turn ON’ 和 ’Turn OFF’ 两个 PushButton 用于通过界面控制 LED 状态, ’Exit’ PushButton 用于退出程序 ./ 最终的 UI 源代码参考如下,将对应的 mainwindow.ui 文件复制到 Apalis iMX6 Python 应用相同路径下 https://github.com/simonqin09/libsoc-examples/blob/master/python/mainwindow.ui c). 程序源代码参考如下: https://github.com/simonqin09/libsoc-examples/blob/master/python/gpiotest_pyqt5.py 说明如下: ./ class ApplicationWindow 用于实现 Qt5 界面以及相关按键操作: // 首先通过 loadUi 函数来加载之前制作好的 UI 文件 mainwindow.ui ,然后初始化界面显示,连接各个按键对应的处理程序 // 最后开启一个新的 Qthread 线程 self.thread ,用于处理外部 GPIO 按键中断相应,连接新线程反馈信号的处理程序,最后启动新线程 // LedStatusChange 函数为处理新线程反馈回来的 LED 状态变化信号而同步改变界面显示状态的函数 // Button_On_clicked 和 Button_Off_clicked 函数用于根据界面按键的点击来对应改变 LED GPIO 输出以及界面显示的函数 // Button_Exit_clicked 和 closeEvent 函数用于处理退出程序包括子线程的退出等相关的函数 ./ class gpioInterrupt 为用于处理 GPIO 中断同时对于改变 LED GPIO 输出以及将 LED 状态变化反馈给界面主程序 // 首先定义反馈信号,并初始化所需要使用的 GPIO 引脚 // run 函数部分基本就是上面第 3 章节的阻塞模式 Python 应用的代码,这里就不做赘述了 d). 测试运行结果如下: ----------------------- root@apalis-imx6:~# ./gpiotest_pyqt5.py The LED initial status is ON set LOW set HIGH The LED turns OFF button clicked for setting LOW The LED turns ON button clicked for setting HIGH root@apalis-imx6:~# ----------------------- 5). 总结 如上述示例,使用 Python 和 PyQt5 非常方便了创建一个嵌入式界面应用程序示例,相对于传统 C 语言开机要配置交叉编译环境,整个流程更加快捷方便,同时在实现比较简单的控制的时候其运行效率也是可以接受的,另外 Python 还可以集成大量的组件方便开发,就更加简化了比如设计机器视觉、人工智能等领域的嵌入式应用开发流程。
相关资源
广告