当前位置: 首页 > java >正文

imx6ull UI开发

imx6ull UI开发简介

  • 在imx6ull上开发UI 应用
    • 硬件层面
    • 内核驱动
      • 显示设备
      • 文件描述符
      • 设备树
    • 软件
      • LVGL
        • 用户空间
        • 内核
      • QT

在imx6ull上开发UI 应用

在 Linux 系统中,应用程序需要通过操作 RGB LCD 的显存来实现在屏幕上显示字符、图像等信息。由于 Linux 采用严格的内存管理机制,显存必须经过申请才能使用。由于虚拟内存机制的存在,驱动程序设置的显存地址必须与应用程序访问的物理内存区域保持一致。

下面从硬件,内核 驱动和软件层面介绍整个流程。

硬件层面

imx6ull 的外设 LCDIF(Liquid Crystal Display Interface) 支持以下功能:

  • 具有异步并行MPU接口的显示器,用于与集成帧缓冲区进行命令和数据传输。
  • 支持动态图像且需要RGB接口模式(DOTCLK接口)的显示器。
  • 用于高速数据传输的VSYNC模式。
  • 接受ITU-R BT.656格式4的数字视频编码器。
    因此可以用这个外设来驱动 TFT(RGB 接口)

内核驱动

通常情况下, 芯片厂商和屏幕厂商已经在Linux内核中实现了驱动, 对于应用来说, 只需要根据实际的硬件来修改一些设置, 如 device tree里LCDIF的有关IO口, 屏幕的有关参数等。

显示设备

在Linux系统中,显示设备通常通过图形子系统来管理,主要有两种方式:直接使用帧缓冲(Framebuffer)和间接使用图形用户界面(GUI)系统,如X Window System或QT等。
帧缓冲是Linux内核提供的一个设备驱动接口,它允许用户空间程序直接访问显示硬件的帧缓冲区。通过/dev/fbX(X: 0~n)等设备文件,用户空间程序可以读写显示内存,从而实现图形显示。

文件描述符

/dev/fbX是字符设备, 文件描述符定义在drivers/video/fbdev/core/fbmem.c文件

设备树

  • imx6ul.dtsi: 设置 LCDIF的有关属性
