linux驱动---视频播放采集架构介绍

lcd驱动框架(图像显示)

图像显示基础

1. 核心组件架构

用户空间
------------------------------------------
|  X11/Wayland |  FBDEV应用 | DRM/KMS应用 |
------------------------------------------
内核空间
------------------------------------------
|         DRM/KMS 框架                  |
|   (Direct Rendering Manager)         |
------------------------------------------
|         Framebuffer (FBDEV)          |
------------------------------------------
|          LCD控制器驱动                |
|         (各厂商的控制驱动)           |
------------------------------------------
硬件层
------------------------------------------
|       LCD面板 + 控制器硬件            |
------------------------------------------

2. 主要驱动框架

(1)Framebuffer (FBDEV) 框架
传统显示框架,较简单但功能有限
设备节点:/dev/fbX

struct fb_info {
    struct fb_var_screeninfo var;  // 可变参数(分辨率、像素格式等)
    struct fb_fix_screeninfo fix;  // 固定参数
    struct fb_ops *fbops;          // 操作函数集
    void *screen_base;             // 显存基地址
};

(2)DRM/KMS 框架
现代标准显示框架,支持硬件加速、多图层合成等
核心组件:

- KMS (Kernel Mode Setting): 负责显示模式设置
CRTC (扫描时序控制器)
–代表显示控制器,负责生成时序信号
–管理扫描输出和帧缓冲切换
–一个CRTC可以驱动一个或多个显示器
Encoder (输出编码器)
–将数字信号转换为特定接口信号(如HDMI, LVDS等)
–连接CRTC和Connector
Connector (物理连接器)
–代表物理显示接口(HDMI, DisplayPort等)
–检测显示器连接状态和EDID信息
Plane (图像层)
支持多层合成,通常包括:Primary Plane (主显示层)、Overlay Plane (叠加层)、Cursor Plane (光标层)

DRM (Direct Rendering Manage):提供核心基础设施和IOCTL接口
drm_device – 代表整个DRM设备,包含设备特定的操作函数集
drm_file – 代表一个用户空间打开的文件实例,跟踪每个进程的DRM状态
drm_mode – 管理显示模式和相关属性

- GEM (Graphics Execution Manager): 内存管理

  • Display Pipeline: 由多个组件组成:
    CRTC (扫描时序控制器)
    Encoder (输出编码器)
    Connector (物理连接器)
    Plane (图像层)

3. LCD 控制器驱动开发

(1)基于 FBDEV 的实现

static int lcd_fb_probe(struct platform_device *pdev)
{
    // 1. 分配fb_info
    struct fb_info *info = framebuffer_alloc(sizeof(struct lcd_data), &pdev->dev);
    
    // 2. 设置操作函数集
    static struct fb_ops lcd_fb_ops = {
        .owner = THIS_MODULE,
        .fb_set_par = lcd_set_par,
        .fb_setcolreg = lcd_setcolreg,
        .fb_fillrect = cfb_fillrect,  // 使用软件实现
        .fb_imageblit = cfb_imageblit,
    };
    info->fbops = &lcd_fb_ops;
    
    // 3. 配置显示参数
    info->var.xres = 800;
    info->var.yres = 480;
    info->var.bits_per_pixel = 32;
    
    // 4. 分配显存
    info->screen_base = dma_alloc_wc(&pdev->dev, size, &dma_handle, GFP_KERNEL);
    info->fix.smem_start = dma_handle;
    info->fix.smem_len = size;
    
    // 5. 注册framebuffer
    register_framebuffer(info);
}

(2)基于 DRM/KMS 的实现

static const struct drm_driver lcd_drm_driver = {
    .driver_features = DRIVER_MODESET | DRIVER_GEM,
    .gem_free_object_unlocked = lcd_gem_free_object,
    .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
    .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
    .gem_prime_import = drm_gem_prime_import,
};

static int lcd_drm_probe(struct platform_device *pdev)
{
    // 1. 创建DRM设备
    drm_dev = drm_dev_alloc(&lcd_drm_driver, &pdev->dev);
    
    // 2. 初始化硬件
    lcd_hw_init(drm_dev);
    
    // 3. 设置显示管道
    ret = lcd_create_pipe(drm_dev, &pipe);
    
    // 4. 注册DRM设备
    drm_dev_register(drm_dev, 0);
}
static const struct drm_crtc_funcs my_crtc_funcs = {
    .destroy = drm_crtc_cleanup,
    .set_config = drm_atomic_helper_set_config,
    .page_flip = drm_atomic_helper_page_flip,
    .reset = drm_atomic_helper_crtc_reset,
    .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
    .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
};

