Linux下LCD驱动详细分析(一)

    貌似好久好久没写驱动类的博客,距上一次写驱动的博客还得回到半年前,那时天气还很冷,如今已经热的要命,但我还是想把自己学习到的知识跟大家分享。没写驱动类的博客是觉得Linux下的驱动源码真是太多太多了,半年前我也比较害怕Linux源代码,随时时间的推移,自己琢磨了不短时间了,觉得大概能读懂Linux源代码了,也就没那么害怕它了。

原归正传,预定以后的驱动博客我想用尽量短篇幅来记录,但是会以尽量详细的角度去分析驱动。学习驱动心得,驱动呢主要还是要抓住主干的架构,太细节的东西不必太刻意去研究,因为很多太底层的函数人家已经帮你实现了,你不必去怀疑它正确与否。

LCD驱动里有个很重要的概念叫帧缓冲(framebuffer),它是Linux系统为显示设备提供的一个接口,应用程序在图形模式允许对显示缓冲区进行读写操作。用户根本不用关心物理显示缓冲区的具体位置及存放方式,因为这些都由缓冲区设备驱动完成了。

启动开发板后执行ls  /dev/fb*  命令可以看到,帧缓冲设备的主设备号为29,对应/dev/fbn设备文件,一般为/dev/fb0

在弄清楚LCD驱动架构之前,我们先弄清楚几个重要的结构体,为了减短篇幅,有一些不是很重要的成员会用省略,具体的源代码请大家参考Linux源代码,这里我使用的源代码是天嵌公司提供的移植好的Linux-2.6.30.4。

1.fb_info结构体(在include/linux/fb.h文件里定义)

struct  fb_info {
int node; /*  序号索引值,/dev/fb0,/dev/fb1  其中0,1 就是从这里获得的*/
int flags;
struct mutex lock;/* 一般在 open/release/ioctl 函数里会用到的锁 */
struct fb_var_screeninfo var;/* 可变参数,很重要 */
struct fb_fix_screeninfo fix;       /* 固定参数,很重要 */
struct fb_monspecs monspecs;/* Current Monitor specs */
struct work_struct queue;       /* Framebuffer event queue */
struct fb_pixmap pixmap;       /* Image hardware mapper */
struct fb_pixmap sprite;       /* Cursor hardware mapper */
struct fb_cmap cmap;       /* Current cmap */
struct list_head modelist;              /* mode list */
struct fb_videomode *mode;/* current mode */

。。。。。。

struct fb_ops *fbops;
struct device *device;/* This is the parent */
struct device *dev;/* This is this fb device */

。。。。。。
char __iomem *screen_base;/* "显存“的基地址 */
unsigned long screen_size;       /* ”显存“的大小 */ 
void *pseudo_palette;      /* 16位假的调色板 */ 
#define FBINFO_STATE_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
u32 state; /* Hardware state i.e suspend */
void *fbcon_par;                /* fbcon use-only private area */
/* From here on everything is device dependent */
void *par;   /* 这个用来存放私有数据 */
};

2.fb_ops结构体(在include/linux/fb.h文件里定义)

考虑到fb_ops结构体里面的函数指针成员太多,这里仅简单列举几个比较常见的,具体的请参考源代码。

struct fb_ops{
struct module *owner;  /* 模块计数 */
int (*fb_open)(struct fb_info *info, int user);           /* 打开函数,第一个参数为fb_info */
int (*fb_release)(struct fb_info *info, int user);
。。。。。。
/* fb_check_var函数用来检查可变参数,并调整修改可变参数  */
int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
。。。。。。
/*fb_setcolreg函数就是用来设置fb_info里面的pseudo_palette调色板成员 */
int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
   unsigned blue, unsigned transp, struct fb_info *info);
。。。。。。

/* 下面三个是通用的函数 */
/* Draws a rectangle */
void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
/* Copy data from area to another */
void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
/* Draws a image to the display */
void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
。。。。。。
/* 有了fb_ioctl应用层可以通过ioctl系统调用来设置屏幕参数等 */
int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
unsigned long arg);
。。。。。。
/* 有了fb_mmap应用层可以通过mmap系统调用来读写帧缓冲区内存 */
int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
。。。
};

3.fb_var_screeninfo 结构体(在include/linux/fb.h文件里定义)

fb_var_screeninfo 被fb_info结构体所包含,这个结构体主要用来设置LCD屏幕的参数,如分辨率、像素比特数等,LCD驱动程序里面硬件相关的设置很多都涉及这个结构体。

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 */
};

4.fb_fix_screeninfo 结构体(在include/linux/fb.h文件里定义)

struct fb_fix_screeninfo {
char id[16];/* 驱动名字就保存在这里*/
unsigned long smem_start;       /* fb缓冲区的基地址,这是一个物理地址 */
__u32 smem_len;       /* fb缓冲区的长度 */
__u32 type;              /* FB_TYPE_类型*/
__u32 type_aux;/* Interleave for interleaved Planes */
__u32 visual;/* FB_VISUAL_类型*/ 
__u16 xpanstep;/* 一般设置为0  */
__u16 ypanstep;/* 一般设置为0  */
__u16 ywrapstep;/* 一般设置为0  */
__u32 line_length;/* 屏幕一行有多个字节    */
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 */
};

以上笼统的介绍了几个重要的结构体,大家如果没有阅读过源码的可能对这些结构体比较陌生,但是没关系,比较常用的我都用显眼的颜色标记了,大家结合以后的博客日志就会懂这些结构有什么作用了。

对于这些参数会在哪里设置?通过什么样的形式来设置?

答:通过平台设备的方式来设置,这就是鼎鼎有名的platform_device结构体了,这个知识留到后面的LCD驱动篇来讲解。

这篇博客先分析到这里,下一篇准备讲内核源代码fbmem.c,这个文件实现了帧缓冲设备驱动的文件操作接口函数。


  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值