LCD驱动编写流程

嵌入式 Linux— LCD 与 Framebuffer 驱动开发详解


一、LCD 显示基础知识

1.1 分辨率(Resolution)

LCD 显示器由一个个像素(Pixel)组成,分辨率表示横向像素 × 纵向像素的总量:

  • 示例:

    • 800×480 表示一行 800 像素,共 480 行
    • 1920×1080(1080p) 是高清分辨率

1.2 像素格式(Pixel Format)

每个像素通常由 RGB 三个颜色通道 + 可选的 Alpha 通道组成:

  • 常见格式:

    • RGB565:16 bit(R:5, G:6, B:5)
    • RGB888:24 bit(R:8, G:8, B:8)
    • ARGB8888:32 bit(包含透明通道)
  • 每像素字节数决定了显存大小和传输带宽


1.3 LCD 接口类型(以 NXP i.MX6ULL 为例)

i.MX6ULL 支持的接口为 并行 RGB 接口

  • RGB 数据线:24 位(每种颜色各占 8 bit)
    在这里插入图片描述

  • 控制信号线

    • HSYNC:行同步
    • VSYNC:帧同步
    • DE(Data Enable):数据使能
    • PCLK:像素时钟,用于采样像素数据

通常需配置约 28 根引脚。


1.4 显存(Framebuffer)

Framebuffer 是存储当前图像像素数据的内存区域,供 LCD 控制器读取并显示。

  • 显存大小 = 宽 × 高 × 每像素字节数
    示例:800 × 480 × 4(ARGB8888)= 1.5 MB

  • 驱动会将显存通过 mmap 映射给用户态程序


1.5 LCD 时序参数

LCD 一帧图像由若干行构成,每行数据也有对应同步信号:

📌 水平时序(每行)
  • HSYNC:行开始
  • HBP(Back Porch):同步后延时
  • HFP(Front Porch):数据发送完后延时
  • HActive:一行有效像素
📌 垂直时序(每帧)
  • VSYNC:帧开始
  • VBPVFP:上下延时
  • VActive:有效显示的行数

🧮 帧率计算公式

PCLK = (HActive + HBP + HFP + HSYNC) × (VActive + VBP + VFP + VSYNC) × 帧率

1.6 LCD模型

在这里插入图片描述

1.7 LCD控制器时序图

在这里插入图片描述

二、LCD 驱动原理与设备树配置

2.1 驱动控制器:eLCDIF

  • i.MX6ULL 内部集成 Enhanced LCD Interface (eLCDIF) 控制器
  • 功能包括:数据缓冲、格式转换、同步信号生成

2.2 设备树配置关键项

1)IOMUXC:引脚复用

为 LCD 分配所需引脚:

pinctrl_lcd: lcdgrp {
    fsl,pins = <
        MX6UL_PAD_LCD_CLK__LCDIF_CLK     0x79
        MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE   0x79
        ...
    >;
};
2)LCD 控制器节点配置
lcdif: lcdif@021c8000 {
    compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
    reg = <0x021c8000 0x4000>;
    ...
    display = <&display0>;
};
3)display-timings 子节点(核心部分)
display0: display0 {
    bits-per-pixel = <32>;
    bus-width = <24>;

    display-timings {
        native-mode = <&timing0>;
        timing0: timing0 {
            clock-frequency = <33264000>;
            hactive = <800>;
            vactive = <480>;
            hback-porch = <40>;
            hfront-porch = <40>;
            vback-porch = <29>;
            vfront-porch = <13>;
            hsync-len = <48>;
            vsync-len = <3>;
            ...
        };
    };
};
4)背光控制节点(PWM/GPIO)
backlight: backlight {
    compatible = "pwm-backlight";
    pwms = <&pwm1 0 5000000>;
    brightness-levels = <0 64 128 255>;
    default-brightness-level = <2>;
};

三、Framebuffer 子系统与驱动框架

3.1 什么是 Framebuffer

Framebuffer 是 Linux 提供的一种显示抽象接口,表现为字符设备 /dev/fb0

  • 用户可以直接读写 framebuffer,显示图像
  • 内核通过 fb_info 与硬件交互

3.2 fb_info 结构体关键字段

struct fb_info {
    struct fb_var_screeninfo var; // 分辨率、像素格式
    struct fb_fix_screeninfo fix; // 显存起始地址、长度
    u8 *screen_base;              // 显存虚拟地址
    struct fb_ops *fbops;         // 操作函数集
};

3.3 fb_ops 操作函数集

struct fb_ops {
    int (*fb_open)(...);
    ssize_t (*fb_read)(...);
    ssize_t (*fb_write)(...);
    int (*fb_ioctl)(...);
    void (*fb_fillrect)(...);     // 填充矩形
    void (*fb_imageblit)(...);    // 显示位图
};

四、自定义 Framebuffer 驱动开发流程

Step 1:分配 fb_info

struct fb_info *info = framebuffer_alloc(0, &pdev->dev);

Step 2:配置变量参数

info->var.xres = 800;
info->var.yres = 480;
info->var.bits_per_pixel = 32;

Step 3:申请显存并映射

info->screen_base = dma_alloc_wc(...);  // 物理显存
info->fix.smem_start = virt_to_phys(info->screen_base);

Step 4:设置 fb_ops

info->fbops = &my_fb_ops;

Step 5:注册 framebuffer

register_framebuffer(info);

五、LCD 控制器初始化流程

在 LCD 控制器的初始化函数中需完成以下步骤:

  1. IO 引脚配置(复用 + 驱动能力)
  2. 设置时钟源:分频后供 LCDIF 控制器
  3. 设置同步参数(VSYNC/HSYNC/Porch 等)
  4. 绑定显存地址(从 Framebuffer 获取物理地址)
  5. 启动控制器输出数据

六、用户空间访问 framebuffer 原理

6.1 方式一:直接写入

cat image.raw > /dev/fb0

6.2 方式二:mmap 映射

fb = open("/dev/fb0", O_RDWR);
fbp = mmap(NULL, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
memcpy(fbp, buffer, screensize);  // 直接写入显存

七、常见问题与调试建议

问题检查点
屏幕无显示背光电源是否开启?
图像错位时序参数是否匹配?
色彩异常像素格式是否一致?
无法写入 /dev/fb0权限、驱动是否注册?

工具命令推荐:

fbset          # 查看 framebuffer 参数
cat /dev/fb0 > dump.raw  # 导出显存数据
hexdump /dev/fb0         # 查看像素数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值