static const struct drm_crtc_helper_funcs my_crtc_helper_funcs = {
    .atomic_check = my_crtc_atomic_check,
    .atomic_begin = drm_atomic_helper_crtc_begin,
    .atomic_flush = drm_atomic_helper_crtc_flush,
    .atomic_enable = my_crtc_atomic_enable,
    .atomic_disable = my_crtc_atomic_disable,
};

static int my_kms_init(struct drm_device *ddev)
{
    struct my_drm_device *priv = ddev->dev_private;
    struct drm_plane *primary;
    struct drm_crtc *crtc;
    struct drm_encoder *encoder;
    struct drm_connector *connector;
    int ret;
    
    /* 创建主平面 */
    ret = drm_plane_helper_add(&priv->primary,
            &my_primary_helper_funcs);
    
    /* 创建CRTC */
    ret = drm_crtc_init_with_planes(ddev, &priv->crtc,
            &priv->primary, NULL, &my_crtc_funcs, NULL);
    drm_crtc_helper_add(&priv->crtc, &my_crtc_helper_funcs);
    
    /* 创建Encoder */
    ret = drm_encoder_init(ddev, &priv->encoder,
            &my_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL);
    
    /* 创建Connector */
    ret = drm_connector_init(ddev, &priv->connector,
            &my_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
    drm_connector_helper_add(&priv->connector,
            &my_connector_helper_funcs);
    
    /* 连接Encoder和Connector */
    drm_connector_attach_encoder(&priv->connector,
            &priv->encoder);
    
    /* 连接CRTC和Encoder */
    drm_mode_config_reset(ddev);
    
    return 0;
}

显存管理 (GEM)

static const struct drm_gem_object_funcs my_gem_funcs = {
    .free = my_gem_free_object,
    .print_info = my_gem_print_info,
    .get_sg_table = my_gem_get_sg_table,
    .vmap = my_gem_vmap,
    .vunmap = my_gem_vunmap,
};

static int my_gem_create(struct drm_device *ddev,
        size_t size, struct drm_gem_object **obj)
{
    struct my_gem_object *my_obj;
    
    my_obj = kzalloc(sizeof(*my_obj), GFP_KERNEL);
    if (!my_obj)
        return -ENOMEM;
    
    drm_gem_private_object_init(ddev, &my_obj->base, size);
    
    my_obj->base.funcs = &my_gem_funcs;
    
    *obj = &my_obj->base;
    return 0;
}

4. 设备树配置

典型 LCD 控制器设备树节点:

lcdc: lcd-controller@01c0c000 {
    compatible = "allwinner,sun8i-a33-tcon";
    reg = <0x01c0c000 0x1000>;
    interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_TCON0>;
    clock-names = "ahb", "tcon-ch0";
    resets = <&ccu RST_BUS_TCON0>;
    
    ports {
        #address-cells = <1>;
        #size-cells = <0>;
        
        tcon0_in: port@0 {
            reg = <0>;
            tcon0_in_drc0: endpoint {
                remote-endpoint = <&drc0_out_tcon0>;
            };
        };
        
        tcon0_out: port@1 {
            reg = <1>;
            tcon0_out_hdmi: endpoint {
                remote-endpoint = <&hdmi_in_tcon0>;
            };
        };
    };
};

5. 调试方法

常用调试工具和技巧:

# 查看FBDEV信息
cat /proc/fb
fbset -i

# DRM调试
cat /sys/kernel/debug/dri/0/state

# 内核日志过滤
dmesg | grep -E "drm|fb|lcd"

# 显示当前显示模式
modetest -M <driver_name>

5. 性能优化方向

  • 异步页面翻转:减少显示延迟
  • DMA传输:降低CPU占用
  • 硬件加速:利用显示控制器的旋转、缩放功能
  • 显存压缩:使用AFBC等压缩技术
  • 自适应刷新率:如支持VRR/FreeSync
  • 多平面合成:利用硬件叠加层

camera驱动框架(图像采集)

1. 整体架构

用户空间
------------------------------------------
| 应用层 (GStreamer, OpenCV, 自定义应用) |
------------------------------------------
|           V4L2 用户空间 API            |
| (libv4l2, v4l-utils, media-ctl)       |
------------------------------------------
内核空间
------------------------------------------
|            V4L2 子系统框架             |
| (Video for Linux 2)                   |
------------------------------------------
|            Media Controller API        |
| (管理复杂的多媒体设备拓扑)             |
------------------------------------------
|           Camera 传感器驱动            |
| (如 ov5640, imx219, 等)               |
------------------------------------------
|           ISP 图像处理驱动             |
| (可选,用于高端摄像头处理)             |
------------------------------------------
硬件层
------------------------------------------
|       Camera 传感器 + 接口硬件         |
| (MIPI CSI-2, Parallel, USB 等)        |
------------------------------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值