linux lcd测试程序,【Tiny6410 And Linux】—(6.1)—LCD 驱动测试程序——原理 (转)...

2012-09-28 09:55

303人阅读

评论(0)

总算要涉及到LCD的驱动程序了,不过之前还是先弄一下LCD的测试程序的好(这里看的是国嵌的代码)!

之前在电脑上找了很久的LCD的驱动程序,也就是xxxfb.c,但是真心看不懂究竟是哪个驱动,但是共性的文件fbmem.c还是可以了解的,这

里就通过fbmem.c来进行简单的介绍吧,至于涉及到的相关的硬件设备(今天写的驱动测试没有涉及到硬件的具体信息),只能等以后再说了!

LCD 驱动测试程序:

首先介绍一下 Framebuffer:Framebuffer 从本质上讲是图形设备的硬件抽象。对开发者而言, Framebuffer

是一块显示缓存,往缓存中写入特定格式的数据就意味着向屏幕输出内容。通过不断的向 Framebuffer 中写入数据,显示控制器就会自动的从

Framebuffer 中取数据并显示出来,帧缓冲设备对应的设备文件为 /dev/fb0,如果系统有多个显示卡, Linux

下还可以支持多个帧缓冲设备,通常指向 /dev/fb0。真缓冲设备为标准的字符设备,主设备号为 29,次设备号从

0 到 31。

下面可以看看帧缓冲设备的架构:

32312712_1.jpg

1、帧缓冲设备结构体介绍:

Linux 内核使用 fb_info 结构来描述帧缓冲设备,定义在 include/linux/fb.h 中, fb_infor 结构常用成员:

struct fb_info {

int node;

int flags;

struct mutex lock;      /* Lock for open/release/ioctl funcs */

struct mutex mm_lock;       /* Lock for fb_mmap and smem_* fields */

struct fb_var_screeninfo var;   /* Current var */

struct fb_fix_screeninfo fix;   /* Current 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 */

/* we need the PCI or similiar aperture base/size not

smem_start/size as smem_start may just be an object

allocated inside the aperture so may not actually overlap */

struct apertures_struct {

unsigned int count;

struct aperture {

resource_size_t base;

resource_size_t size;

} ranges[0];

} *apertures;

};

其中 fb_var_screeninfo 结构记录了用户可以修改的显示参数,包括屏幕分辨率等。

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

};

fb_fix_screeninfo 记录了用户不能修改的显示控制器参数,如显示缓存的物理地址等。

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

};

还有就是 fb_ops 结构包含了对控制器进行操作的函数指针。

struct fb_ops {

/* open/release and usage marking */

struct module *owner;

int (*fb_open)(struct fb_info *info, int user);

int (*fb_release)(struct fb_info *info, int user);

/* For framebuffers with strange non linear layouts or that do not

* work with normal memory mapped access

*/

ssize_t (*fb_read)(struct fb_info *info, char __user *buf,

size_t count, loff_t *ppos);

ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,

size_t count, loff_t *ppos);

/* checks var and eventually tweaks it to something supported,

* DO NOT MODIFY PAR */

int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);

/* set the video mode according to info->var */

int (*fb_set_par)(struct fb_info *info);

/* set color register */

int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,

unsigned blue, unsigned transp, struct fb_info *info);

/* set color registers in batch */

int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);

/* blank display */

int (*fb_blank)(int blank, struct fb_info *info);

/* pan display */

int (*fb_pan_display)(struct fb_var_screeninfo *var, 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);

/* Draws cursor */

int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);

/* Rotates the display */

void (*fb_rotate)(struct fb_info *info, int angle);

/* wait for blit idle, optional */

int (*fb_sync)(struct fb_info *info);

};

2、控制器操作函数(fbmem.c):

这里首先讲述一下 LCD 测试程序的基本步骤:

1)用 ioctl 操作取得当前屏幕的参数,根据屏幕参数可以计算屏幕缓冲区的大小。

2)将屏幕缓冲区映射到用户空间(mmap)。

3)映射后即可直接读写

这里用到 open、release、ioctl 等函数,主要介绍下 ioctl 函数吧,代码如下:

static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

{

struct inode *inode = file->f_path.dentry->d_inode;

int fbidx = iminor(inode);

struct fb_info *info = registered_fb[fbidx];

return do_fb_ioctl(info, cmd, arg);

}

