tag 标签: TorizonCore

相关博文
  • 热度 9
    2022-4-24 11:21
    1441 次阅读|
    0 个评论
    ​ B y Toradex 胡珊逢 在嵌入式设备上开发图形用户界面通常会选择 Qt 。这是一种经验证的方案,我们可以在多个领域看到用 Qt 开发的 UI 。但随着移动端和 web 端界面更为广泛地使用,源自于这两个领域的技术也开始向嵌入式设备渗透。 Flutter 就是一个例子。本文将介绍如何在 Torizon 平台上如何使用 Flutter 来开发用户界面。 Google 面向 Android, iOS 推出的跨平台移动应⽤开发框架 Flutter 可以构建高质量的原⽣⽤户界⾯ , 并可以扩展支持 Web 和桌面应用。 Flutter 尚未官方支持嵌入式系统 , 但目前 Sony 和 Ubuntu 正在致力于该工作。例如来自 Sony 的 elinux 可以在嵌入式平台上使用 Flutter 。我们也将以此为基础 , 在 Verdin iMX8M Plus 的 Torizon 上运行 Flutter 应用。 我们来看看 Flutter 的构架。如下图所示 , 其由三个部分构成 , User app, Framework 和 Engine 。 flutter-elinux-linux 属于为嵌入式提供支持的 embbedder 。它可以运行在 wayland 显示后台 , 这也是 Torizon 提供的显示框架。 flutter-elinux-linux 将提供 flutter-client , libflutter_elinux_wayland.so 和 libflutter_engine.so 。这些软件的功能参考该网页描述。 https://github.com/sony/flutter-embedded-linux/wiki/Features-of-Embedded-Linux-embedding-for-Flutter flutter-elinux 是 Flutter SDK 的一个非官方插件 , 用于为嵌入式设备创建、编译和调试 Flutter 应用 , 并使用 flutter-elinux-linux 在设备上显示。 为了减少对编译电脑的软件环境影响 , 我们将使用 docker 容器进行编译。使用下面命令获取 ubuntu:20.04 容器并进入其中。由于后面需要向容器内提供文件 , 这里将 /home/user/flutter 映射到容器内的 /opt/flutter 。 ----------------------------------------------- ~$ docker pull ubuntu:20.04 ~$ docker run -it -v /home/user/flutter:/opt/flutter --name flutter_build ubuntu:20.04 /bin/bash ----------------------------------------------- 如果后续进入该容器重新编译,可以使用下面命令: ----------------------------------------------- ~$ docker container start flutter_build ~$ docker exec -it flutter_build bash ----------------------------------------------- 在容器中安装所需的软件。 ----------------------------------------------- # apt update # apt upgrade # apt install clang cmake build-essential pkg-config libegl1-mesa-dev libxkbcommon-dev libgles2-mesa-dev # apt install libwayland-dev wayland-protocols git curl wget unzip git # apt install python2 # apt install virtualenv ----------------------------------------------- 下载编译工具。 ----------------------------------------------- # mkdir -p /opt/flutter # cd /opt/flutter # git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git # export PATH=$PATH:$(pwd)/depot_tools ----------------------------------------------- 默认的 ubuntu:20.04 使用 Python3 ,在容器里使用 virtualenv 创建 Python2 环境。 ----------------------------------------------- # virtualenv .env -p python2 # source .env/bin/activate ----------------------------------------------- 创建 .gclient 文件并指定版本。 ----------------------------------------------- # cat .gclient solutions = ----------------------------------------------- 上面的 bd539267b42051b0da3d16ffa8f48949dce8aa8f 对应 ${path_to_flutter_sdk_install}/flutter/bin/internal/engine.version ,两者需要一致。如果不指定的话,会下载最新的版本。除非确实需要编译最新版本的 Engine ,否则并不推荐。 获取代码。 ----------------------------------------------- # gclient sync ----------------------------------------------- 编译 embbedder 。这里编译为 arm64 目标 release 模式的 embedder 。 ----------------------------------------------- # cd src # ./flutter/tools/gn --target-os linux --linux-cpu arm64 --runtime-mode release --embedder-for-target --disable-desktop-embeddings --no-build-embedder-examples # ninja -C out/linux_release_arm64 ----------------------------------------------- 编译成功后在 out/linux_release_arm64 目录中可以看到 libflutter_engine.so 文件。 接下来将编译 Embedded Linux embedding for Flutter ,这里会生成 flutter-client 和 libflutter_elinux_wayland.so 。如果在 X86 电脑上交叉编译需要使用 Yocoto Project 生成包含 clang 在内的 SDK , 这会涉及大量的工作内容。在 Torizon 中我们可以直接使用 debian 容器并通过 apt 命令安装相应的软件 , 在 Verdin iMX8M Plus 本地编译。这通常适用于代码量不是很多的项目。在 Verdin iMX8M Plus 上运行下面命令启动 debian 容器。 ----------------------------------------------- ~$ docker run -it -v /home/torizon/workspace:/opt/workspace torizon/debian:$CT_TAG_DEBIAN /bin/bash ----------------------------------------------- 在容器中安装所需的软件。 ----------------------------------------------- # apt update # apt install clang cmake build-essential pkg-config libegl1-mesa-dev libxkbcommon-dev libgles2-mesa-dev # apt install unzip git # apt install curl wget # apt install libwayland-dev wayland-protocols # apt install libdrm-dev libgbm-dev libinput-dev libudev-dev libsystemd-dev # cd /opt/workspace ----------------------------------------------- 下载 flutter-embedded-linux 代码。 ----------------------------------------------- # git clone https://github.com/sony/flutter-embedded-linux.git # cd flutter-embedded-linux/ # mkdir build ----------------------------------------------- 此时将刚才编译的 libflutter_engine.so 复制到 build 目录。然后分别执行下面两个命令。 ----------------------------------------------- # cmake -DUSER_PROJECT_PATH=examples/flutter-wayland-client -DCMAKE_BUILD_TYPE=Release .. # cmake -DUSER_PROJECT_PATH=examples/flutter-wayland-client -DCMAKE_BUILD_TYPE=Release -DBUILD_ELINUX_SO=ON -DBACKEND_TYPE=WAYLAND -DENABLE_ELINUX_EMBEDDER_LOG=OFF -DFLUTTER_RELEASE=ON .. ----------------------------------------------- 编译完成后在 build 目录下可以看到生成的 flutter-client 和 libflutter_elinux_wayland.so 两个文件。上面使用的编译选项含义请参考该 网页 说明。 接下来重新回到 X86 编译电脑开始 Flutter 应用的编译。用下面命令重新进入使之前的 ubuntu:20.04 容器。 ----------------------------------------------- ~$ docker exec -it flutter_build bash ----------------------------------------------- 下载 flutter-elinux 。这个是 Flutter SDK 。 ----------------------------------------------- # cd /opt/flutter/ # git clone https://github.com/sony/flutter-elinux # export PATH=$PATH:/opt/flutter/flutter-elinux/bin ----------------------------------------------- 运行下面命令查看安装情况。 ----------------------------------------------- # flutter-elinux doctor # flutter-elinux devices ----------------------------------------------- 创建一个示例工程。 ----------------------------------------------- # flutter-elinux create demo1 # cd demo1 ----------------------------------------------- 按照这里的说明交叉编译创建的工程。但在这之前需要准备 Verdin iMX8M Plus 的 arm64 格式文件系统。该文件系统可以是来自刚才在 Verdin iMX8M Plus 上编译 Embedded Linux embedding for Flutter 的容器。 在 Verdin iMX8M Plus 运行下面命令 , 查看容器 ID 。 ----------------------------------------------- $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3dea07245b24 torizon/debian:2-bullseye "/bin/bash" 2 days ago Exited (137) 2 hours ago hardcore_nightingale ----------------------------------------------- 将容器的文件系统复制出来并打包。 ----------------------------------------------- $ sudo docker cp 3dea07245b24:/ arm64-sysroot $ sudo tar cvf arm64-sysroot.tar arm64-sysroot ----------------------------------------------- 然后将 arm64-sysroot.tar 复制到 X86 编译电脑的 flutter_build 容器中,位于 /opt/flutter 目录。回到 flutter_build 容器,解压 arm64-sysroot.tar 。 ----------------------------------------------- # cd /opt/flutter/ # tar vxf arm64-sysroot.tar ----------------------------------------------- 进入刚才创建的 demo1 目录,运行下面命令编译。 ----------------------------------------------- # cd demo1 # flutter-elinux build elinux --target-arch=arm64 --target-sysroot=/opt/flutter/arm64-sysroot ----------------------------------------------- 待编译结束后,查看 build/elinux/arm64/release/bundle ,这里是 Flutter app 运行所需的所以文件。 ----------------------------------------------- # tree build/elinux/arm64/release/bundle -L 2 . |-- data | |-- flutter_assets | `-- icudtl.dat |-- demo1 `-- lib |-- libapp.so |-- libflutter_elinux_wayland.so `-- libflutter_engine.so ----------------------------------------------- libflutter_elinux_wayland.so 和 libflutter_engine.so 是 Fltter SDK 预编译的库文件,需要将其替换为之前编译的库文件。 将 flutter-client 和 bundle 文件夹复制到 Verdin iMX8M Plus 的 /home/torizon/flutter_demo 目录。然后先启动 weston 容器。 ----------------------------------------------- $ docker run -e ACCEPT_FSL_EULA=1 -d --rm --name=weston --net=host --cap-add CAP_SYS_TTY_CONFIG \ -v /dev:/dev -v /tmp:/tmp -v /run/udev/:/run/udev/ \ --device-cgroup-rule='c 4:* rmw' --device-cgroup-rule='c 13:* rmw' \ --device-cgroup-rule='c 199:* rmw' --device-cgroup-rule='c 226:* rmw' \ torizon/weston-vivante:$CT_TAG_WESTON_VIVANTE --developer weston-launch \ --tty=/dev/tty7 --user=torizon ----------------------------------------------- 再启动另外一个 torizon/weston-vivante 容器,在里面我们将用命令行的方式启动编译好的 demo1 。 ----------------------------------------------- $ docker run -e ACCEPT_FSL_EULA=1 -it --rm --name=wayland-app --user=torizon \ -v /dev/dri:/dev/dri -v /dev/galcore:/dev/galcore -v /tmp:/tmp -v /home/torizon/flutter_demo:/opt/flutter \ --device-cgroup-rule='c 199:* rmw' --device-cgroup-rule='c 226:* rmw' \ torizon/weston-vivante:$CT_TAG_WESTON_VIVANTE bash ----------------------------------------------- 在启动的容器内运行下面命令。 ----------------------------------------------- # cd /opt/flutter # LD_LIBRARY_PATH=/opt/flutter/bundle/lib/ ./flutter-client -b /opt/flutter/bundle ----------------------------------------------- 最后,我们将介绍如何导入一个现成的 Flutter 项目并打包为一个容器,用 docker-compose 文件启动。这里以 covid19_mobile_app 为例进行说明。 在 flutter_build 容器中,下载 covid19_mobile_app 代码,将之前 demo1 目录中的 elinux 文件夹复制到 covid19_mobile_app 后再编译。同样 , libflutter_elinux_wayland.so 和 libflutter_engine.so 也需要替换为之前编译的库文件。 ----------------------------------------------- # cp -r ../demo1/elinux covid19_mobile_app # flutter-elinux pub get # flutter-elinux build elinux --target-arch=arm64 --target-sysroot=/opt/flutter/arm64-sysroot ----------------------------------------------- 编译结束后,将 covid19_mobile_app 的 bundle 目录连同 flutter-client ,以及下面的 startup.sh , Dockerfile 放到任一目录中。 startup.sh ----------------------------------------------- #!/bin/bash LD_LIBRARY_PATH=/home/torizon/bundle/lib/ /usr/sbin/flutter-client -b /home/torizon/bundle ----------------------------------------------- Dockerfile ----------------------------------------------- FROM --platform=linux/arm64 torizon/weston-vivante:2 ADD bundle /home/torizon/bundle COPY flutter-client /usr/sbin COPY startup.sh /home/torizon CMD ----------------------------------------------- 运行下面命令生成一个 flutter app 容器。 ----------------------------------------------- $ docker build -t flutter_demo:1 . ----------------------------------------------- 将 flutter_demo:1 容器和 docker-compose.yml 文件复制到 Verdin iMX8M Plus 上。 docker-compose.yml ----------------------------------------------- services: flutter_demo_covid19: depends_on: - weston devices: device_cgroup_rules: - c 199:* rmw - c 226:* rmw volumes: - /tmp:/tmp:rw - /dev/dri:/dev/dri:rw - /dev/galcore:/dev/galcore:rw weston: cap_add: - CAP_SYS_TTY_CONFIG device_cgroup_rules: - c 4:0 rmw - c 4:7 rmw - c 13:* rmw - c 199:* rmw - c 226:* rmw environment: - ACCEPT_FSL_EULA=1 image: torizon/weston-vivante:2 network_mode: host volumes: - source: /tmp target: /tmp type: bind - source: /dev target: /dev type: bind - source: /run/udev target: /run/udev type: bind version: '2.4' ----------------------------------------------- 运行 docker-compose up -d 即可启动 weston 和 flutter app 容器。 总结 Flutter 框架为图形界面开发提供一个非常灵活的方案,使得嵌入式开发也可以从中受益。于此同时,嵌入式 Linux 对 Flutter 的支持也处于早期阶段,项目开发需要充分验证。
  • 热度 10
    2021-10-15 15:24
    2220 次阅读|
    0 个评论
    B y Toradex 胡珊逢 Torizon 是 Toradex 面向行业应用推出的一款基于 Linux 的全新 的开源 操作系统。其旨在简化嵌入式系统开发的难度,同时引入现代软件开发、维护理念,提供更加可靠且易于使用的互联、在线功能。 Torizon 为嵌入式设备实现了一套崭新的开发和使用方法。本文接下来将介绍 Torizon 的特色功能,以及相比于传统的 Linux 系统在使用上的差异。 Torizon 由 TorizonCore OS 和 Torizon Platform 两大部分组成。 TorizonCore OS 是安装在 Toradex 计算机模块上的操作系统。 Torizon Platform 是 Toradex 维护 的 在线平台,其能够于 TorizonCore OS 建立网络连接,为运行 TorizonCore OS 的计算机模块提供诸多在线功能,例如 OTA 更新、集群设备管理、远程监控等。 TorizonCore OS 底层采用了 Linux ,支持常用的 Linux 命令工具。该系统一个显著特点是支持容器 docker 。如下图所示, TorizonCore 包含了 Linux 内核、容器运行环境、以及 OTA 等其他服务。用户的应用运行在容器之中,而非直接访问 Linux 文件系统。多个容器可以独立运行。 容器是一种标准化的软件单元。一个容器集合了用户应用本身,以及该应用运行所依赖的软件如第三方库文件,配置文件和数据文件等。容器中的软件独立于操作系统,可以视为操作系统的虚拟化。因此容器可以非常容易地迁移到其他硬件平台上。 对 Docker 容器的支持,使得用户可以利用 Docker H ub 上丰富的现成容器,例如 Qt 、 Debian 、 Ubuntu 、 .Net 、 Python 等。从而不再需要进行复杂的交叉编译。同时容器技术具有非常高效的版本管理功能,用户应用的升级和回滚都可以从中受益。例如在传统 Linux BSP 上从 Qt 5.12 升级到 Qt5.15 , 用户需要重新编译 Qt 源码或者 使用 Yocto P roject 重构 整个 BSP 。而在 TorizonCore OS 上下载一个 Qt5.15 的容器即可。也无需担心操作系统其他软件的版本是否兼容。 由于采用了容器的方式运行用户软件 , TorizonCore OS 本身一个非常精简的最小功能系统。用户不在其上面直接安装软件或者部署编译好的应用。除了系统配置目录如 /etc , TorizonCore OS 的大部分文件系统都不允许用户直接修改 , 如 /usr 、 /lib 等目录下的文件。 用户需要创建一个容器,在容器安装所需的软件以及编译好的应用程序。然后启动容器,由容器中的应用程序实现相关业务功能。 TorizonCore OS 的文件系统由 OSTree 管理。这是一种类似 git 工作模式的文件管理系统,由其实现对每个系统文件的添加、删除、恢复等功能。同时 OSTree 也是实现 OTA 更新的基础。 传统的嵌入式设备在第一批设备出厂后,通常软件和硬件都不再会发生变化。而对于现代软件开发来说,借助 CI (持续集成)、 CD (持续开发)等模式,即使在设备交付后,仍能够提供软件更新,修复未知的问题或者增加新功能,从而提升用户使用体验。位于云端的 Torizon Platform 则为 TorizonCore OS 提供 OTA 更新、集群设备管理和远程监控功能 , 更多实用的功能也会即将上线。 OTA 更新 允许嵌入式设备远程更新其软件 , 无需直接接触设备就 通过 更新软件修复问题、部署新业务或者打补丁。具有 OTA 功能的设备通常对该功能具有较高的要求。更新出错、网络中断或者更新期间意外断电都可能导致设备无法正常工作。所以 OTA 需要能够在更新出错 时 能够自动回滚到最后一个可正常运行的软件状态。 Torizon OTA 采用高可靠的 Aktualizr 客户端 , 默认已经集成在 TorizonCore OS 。凭借 OSTree 实现了软件版本回滚功能。相对于 A/B 分区整体更新方式 , Torizon OTA 采用的是差分更新 , 即只更新发生更改的文件。有效得提高了更新速度,并减少数据下载量。这对使用 4G/5G 上网的设备显得尤为重要。 用户可以将自己的 BSP 上传到 Torizon Platform 对特定的设备进行更新,也可以使用 Toradex 发布的 BSP 令设备保持最新的软件状态。同时也 单独 可以对设备上的容器进行更新,而非整个 BSP 。 Torizon Platform 的 集群设备管理 能够更加高效地对大量设备进行维护。实现批量设备的重启、 安装 特定的更新等。 远程监控 能够远程查看设备的运行状态,例如 CPU 负荷、内存占用、网络使用、 正在 运行进程和重要 的 异常日志等。这些信息可以被发送到 Torizon Platform ,给用户提供可视化监控数据。远程监控基于 Fluent Bit 实现。这是一个开源的日志处理和转发器。用户可以使用丰富的插件来采集更多的数据,包括温度、内核日志等。除了监控设备运行状态外,这些数据也有助于修复现场遇到的问题。 远程访问是即将上线的另一个功能。这可以令您接管设备,简化客户支持或者问题排查。 对于开发人员, Toradex 提供相应的插件支持使用 Visual Studio/Visual Studio Code 开发 Torizon 。用户可以自由选择 Windows 、 Linux 或者 Mac 作为开发主机。 Torizon 扩展插件提供对 Visual Studio Code 完善的支持。扩展插件可以便捷地管理容器和在设备上 在线 调试 , 使您可以通过很少的几次点击就完成从 Visual Studio Code 完成应用部署。甚至直接将开发好的容器上传到 Torizon Platform 进行远程部署。 Visual Studio/Visual Studio Code 中我们也提供包括 C/C++ 、 Python 、 .NET Core 甚至是 Qt 开发的工程模板。 令用户在嵌入式设备上方便地使用主流开发语言。 上面是对 Torizon 系统从设备端 TorizonCore OS , 到云端的 Torizon P latform 以及开发工具的简要介绍。如果您像更全面而深入的了解 Torizon ,请阅读 这里 。