全志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结构然后向系统注册或注销它。
评论