• LCD驱动程序(一)


    LCD显示原理:

    在JZ2440上,想要让LCD显示,需要几个部分1、LCD硬件 2、开发板上的LCD控制器 3、SDRAM内存存放数据FramBuffer 4、可能还需要一个调色板(实际上是一块内存,里面数据可以组成各种颜色)

    显示原理:在开发板上操作LCD控制器,使得开发板向SDRAM内存里去除数据发送通过LCD数据引脚发送到LCD屏上。

    具体硬件操作步骤:

    1、LCD引脚的连接,根据LCD原理图配置引脚

    2、根据LCD控制器手册设置LCD控制器

    3、分配显存,并把地址告诉LCD控制器

    需要调色板的情况:LCD数据线少,比如16位数据线无法显示完全部的颜色组成,只能当做一个索引作用,指向调色板上正真的地址颜色空间

     

    LCD液晶屏显示原理:

         可以想象一下LCD后面有一个电子枪,电子枪的作用就是将从FramBuffer内存里获取到的颜色,一个一个的打到LCD屏幕上,怎么打?顺序为:

    以液晶屏左上角开始,从左往右开始,一个一个颜色点打上去,打到后面没有地方的时候,又开始换行又从左往右打;就比如你打开一个记事本按住某个字符符号不懂,

    它会不断的在记事本上输出字母,当到边界是开始换行输出。直到输出完为止。当然LCD液晶屏上空间有限,打的速率非常快的,是你感觉是图像是突然就出现到你

    前面来一样。

    ------------------------------------------------------------------------------------------------------------------------------------

    LCD驱动程序的框架

    满足字符设备驱动程序的框架

    1、应用程序通过open、read、write等函数进入内核进而调用dri_open、dri_read、dir_write等函数,通过设备好找到LCD驱动的注册id,进而

    进入到到驱动函数的File_operation结构体函数,对硬件进行操作,主要框架如图所示。


    LCD驱动程序

    假设
    app: open("/dev/fb0", ...) 主设备号: 29, 次设备号: 0
    --------------------------------------------------------------
    kernel:
    fb_open
    int fbidx = iminor(inode);
    struct fb_info *info = = registered_fb[0];

    app: read()
    ---------------------------------------------------------------
    kernel:
    fb_read
    int fbidx = iminor(inode);
    struct fb_info *info = registered_fb[fbidx];
    if (info->fbops->fb_read)
    return info->fbops->fb_read(info, buf, count, ppos);

    src = (u32 __iomem *) (info->screen_base + p);
    dst = buffer;
    *dst++ = fb_readl(src++);
    copy_to_user(buf, buffer, c)

    问1. registered_fb在哪里被设置?
    答1. register_framebuffer

    怎么写LCD驱动程序?
    1. 分配一个fb_info结构体: framebuffer_alloc
    2. 设置
    3. 注册: register_framebuffer
    4. 硬件相关的操作

    ----------------------------------------------------------------------------------------------------------------

    对LCD初始化:主入口函数要做的事情

    1. 分配一个fb_info结构体: framebuffer_alloc

    struct fb_info {   

    ........

    struct fb_var_screeninfo var; /* Current var  可变参数*/
    struct fb_fix_screeninfo fix; /* Current fix 固定参数*/

    ........

    }

    /* 1. 分配一个fb_info */
    s3c_lcd = framebuffer_alloc(0, NULL);

    2. 设置

    /* 2. 设置 */
    /* 2.1 设置固定的参数 Current fix*/

    struct fb_fix_screeninfo {
    char id[16]; /* identification string eg "TT Builtin" */
    unsigned long smem_start; /* Start of frame buffer mem */
    /* (physical address) */
    __u32 smem_len; /* Length of frame buffer mem */
    __u32 type; /* see FB_TYPE_* */
    __u32 type_aux; /* Interleave for interleaved Planes */
    __u32 visual; /* see FB_VISUAL_* */
    __u16 xpanstep; /* zero if no hardware panning */
    __u16 ypanstep; /* zero if no hardware panning */
    __u16 ywrapstep; /* zero if no hardware ywrap */
    __u32 line_length; /* length of a line in bytes */
    unsigned long mmio_start; /* Start of Memory Mapped I/O */
    /* (physical address) */
    __u32 mmio_len; /* Length of Memory Mapped I/O */
    __u32 accel; /* Indicate to driver which */
    /* specific chip/card we have */
    __u16 reserved[3]; /* Reserved for future compatibility */
    };

    strcpy(s3c_lcd->fix.id, "mylcd");
    s3c_lcd->fix.smem_len = 240*320*16/8;
    s3c_lcd->fix.type = FB_TYPE_PACKED_PIXELS;
    s3c_lcd->fix.visual = FB_VISUAL_TRUECOLOR; /* TFT */
    s3c_lcd->fix.line_length = 240*2;


    /* 2.2 设置可变的参数Current var */

                 

    struct fb_var_screeninfo {
    __u32 xres; /* visible resolution */
    __u32 yres;
    __u32 xres_virtual; /* virtual resolution */
    __u32 yres_virtual;
    __u32 xoffset; /* offset from virtual to visible */
    __u32 yoffset; /* resolution */

    __u32 bits_per_pixel; /* guess what */
    __u32 grayscale; /* != 0 Graylevels instead of colors */

    struct fb_bitfield red; /* bitfield in fb mem if true color, */
    struct fb_bitfield green; /* else only length is significant */
    struct fb_bitfield blue;
    struct fb_bitfield transp; /* transparency */

    __u32 nonstd; /* != 0 Non standard pixel format */

    __u32 activate; /* see FB_ACTIVATE_* */

    __u32 height; /* height of picture in mm */
    __u32 width; /* width of picture in mm */

    __u32 accel_flags; /* (OBSOLETE) see fb_info.flags */

    /* Timing: All values in pixclocks, except pixclock (of course) */
    __u32 pixclock; /* pixel clock in ps (pico seconds) */
    __u32 left_margin; /* time from sync to picture */
    __u32 right_margin; /* time from picture to sync */
    __u32 upper_margin; /* time from sync to picture */
    __u32 lower_margin;
    __u32 hsync_len; /* length of horizontal sync */
    __u32 vsync_len; /* length of vertical sync */
    __u32 sync; /* see FB_SYNC_* */
    __u32 vmode; /* see FB_VMODE_* */
    __u32 rotate; /* angle we rotate counter clockwise */
    __u32 reserved[5]; /* Reserved for future compatibility */
    };

    s3c_lcd->var.xres = 240;
    s3c_lcd->var.yres = 320;
    s3c_lcd->var.xres_virtual = 240;
    s3c_lcd->var.yres_virtual = 320;
    s3c_lcd->var.bits_per_pixel = 16;

    /* RGB:565 */
    s3c_lcd->var.red.offset = 11;
    s3c_lcd->var.red.length = 5;

    s3c_lcd->var.green.offset = 5;
    s3c_lcd->var.green.length = 6;

    s3c_lcd->var.blue.offset = 0;
    s3c_lcd->var.blue.length = 5;

    s3c_lcd->var.activate = FB_ACTIVATE_NOW;


    /* 2.3 设置操作函数 */

    s3c_lcd->fbops              = &s3c_lcdfb_ops;
    /* 2.4 其他的设置 */

    s3c_lcd->screen_size   = 240*324*16/8;

     3. 硬件相关的操作 

    /* 3.1 配置GPIO用于LCD */
    /* 3.2 根据LCD手册设置LCD控制器, 比如VCLK的频率等 */
    /* 3.3 分配显存(framebuffer), 并把地址告诉LCD控制器 */


    4. 注册: register_framebuffer

    /* 4. 注册 */
    register_framebuffer(s3c_lcd);

    剩余的对s3c_lcdfb_ops的配置以及硬件配置查看LCD驱动(二)

  • 相关阅读:
    娃娃机 解题报告
    ecshop
    多字节字符串 函数
    电商中设置满包邮,满减等促销搞活动;电商平台同步到第三方,日志记录
    PHP文件操作
    apache重写字段详细说明
    httpc服务器错误类型大全
    正则入门简易
    php100 编程小技巧
    memcache
  • 原文地址:https://www.cnblogs.com/yihujiu/p/6390724.html
Copyright © 2020-2023  润新知