lcdif: lcdif@21c8000 {compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";reg = <0x021c8000 0x4000>;interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,<&clks IMX6UL_CLK_LCDIF_APB>,<&clks IMX6UL_CLK_DUMMY>;clock-names = "pix", "axi", "disp_axi";status = "disabled";};
  • OEM工程的设备树: 设置屏幕相关的属性和pinctrl 有关信息
&lcdif {assigned-clocks = <&clks IMX6UL_CLK_LCDIF_PRE_SEL>;assigned-clock-parents = <&clks IMX6UL_CLK_PLL5_VIDEO_DIV>;pinctrl-names = "default";pinctrl-0 = <&pinctrl_lcdif_dat&pinctrl_lcdif_ctrl>;display = <&display0>;status = "okay";display0: display {bits-per-pixel = <24>;bus-width = <24>;display-timings {native-mode = <&timing0>;timing0: timing0 {clock-frequency =<60000000>;hactive = <1024>;vactive = <600>;hfront-porch = <160>;hback-porch = <160>;hsync-len = <10>;vback-porch = <23>;vfront-porch = <12>;vsync-len = <3>;hsync-active = <0>;vsync-active = <0>;de-active = <1>;pixelclk-active = <1>;};};};
};// backlight
pinctrl_pwm1: pwm1grp {fsl,pins = <MX6UL_PAD_LCD_DATA00__PWM1_OUT          0x110b0>;};// lcdif command line
pinctrl_lcdif_ctrl: lcdifctrlgrp {fsl,pins = <MX6UL_PAD_LCD_CLK__LCDIF_CLK		0x79MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC	0x79MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC	0x79MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE	0x79MX6UL_PAD_NAND_ALE__GPIO4_IO10          0x17059>;};
// lcdif data linepinctrl_lcdif_dat: lcdifdatgrp {fsl,pins = <MX6UL_PAD_LCD_DATA00__LCDIF_DATA00	0x79MX6UL_PAD_LCD_DATA01__LCDIF_DATA01	0x79MX6UL_PAD_LCD_DATA02__LCDIF_DATA02	0x79MX6UL_PAD_LCD_DATA03__LCDIF_DATA03	0x79MX6UL_PAD_LCD_DATA04__LCDIF_DATA04	0x79MX6UL_PAD_LCD_DATA05__LCDIF_DATA05	0x79MX6UL_PAD_LCD_DATA06__LCDIF_DATA06	0x79MX6UL_PAD_LCD_DATA07__LCDIF_DATA07	0x79MX6UL_PAD_LCD_DATA08__LCDIF_DATA08	0x79MX6UL_PAD_LCD_DATA09__LCDIF_DATA09	0x79MX6UL_PAD_LCD_DATA10__LCDIF_DATA10	0x79MX6UL_PAD_LCD_DATA11__LCDIF_DATA11	0x79MX6UL_PAD_LCD_DATA12__LCDIF_DATA12	0x79MX6UL_PAD_LCD_DATA13__LCDIF_DATA13	0x79MX6UL_PAD_LCD_DATA14__LCDIF_DATA14	0x79MX6UL_PAD_LCD_DATA15__LCDIF_DATA15	0x79MX6UL_PAD_LCD_DATA16__LCDIF_DATA16	0x79MX6UL_PAD_LCD_DATA17__LCDIF_DATA17	0x79MX6UL_PAD_LCD_DATA18__LCDIF_DATA18	0x79MX6UL_PAD_LCD_DATA19__LCDIF_DATA19	0x79MX6UL_PAD_LCD_DATA20__LCDIF_DATA20	0x79MX6UL_PAD_LCD_DATA21__LCDIF_DATA21	0x79MX6UL_PAD_LCD_DATA22__LCDIF_DATA22	0x79MX6UL_PAD_LCD_DATA23__LCDIF_DATA23	0x79>;};
  • 驱动
    搜索 imx6ul.dtsi里定义的 LCDIF 的 compatible , 可以找到 imx6ull LCDIF的驱动文件 drivers/video/fbdev/mxsfb.c

软件

分别以LVGL 和QT两种UI 开发框架角度介绍

LVGL

LVGL移植的详细介绍可以参考LVGL仓库。现简要介绍LVGL实现图形显示的框架流程。

用户空间
  • 使用 “mmap” 将framebuffer和 /dev/fbX 映射起来
  • 实现flush_cb
    –使用memcpy将 UI 数据copy 到 framebuffer
    –最后调用 lv_disp_flush_ready 表示显示刷新操作已完成
内核
  • /dev/fb0 是 Linux FrameBuffer 驱动导出的字符设备。
  • 用户空间通过 mmap 把 FrameBuffer 物理内存映射到用户空间指针(fbp)。
  • 用户空间写 fbp,实际上就是直接写显存。
  • 内核 FrameBuffer 驱动负责把这些数据同步到实际的显示控制器(如 i.MX6ULL 的 LCDIF 控制器)。
  • 显示控制器周期性地从显存读取数据,驱动 TFT 屏显示。
  • 内核 FrameBuffer 驱动的主要职责
    • 初始化 LCD 控制器(如设置分辨率、时序、显存地址等)。
    • 响应用户空间的 ioctl(如获取/设置分辨率、虚拟分辨率、offset 等)。
    • 提供 mmap 支持,让用户空间可以直接访问显存。
    • 处理可能的同步(如部分硬件需要显存 flush 或 cache 操作)。
  • 流程图
	LVGL (flush_cb)|vmemcpy/写入 fbp (mmap 映射的显存)|v/dev/fb0 (FrameBuffer 设备)|vLinux FrameBuffer 驱动 (fbmem.c, fbdev.c, mxsfb.c 等)|vLCD 控制器 (i.MX6ULL LCDIF)|vTFT 屏显示

QT

  • 移植QT 到 imx6ull
    • 移植完成后, 设置qt的环境变量 /etx/profile/

      把/dev/fb0指定为QT的显示设备

      export QT_QPA_PLATFORM=li nuxfb:tty=/dev/fb0
      
  • QT应用程序结合Qt的屏幕管理功能,通过QScreen类获取和操作多个显示设备
QList<QScreen *> screens = QGuiApplication::screens();for (QScreen *screen : screens) {qDebug() << "Found screen:" << screen->name();// 可以在这里进行其他屏幕相关的操作}
http://www.xdnf.cn/news/15620.html

相关文章:

  • 20250718-1-Kubernetes 应用程序生命周期管理-应用部署、升级、弹性_笔记
  • 短视频矩阵的时代结束了吗?
  • 【推理的思想】程序正确性证明(一):演绎推理基础知识
  • 网络编程(modbus,3握4挥)
  • 代码随想录算法训练营第二十四天
  • 包管理工具npm cnpm yarn的使用
  • 【47】MFC入门到精通——MFC编辑框 按回车键 程序闪退问题 ,关闭 ESC程序退出 问题
  • LVS集群
  • Python编程进阶知识之第二课学习网络爬虫(requests)
  • java-字符串和集合
  • JAVA中的Map集合
  • wireshark的常用用法
  • c#笔记之方法的形参列表以及方法重载
  • 测试学习之——Pytest Day3
  • 支付宝智能助理用户会话实时统计:Flink定时器与状态管理实战解析
  • Adam优化器
  • IMU噪声模型
  • 【数据结构】链表(linked list)
  • PostgreSQL 中的 pg_trgm 扩展详解
  • 命名实体识别15年研究全景:从规则到机器学习的演进(1991-2006)
  • Python 基础语法与数据类型(十三) - 实例方法、类方法、静态方法
  • SAP-ABAP:SAP的‘cl_http_utility=>escape_url‘对URL进行安全编码方法详解
  • Linux Swap区深度解析:为何禁用?何时需要?
  • 【程序地址空间】虚拟地址与页表转化
  • 基于Rust游戏引擎实践(Game)
  • 线上项目https看不了http的图片解决
  • 在分布式系统中,如何保证缓存与数据库的数据一致性?
  • docker 容器无法使用dns解析域名异常问题排查
  • springboot 整合spring-kafka客户端:SASL_SSL+PLAINTEXT方式
  • LeetCode20