static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,

unsigned long arg)

{

struct fb_ops *fb;

struct fb_var_screeninfo var;

struct fb_fix_screeninfo fix;

struct fb_con2fbmap con2fb;

struct fb_cmap cmap_from;

struct fb_cmap_user cmap;

struct fb_event event;

void __user *argp = (void __user *)arg;

long ret = 0;

switch (cmd) {

case FBIOGET_VSCREENINFO:

if (!lock_fb_info(info))

return -ENODEV;

var = info->var;

unlock_fb_info(info);

ret = copy_to_user(argp, &var, sizeof(var)) ? -EFAULT : 0;

break;

case FBIOPUT_VSCREENINFO:

if (copy_from_user(&var, argp, sizeof(var)))

return -EFAULT;

if (!lock_fb_info(info))

return -ENODEV;

console_lock();

info->flags |= FBINFO_MISC_USEREVENT;

ret = fb_set_var(info, &var);

info->flags &= ~FBINFO_MISC_USEREVENT;

console_unlock();

unlock_fb_info(info);

if (!ret && copy_to_user(argp, &var, sizeof(var)))

ret = -EFAULT;

break;

case FBIOGET_FSCREENINFO:

if (!lock_fb_info(info))

return -ENODEV;

fix = info->fix;

unlock_fb_info(info);

ret = copy_to_user(argp, &fix, sizeof(fix)) ? -EFAULT : 0;

break;

case FBIOPUTCMAP:

if (copy_from_user(&cmap, argp, sizeof(cmap)))

return -EFAULT;

ret = fb_set_user_cmap(&cmap, info);

break;

case FBIOGETCMAP:

if (copy_from_user(&cmap, argp, sizeof(cmap)))

return -EFAULT;

if (!lock_fb_info(info))

return -ENODEV;

cmap_from = info->cmap;

unlock_fb_info(info);

ret = fb_cmap_to_user(&cmap_from, &cmap);

break;

case FBIOPAN_DISPLAY:

if (copy_from_user(&var, argp, sizeof(var)))

return -EFAULT;

if (!lock_fb_info(info))

return -ENODEV;

console_lock();

ret = fb_pan_display(info, &var);

console_unlock();

unlock_fb_info(info);

if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))

return -EFAULT;

break;

case FBIO_CURSOR:

ret = -EINVAL;

break;

case FBIOGET_CON2FBMAP:

if (copy_from_user(&con2fb, argp, sizeof(con2fb)))

return -EFAULT;

if (con2fb.console  MAX_NR_CONSOLES)

return -EINVAL;

con2fb.framebuffer = -1;

event.data = &con2fb;

if (!lock_fb_info(info))

return -ENODEV;

event.info = info;

fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);

unlock_fb_info(info);

ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;

break;

case FBIOPUT_CON2FBMAP:

if (copy_from_user(&con2fb, argp, sizeof(con2fb)))

return -EFAULT;

if (con2fb.console  MAX_NR_CONSOLES)

return -EINVAL;

if (con2fb.framebuffer = FB_MAX)

return -EINVAL;

if (!registered_fb[con2fb.framebuffer])

request_module("fb%d", con2fb.framebuffer);

if (!registered_fb[con2fb.framebuffer]) {

ret = -EINVAL;

break;

}

event.data = &con2fb;

if (!lock_fb_info(info))

return -ENODEV;

event.info = info;

ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);

unlock_fb_info(info);

break;

case FBIOBLANK:

if (!lock_fb_info(info))

return -ENODEV;

console_lock();

info->flags |= FBINFO_MISC_USEREVENT;

ret = fb_blank(info, arg);

info->flags &= ~FBINFO_MISC_USEREVENT;

console_unlock();

unlock_fb_info(info);

break;

default:

if (!lock_fb_info(info))

return -ENODEV;

fb = info->fbops;

if (fb->fb_ioctl)

ret = fb->fb_ioctl(info, cmd, arg);

else

ret = -ENOTTY;

unlock_fb_info(info)    }

return ret;

}

如果对 ioctl 函数有所理解,可以很快看到 cmd 变量 FBIOGET_VSCREENINFO,这个变量就可以获得设备体 /dev/fb0 的相关的详细信息!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值