Slint 打印机 Demo 在 Zephyr 上的构建与移植实战:从 native_sim 模拟器到 MIMXRT1170 / EK-RZ/A3M 真机

Slint 打印机 Demo 在 Zephyr 上的构建与移植实战:从 native_sim 模拟器到 MIMXRT1170 / EK-RZ/A3M 真机 Slint 打印机 Demo 在 Zephyr 上的构建与移植实战从 native_sim 模拟器到 MIMXRT1170 / EK-RZ/A3M 真机【免费下载链接】slintSlint is an open-source declarative GUI toolkit to build native user interfaces for Rust, C, JavaScript, or Python apps.项目地址: https://gitcode.com/GitHub_Trending/sl/slint本篇技术指南以 demos/printerdemo/zephyr/README.md 为核心骨架完整讲解 Slint Printer Demo 在 Zephyr RTOS 上的环境搭建、模拟器构建运行、两块真实开发板的构建烧录流程并结合仓库中 zephyr-common 平台集成的源码实现深入剖析显示驱动接入、RGB565 像素字节序处理、面板旋转、触摸事件映射与事件循环等底层原理。读完本文你不仅能亲手在 Zephyr 上跑起 Slint 示例还能理解如何将 Slint 移植到自己的 Zephyr 板卡。一、示例概览一个跑在 MCU 上的打印机触屏界面Printer Demo 是 Slint 官方示例中模拟打印机触摸屏界面的演示程序UI 定义位于 demos/printerdemo/ui/printerdemo.slint由MainWindow组件组织HomePage、SettingsPage、InkPage等页面并通过PrinterState、PrinterQueue、InkLevel等全局结构对外暴露数据与回调供 C 侧代码驱动。Zephyr 移植版本位于 demos/printerdemo/zephyr目录结构如下main.cpp应用入口负责初始化显示设备、创建 UI、用 C Model 填充墨量/打印队列数据、注册定时器驱动打印进度动画CMakeLists.txt按 BOARD 区分平台配置 Rust target、软件渲染器特性、面板旋转与字节序等编译选项VERSIONZephyr 应用版本元数据1.0.0README.md/README_NXP.md构建说明本文主体即基于前者展开。与 Espressif 集成不同Slint 的 Zephyr 平台集成不作为 Slint C API 的一部分提供而是以可复用的共享源码形式放在 demos/zephyr-common 目录由slint-zephyr.cpp/slint-zephyr.h实现。这样设计的原因文档中也有说明Zephyr 使用 Device Tree 向设备驱动模型描述硬件要注册输入事件回调既需要从 device tree 节点拿到struct device *指针也需要理解具体驱动行为才能编写回调函数。二、已确认的已知问题在动手之前先了解该示例当前的两个已知限制来自原文档均可从源码得到印证平台集成不随 C API 分发如前所述当前实现是通用方案足以覆盖 native_sim 模拟器与带显示 shield 的驱动更通用的抽象方案留待未来研究。不支持双缓冲Double Buffering在 slint-zephyr.cpp 中可以看到ZephyrWindowAdapter::init_from里双缓冲相关代码被注释掉固定使用RepaintBufferType::ReusedBuffer因为测试所用的模拟器与硬件均未上报支持SCREEN_INFO_DOUBLE_BUFFER。日志中会打印Double buffering: 0之类的信息可供确认。三、环境准备Prerequisites在运行本示例前需要完成以下七步准备1. 安装 Rust 并启用 nightly 通道# 通过 rustup 安装官方安装方式 rustup toolchain install nightly rustup default nightlynightly 通道是必需的从 CMakeLists.txt 可以看到native_sim 与 rza3m_ek 目标都使用-Zbuild-stdcore,alloc这类仅 nightly 可用的 cargo 标志。2. 安装 Zephyr 依赖按 Zephyr 官方 Getting Started 文档安装系统级编译依赖。3. 在虚拟环境中安装 West# 如果已检出 Slint 源码 python3 -m venv ../.venv source ../.venv/bin/activate # 如果还没有 Slint 源码 mkdir slint-zephyr python3 -m venv slint-zephyr/.venv source slint-zephyr/.venv/bin/activate # 安装 west pip install west4. 获取 Zephyr 源码通过 West manifest# 如果已检出 Slint 源码会在 Slint 源码旁边拉取 Zephyr 源码 cd .. west init -l --mf demos/zephyr-common/west.yaml ./slint # 如果还没有 Slint 源码会把 Slint 与 Zephyr 源码都检出到 slint-zephyr west init -m https://github.com/slint-ui/slint --mr zephyr --mf demos/zephyr-common/west.yaml slint-zephyr cd slint-zephyr # 检出所有仓库 west update这里用到的 manifest 文件 demos/zephyr-common/west.yaml 中Zephyr 被固定到v4.4.1版本。注意 manifest 的路径是以仓库根目录为基准的相对路径位于demos/zephyr-common/west.yaml。5. 导出 Zephyr CMake 包west zephyr-export这能让 CMake 自动加载构建 Zephyr 应用所需的样板代码。6. 安装 Zephyr 的 Python 依赖pip install -r ~/zephyrproject/zephyr/scripts/requirements.txt7. 安装 Zephyr SDK使用v1.0.1版本按原文档要求。四、在模拟器中构建与运行环境就绪后进入本目录执行# 构建 west build -b native_sim/native/64 -p always slint/demos/printerdemo/zephyr # 运行 ./build/zephyr/zephyr.exe-p always强制进行一次 pristine 构建干净构建Zephyr 官方文档推荐新用户使用此选项。模拟器方案的配套配置位于 demos/zephyr-common/boards/native_sim_64.conf开启CONFIG_INPUT_SDL_TOUCHy通过 SDL 模拟触摸输入与 demos/zephyr-common/boards/native_sim_64.overlay将 SDL 显示控制器设为 720x1280即竖屏面板尺寸。对应地CMakeLists.txt 为native_sim/native/64指定了x86_64-unknown-linux-gnu的 Rust 目标以及-Zbuild-stdcore,alloc标志。模拟器下 Zephyr 的 POSIX 架构无法抢占忙碌线程因此 slint-zephyr.cpp 在存在活跃动画时会主动k_sem_take睡眠 10ms避免事件循环死循环。五、在真实设备上构建、烧录与运行5.1 NXP MIMXRT1170-EVKBRK055HDMIPI4MA0 MIPI 显示屏该示例已在 NXP MIMXRT1170-EVKB 开发板配合 RK055HDMIPI4MA0 MIPI 显示屏上完成测试。板载调试探针可能需要按 Zephyr 文档说明进行配置。# 构建 west build -b mimxrt1170_evkB/mimxrt1176/cm7 -p always slint/demos/printerdemo/zephyr -- -DSHIELDrk055hdmipi4ma0 -DCMAKE_BUILD_TYPERelease # 烧录 west flash对应板级配置在 demos/zephyr-common/boards/mimxrt1170_evk_mimxrt1176_cm7.confCONFIG_MAIN_STACK_SIZE32768加大主线程栈避免 MPU FAULT: Stacking errorCONFIG_FPUyCONFIG_FP_HARDABIy启用硬件 FPU 与硬浮点 ABIRustthumbv7em-none-eabihf目标必需CONFIG_DMAyCONFIG_MCUX_ELCDIF_PXPyCONFIG_MCUX_ELCDIF_PXP_ROTATE_90y启用 PXP 外设及其 90 度旋转。PXP 硬件旋转的接入逻辑在 slint-zephyr.cpp当使能CONFIG_MCUX_ELCDIF_PXP_ROTATE_90时rotation.hardware Rotate270——因为 Kconfig 命名的是面板看到的旋转角度与帧缓冲实际经历的旋转方向相反。由于 PXP 走 DMA API 时显示驱动不支持局部刷新slint-zephyr.cpp 在CONFIG_MCUX_ELCDIF_PXP定义下改为整帧display_write。此外由于 RK055HDMIPI4MA0 盾板的 MIPI 显示屏也消费原生字节序的 RGB565 像素数据CMakeLists.txt 会为所有使用该 shield 的构建统一设置SLINT_ZEPHYR_RGB565_NATIVE_ENDIAN1。5.2 Renesas EK-RZ/A3M5 英寸 720x1280 MIPI 屏该示例也可以在 Renesas EK-RZ/A3M 评估套件及其 5 英寸 720x1280 MIPI 显示屏上运行。注意EK-RZ/A3M 必须使用 Renesas 的 Zephyr fork。将前置步骤第 4 步替换为# 如果已检出 Slint 源码使用 west-rza3m.yaml 而非 west.yaml cd .. west init -l --mf demos/zephyr-common/west-rza3m.yaml ./slint # 如果还没有 Slint 源码 west init -m https://github.com/slint-ui/slint --mr zephyr --mf demos/zephyr-common/west-rza3m.yaml slint-zephyr cd slint-zephyr # 检出所有仓库 west update专用 manifest demos/zephyr-common/west-rza3m.yaml 将 Zephyr 指向 Renesas 仓库的wip_rz分支因为该板卡与显示支持目前只存在于这个 fork 上。随后构建与烧录# 构建 west build -b rza3m_ek -p always slint/demos/printerdemo/zephyr -- -DSHIELDrtkapplcdms02001be -DCMAKE_BUILD_TYPERelease # 烧录使用 J-Link west flash对应的板级配置在 demos/zephyr-common/boards/rza3m_ek.conf其中CONFIG_MAIN_STACK_SIZE65536、CONFIG_HEAP_MEM_POOL_SIZE16777216提供了更充裕的栈与堆空间并启用了CONFIG_INPUT_GT911触摸控制器驱动rza3m_ek.overlay 则通过 chosen 节点将zephyr,touch指向 GT911 触摸设备。针对该板卡的特殊处理集中在 CMakeLists.txtRust 目标为aarch64-unknown-none并同样使用-Zbuild-stdcore,alloc由于面板以竖屏方式安装SLINT_ZEPHYR_PANEL_ROTATION90由软件渲染器将 UI 旋转四分之一圈后再绘制该显示驱动消费原生字节序 RGB565 像素设置SLINT_ZEPHYR_RGB565_NATIVE_ENDIAN1。另外slint-zephyr.cpp 在CONFIG_BOARD_RZA3M_EK下把事件循环最长睡眠时间截断为 10 秒避免唤醒间隔过长。六、深入源码Zephyr 平台集成是如何工作的6.1 CMake 构建要点CMakeLists.txt 是整个移植的构建枢纽几个关键点以BOARD变量区分三套目标并为每套目标设置对应的 RustCARGO_TARGET、SLINT_LIBRARY_CARGO_FLAGS、板级配置名BOARD_CONF_NAME共享配置来自 demos/zephyr-common/prj.conf其中开启了 C20CONFIG_CPPy、CONFIG_STD_CPP20y、CONFIG_REQUIRES_FULL_LIBCPPy、显示与输入子系统并通过CONFIG_INPUT_THREAD_PRIORITY_OVERRIDEyCONFIG_INPUT_THREAD_PRIORITY-1把输入线程优先级提到帧渲染之上避免渲染期间触摸事件无法及时出队强制启用 Slint 的 freestanding无标准库宿主环境与软件渲染器特性SLINT_FEATURE_FREESTANDING、SLINT_FEATURE_RENDERER_SOFTWARE、SLINT_FEATURE_SDF_FONTS资源以embed-for-software-renderer-with-sdf方式内嵌通过slint_target_sources(app ../ui/printerdemo.slint)将 UI 文件接入 Slint 构建系统自动生成 C 头文件printerdemo.h通过SLINT_ZEPHYR_PANEL_ROTATION与SLINT_ZEPHYR_RGB565_NATIVE_ENDIAN两个编译期宏向slint-zephyr.cpp传递面板安装方向与像素字节序信息。6.2 显示适配与软件渲染ZephyrPlatform与ZephyrWindowAdapter分别继承 Slint 的slint::platform::Platform与slint::platform::WindowAdapter。初始化时slint_zephyr_init(display)关闭背光display_blanking_off并注册平台ZephyrWindowAdapter::init_from通过display_get_capabilities查询屏幕分辨率、像素格式与双缓冲能力并打印到日志如Screen size: ...、Pixel format: RGB_565若当前像素格式不受支持则在RGB_565与RGB_565XZephyr 4.4 前称BGR_565见 slint-zephyr.cpp 的版本兼容宏之间切换必要时调用display_set_pixel_format之后为软件渲染器分配 RGB565 帧缓冲并调用m_renderer.set_rendering_rotation(...)应用渲染旋转。绘制流程在maybe_redraw()中软件渲染器只重绘脏区域得到矩形列表后逐块写入显示驱动当需要字节交换时会把每个 16 位像素的高低字节对调(*px 8) | (*px 8)用于解决驱动声明字节序与实际消费字节序不一致的问题对应 Zephyr 的 issue #53642 场景。日志会输出slint渲染耗时与write写屏耗时便于性能分析。6.3 旋转模型与触摸坐标映射源码用DisplayRotation结构描述面板、帧缓冲与 UI 三者之间的旋转关系区分两种旋转来源显示硬件如 PXP在送往面板途中对帧缓冲的旋转hardware以及软件渲染器绘制时对 UI 的旋转rendering。由此派生出帧缓冲尺寸、逻辑尺寸与触摸坐标转换touch_rotation并在map_touch_position中通过rotated()函数把面板坐标系下的触摸位置换算到逻辑坐标。这套模型正是文档中通用实现足以覆盖模拟器与显示 shield 驱动的源码体现。6.4 输入事件回调与事件循环触摸接入采用 Zephyr 4.x 的输入子系统当 device tree 中存在zephyr,touchchosen 节点时INPUT_CALLBACK_DEFINE注册zephyr_process_input_event回调slint-zephyr.cpp回调解析INPUT_ABS_X/INPUT_ABS_Y累积坐标在sync事件时根据按下/移动/抬起状态通过slint::invoke_from_event_loop把dispatch_pointer_press_event/dispatch_pointer_move_event/dispatch_pointer_release_event投递到事件循环线程执行保证触摸事件与渲染线程串行安全。事件循环run_event_loop的主体是更新定时器与动画 → 消费run_in_event_loop投递的任务队列 → 触发重绘 → 依据是否存在活跃动画 / 下一个定时器更新时间决定睡眠时长k_sem_take空闲时永久睡眠等待信号量唤醒实现零功耗轮询。6.5 应用侧数据驱动main.cpp 展示了 Slint 的 C 数据绑定用法自定义InkLevelModel继承slint::ModelInkLevel提供四种墨水的颜色与余量通过globalPrinterState().set_ink_levels(...)注入 UI用slint::VectorModelPrinterQueueItem接管打印队列注册on_start_job添加新任务、附带时间戳与on_cancel_job按下标取消回调用slint::Timer每秒推进队首任务的打印进度超过 100% 即出队从而驱动 UI 上的队列动画。七、小结与延伸阅读至此你应当能够独立完成 Printer Demo 在 Zephyr 上的三套目标构建native_sim 模拟器、NXP MIMXRT1170-EVKB、Renesas EK-RZ/A3M并理解 Slint 平台集成在 Zephyr 下的核心机制Device Tree 驱动的显示与触摸接入、RGB565 字节序适配、硬件/软件双层旋转模型、信号量驱动的事件循环以及通过Model与回调实现的数据绑定。进一步了解与本主题相关的仓库资源平台集成源码demos/zephyr-common/slint-zephyr.cpp、demos/zephyr-common/slint-zephyr.h共享 Kconfigdemos/zephyr-common/prj.confWest manifestdemos/zephyr-common/west.yamlZephyr v4.4.1、demos/zephyr-common/west-rza3m.yamlRenesaswip_rz分支板级配置与 overlaydemos/zephyr-common/boards应用入口与构建脚本demos/printerdemo/zephyr/main.cpp、demos/printerdemo/zephyr/CMakeLists.txtUI 定义demos/printerdemo/ui/printerdemo.slint如果你计划把 Slint 带到自己的 Zephyr 板卡可以从zephyr-common这套共享实现出发为你的 BOARD 在CMakeLists.txt中补充 Rust 目标与板级配置并在boards/下添加对应的.conf与.overlay重点核对显示驱动的像素格式、字节序与面板安装方向三项参数。【免费下载链接】slintSlint is an open-source declarative GUI toolkit to build native user interfaces for Rust, C, JavaScript, or Python apps.项目地址: https://gitcode.com/GitHub_Trending/sl/slint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考