lxiaogao

全志lcd framebuffer驱动原理

全局变量

struct fb_info *registered_fb[FB_MAX];

int num_registered_fb;

             这两变量记录了所有fb_info 结构的实例,fb_info 结构描述显卡的当前状态,所有设备对应的fb_info 结构都保存在这个数组中,当一个FrameBuffer设备驱动向系统注册自己时,其对应的fb_info 结构就会添加到这个结构中,同时num_registered_fb 为自动加1.

 

Lcd\dev_lcd.c中

 

intlcd_init(void)

{

。。。。。。

LCD_get_panel_funs_0(&lcd0_cfg);->  fun->cfg_open_flow = LCD_open_flow;->

         Fb_Init(0);->register_framebuffer()

。。。。。。

}

 

 

structfb_info *info = registered_fb[newidx];

 

int i, new_idx = -1, ret = 0;

 

         if (!fbcon_has_console_bind)

                   return 0;

 

         for (i = first_fb_vc; i <= last_fb_vc; i++) {

                   if (con2fb_map[i] != idx&&

                       con2fb_map[i] != -1) {

                            new_idx = i;

                            break;

                   }

         }

 

 

info->fbops->fb_imageblit(info, image);----à void cfb_imageblit(structfb_info *p, conststructfb_image *image)

 

 

fbmem.c中创建设备结构fb* 并绑定与用户空间交互的fops如 write read

staticconststructfile_operationsfb_fops = {

         .owner =  THIS_MODULE,

         .read =               fb_read,

         .write =    fb_write,

。。。。。。。

}

 

         if (info->fbops->fb_write)

                   return info->fbops->fb_write(info, buf, count, ppos);

        

最终还是调用info->fbops(static structfb_opsdispfb_ops(dev_fb.c(注册fb驱动)))

 

 


 

static struct {

const char *name;

int (*init)(void);

int (*setup)(void);

} fb_drivers[] __initdata= { ....};

 

如果FrameBuffer设备被静态链接到内核,其对应的入口就会添加到这个表中;如果是动态加载的,即使用insmod/rmmod,就不需要关心这个表。

 

static struct file_operations fb_ops ={

owner: THIS_MODULE,

read: fb_read,

write: fb_write,

ioctl: fb_ioctl,

mmap: fb_mmap,

open: fb_open,

release: fb_release

};

这是一个提供给应用程序的接口.

 

2)fbmem.c 实现了如下函数.

 

register_framebuffer(struct fb_info *fb_info);

unregister_framebuffer(struct fb_info *fb_info);

 

这两个是提供给下层FrameBuffer设备驱动的接口,设备驱动通过这两函数向系统注册或注销自己。几乎底层设备驱动所要做的所有事情就是填充fb_info结构然后向系统注册或注销它。


评论