编写基于Linux的lcd驱动

看lcd驱动好几天了,一直找不到突破点,感觉无从下手。今天看了一篇介绍lcd驱动编写的文章,写的很详细,对理解frambuffer以及lcd驱动很有帮助。但是英文的,多多少少有点不习惯,翻译下来留着以后复习的时候再看就方便了。

摘要:
    本文详细描述怎样编写linux frambuffer LCD 驱动程序
    1. LCD 驱动/设备/控制器
    2. linux frambuffer 驱动
        2.1 为什么要用frambuffer?
        2.2 什么是frambuffer设备?
        2.3 怎样编写frambuffer驱动程序?
    3. linux frambuffer 驱动源码分析
        3.1 fb.h
        3.2 fbmen.c
    4. LCD 控制器驱动程序结构
        4.1 为lcd显存分配内存
        4.2 实现 fb_ops 功能函数


1.LCD 驱动/设备/控制器
    除了LCD设备的datasheet,还有两个关于LCD的非常不错的书,并且他们都是中文的。一本叫:《液晶显示技术》,另外一本叫《液晶显示器件》。这两本书详细介绍了LCD的知识,包括对硬件的操作,LCD的底层编程等。这两本书对设计LCD模块和底层编程都很有帮助。

2. linux frambuffer 驱动
2.1 为什么要用frambuffer?

如果我们的系统要用GUI(图形界面接口),比如minigui,MicroWindows.这时LCD设备驱动程序就应该编写成frambuffer接口,而不是编写成仅仅操作底层的LCD控制器接口。
2.2 什么是frambuffer设备?
   frambuffer设备层是对图像设备的一种抽象,它代表了视频硬件的帧缓存,使得应用程序通过定义好的接口就可以访问硬件。所以应用程序不需要考虑底层的(寄存器级)的操作。应用程序对设备文件的访问一般在
/dev 目录,如 /dev/fb*。更多关于frambuffer设备的详细信息请阅读内核文档:linux /Documentation /fb /framebuffer.txt and linux /Documentation /fb /interal.txt 
2.3 怎样编写frambuffer驱动程序?
   关于如何编写frambuffer设备驱动,有很多参考资料。你可以在/linux-fbdev.sourceforge.net /HOWTO /index.html网站上阅读“Linux Frame buffer Driver Writing HOWTO”。
但是我认为这篇文章过于简短。所以分析内核相关部分的源码才是王道。
3.linux frambuffer 驱动源码分析
linux中frambuffer接口的所有功能实现都包括在下面两个文件中
1) linux/include/linux/fb.h 
2) linux/drivers/video/fbmem.c 
下面详细分析这两个文件: 
3.1 fb.h 
所有frambuffer重要的结构体都定义在这个文件中。下面逐个分析他们:
1) fb_var_screeninfo 
这个结构用来描述一个显卡可以被设置的特性,在fb_var_screeninfo结构体里有我们设备需要的,比如分辨率等信息。

 

struct fb_var_screeninfo {       __u32 xres;         /* 视口水平分辨率      */       __u32 yres;       __u32 xres_virtual;     /* 虚拟屏幕水平分辨率        */       __u32 yres_virtual;       __u32 xoffset;          /* 偏移视口与虚拟屏幕水平分辨率偏移 */       __u32 yoffset;                    __u32 bits_per_pixel;       /* 像素的位数            */       __u32 grayscale;        /* 灰度标志,如果为1代表是灰度 */          struct fb_bitfield red;     /* 如果是真彩色,这个是颜色位,如果不是那么只有结构的大小重要,其他表示的信息无关紧要 */       struct fb_bitfield green;          struct fb_bitfield blue;       struct fb_bitfield transp;  /* 透明度      */            __u32 nonstd;           /* 非标准颜色表示标志位 */       __u32 activate;         /* 参照 FB_ACTIVATE_*     */       __u32 height;           /* 在内存地址空间的长度    */       __u32 width;            /* 在内存地址空间的宽度     */          __u32 accel_flags;      /* (不用了) 参照 fb_info.flags */          /* 时序: 以下所有的值单位都是pixclock, 当然除了pixclock */       __u32 pixclock;         /* 每秒像素值 */       __u32 left_margin;      /* 从sync信号到显示真正的像素的时钟个数 */       __u32 right_margin;     /* 从真正显示像素到sync信号的时钟个数  */       __u32 upper_margin;     /* 上面两个是针对列像素的,这个针对行的   */       __u32 lower_margin;       __u32 hsync_len;        /* 水平sync信号的长度  */       __u32 vsync_len;        /* 垂直sync信号的长度  */       __u32 sync;         /* 参照 FB_SYNC_*     */       __u32 vmode;            /* 参照 FB_VMODE_*        */       __u32 rotate;           /* angle we rotate counter clockwise */ 译者注:这个不知道具体是什么       __u32 reserved[5];      /* 保留 */   };  

2) fb_fix_screeninfon 
这个结构体定义了一些显示设备的特性,这些特性当设备的工作模式确定之后就不能改变了。例如:frambuffer 内存的起始地址。这个地址是根据模式的不同而不同。一旦你用了一种模式,你就不要在想去改变他的起始地址了。在这种情况下,你可以获得显示设备的内存区域地址,但是你��能更改他。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwzjfs.html