LCD设备驱动的体系结构

    xiaoxiao2025-09-13  870

    Linux帧缓冲设备驱动结构

    下面结构描述了显示卡的特性:    __u32 是表示 unsigned 不带符号的 32 bits 的数据类型,其余类推。这是 Linux 内核中所用到的数据类型,如果是开发用户空间(user-space)的程序,可以根据具体计算机平台的情况,用 unsigned long 等等来代替 Struct fb_var_screeninfo 可变参数结构体,LCD驱动可以在运行中改变的参数放在此处 可以使用ioctl()函数进行设置

     struct fb_var_screeninfo { __u32 xres;   

    __u32 yres; 

      // 可见屏幕大小,即实际液晶屏的大小 __u32 xres_virtual;  __u32 yres_virtual;     // 虚拟屏幕大小,可以做一个大的显示缓冲区,仅显示 其中的一部分  __u32 xoffset;  // 虚拟到可见之间的偏移坐标  __u32 yoffset;     __u32 bits_per_pixel;// 每像素比特位数  __u32 grayscale; // !=0 灰度代替颜色显示

    struct fb_bitfield red;   struct fb_bitfield green;  struct fb_bitfield blue; struct fb_bitfield transp;      // fb缓存的RGB位域,包括颜色占几位,偏移几位 __u32 nonstd; /* != 0 非标准像素格式 */ __u32 activate;  /* see FB_ACTIVATE_*/ __u32 height; /* height of picture in mm */ __u32 width; /* width of picture in mm  */ __u32 accel_flags;/* acceleration flags (hints) */ __u32 pixclock; /* 像素时钟(ps) */ __u32 left_margin;/* 行切换:从同步到绘图之间的延*/ __u32 right_margin;/* 行切换:从绘图到同步之间的延时 */ __u32 upper_margin;/* 帧切换:从同步到绘图之间的延*/ __u32 lower_margin;/* 帧切换:从绘图到同步之间的延时 */  __u32 hsync_len; /* 水平同步的长度*/ __u32 vsync_len; /* 垂直同步的长度*/ __u32 sync;  /* see FB_SYNC_*  */ __u32 vmode;  /* see FB_VMODE_*  */ __u32 reserved[6];   /* 保留 */ };

    前几个成员决定了分辨率。xres和yres是在屏幕上可见的实际分辨率,在通常的vga模式将为640和400(也许是480,by highbar)。

    *res-virtual决定了构建屏幕时视频卡读取屏幕内存的方式。当实际的垂直分辨率为400,虚拟分辨率可以是800。这意味着800行的数据被保存在了屏幕内存区中。因为只有400行可以被显示,决定从那一行开始显示就是你的事了。

    这个可以通过设置*offset来实现。给yoffset赋0将显示前400行,赋35将显示第36行到第435行,如此重复。这个功能在许多情形下非常方便实用。它可以用来做双缓冲。双缓冲就是你的程序分配了可以填充两个屏幕的内存。将offset设为0,将显示前400行(假设是标准的vga),同时可以秘密的在400行到799行构建另一个屏幕,当构建结束时,将yoffset设为400,新的屏幕将立刻显示出来。现在将开始在第一块内存区中构建下一个屏幕的数据,如此继续。这在动画中十分有用。

    另外一个应用就是用来平滑的滚动整个屏幕。就像在前面屏幕中一样,在内存分配800行的空间。每隔10毫秒设定一个定时器(timer,见man settimer和man signal / man sigaction),将offset设为1或是比上次更多,瞧,你看到了一个平滑滚动的屏幕。确保你的信号(signal)不要因为最佳输出的原因被信号处理程序阻塞。

    将bits_per_pixel 设为1,2,4,8,16,24或32来改变颜色深度(color depth)。不是所有的视频卡和驱动都支持全部颜色深度。当颜色深度改变,驱动将自动改变fb-bitfields。这些指出,在一个特定的颜色基准上,多少和哪些比特被哪种颜色使用。如果bits-per-pixel小于8,则fb-bitfields将无定义而且颜色映射将启用。

    在fb-var-screeninfo结构结尾的定时的设置是当你选择一个新的分辨率的时候用来设定视频定时的。(EXAMINE AND EXPLAIN TIMINGS! )

     

    struct fb_fix_screeninfo   LCD驱动固定参数,在运行过程中是不允许改变的,一般在初始化驱动的时候进行赋值 如LCD缓冲区首地址等  

    struct fb_fix_screeninfo { char id[16];/* 字符串形式的标识符*/ unsigned long smem_start; /*fb缓存开始的位置*/ __u32 smem_len; /* fb缓存的长度 */ __u32 type;       /* see FB_TYPE_* */ __u32 type_aux;  /* 分界 */ __u32 visual; /* see FB_VISUAL_* */  __u16 xpanstep;/*如果没有硬件panning,赋0 */ __u16 ypanstep; __u16 ywrapstep;

    __u32 line_length;/* 一行的字节数    */ unsigned long mmio_start;/*内存映射IO的开始地址 */ __u32 mmio_len; /* 内存映射IO的长度  */ __u32 accel;   __u16 reserved[3];/*保留*/ };

    struct fb_cmap 调色板结构体,记录一个调色板的颜色信息

    struct fb_cmap {  __u32 start; /* 第一个元素入口*/  __u32 len;       /* 元素的数量 */  __u16 *red;  /* 颜色值 */  __u16 *green;  __u16 *blue;  __u16 *transp;  /* transparency, can be NULL */ };

    颜色值是一个缓冲区,可以有多个颜色,len即表示总共有多少个颜色值

    struct fb_info  帧缓冲设备结构体,每个结构体对应一个帧缓冲设备 LCD就是一个帧缓冲设备 有的显卡支持多个屏幕,就有多个帧缓冲设备 包含上了帧缓冲设备所有的信息 struct fb_info {    char modename[40];  /* 标识符*/    kdev_t node;    int flags;    int open;              /* 打开标志位 */ #define FBINFO_FLAG_MODULE 1 /* 低层次驱动是模块 */    struct fb_var_screeninfo var;  /* 可变参数 */    struct fb_fix_screeninfo fix;  /* 固定参数*/    struct fb_monspecs monspecs;                               /* Current Monitor specs */    struct fb_cmap cmap;           /* 颜色表 */    struct fb_ops *fbops;         /*函数集 */ char *screen_base;                                 /* 虚拟基地址 */ struct display *disp;       /* initial display variable */ struct vc_data *display_fg;     /* Console visible on this display */ char fontname[40]; /* 默认字体名字 */ devfs_handle_t devfs_handle;/* 设备句柄  */ devfs_handle_t devfs_lhandle;    /* 设备句柄软连接  */ void *pseudo_palette;                /* 虚拟调色板,用于真彩色没有调色板情况 */ void *par;  }; struct s3c2410fb_mach_info  LCD屏的具体信息,包括屏幕大小,时序关系等 如果整个系统平台要是另外一块LCD屏,只需要根据LCD屏的特性,填写这个结构体即可 struct s3c2410fb_mach_info {  u_long  pixclock; // 像素时钟

     u_short  xres;     // 屏幕大小  u_short  yres;  u_char  bpp;                            // 几位表示一个像素  u_char  hsync_len; // 行长度  u_char  left_margin; /* 行切换:从同步到绘图之间的延*/  u_char  right_margin; /* 行切换:从绘图结束到同步之间的延时 */ u_char  vsync_len; // 帧同步长度 u_char  upper_margin; /* 帧切换:从同步到绘图之间的延时*/ u_char  lower_margin; /* 帧切换:从绘图结束到同步之间的延时*/ u_char  sync;

    u_int  cmap_grayscale:1,  // 颜色模式        cmap_inverse:1,    cmap_static:1,           unused:29;     u_int  state;

     struct s3c2410fb_lcd_reg reg;  // 寄存器设置 }; static struct fb_ops s3c2410fb_ops = {  owner:  THIS_MODULE,  fb_get_fix: s3c2410fb_get_fix,  fb_get_var: s3c2410fb_get_var,  fb_set_var: s3c2410fb_set_var,  fb_get_cmap: s3c2410fb_get_cmap,  fb_set_cmap: s3c2410fb_set_cmap, }; static int  s3c2410fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)

    功能:得到fix结构体数据信息 参数: fix 得到数据的保存地址 Con 当前控制台序号 Info 帧缓冲设备结构体 static int s3c2410fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) 功能:得到var结构体数据 参数: var:保存得到的数据 Con:当前控制台序号 Info:帧缓冲设备结构体 static int s3c2410fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) 功能:设置var结构体数据 参数: var:需要设置的数据 Con:当前控制台序号 Info:帧缓冲设备结构体 static int s3c2410fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) 功能:得到调色板颜色信息 参数: cmap: 存放调色板信息 Kspc:0直接拷贝,1 使用copy_to_user拷贝 Con: 当前控制台序号 Info:帧缓冲设备结构体

    static int s3c2410fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) 功能:得到调色板颜色信息 参数: cmap: 需要设置的调色板信息 Kspc:0直接拷贝,1 使用copy_to_user拷贝 Con: 当前控制台序号 Info:帧缓冲设备结构体 LCD驱动主要的任务是实现info这个结构体和ops其中的函数 LCD驱动并没有关于数据传输的函数,仅设置各种参数,具体的数据传输由上层实现,具体见fbmem.c LCD驱动最烦琐的地方是各种数据结构之间的赋值,因此深入理解各种数据结构非常关键

    转载请注明原文地址: https://ju.6miu.com/read-1302620.html
    最新回复(0)