一个懒惰的文艺工程师!
分类: LINUX
2013-11-08 19:05:14
原文地址:LCD & framebuffer开发心得 作者:dfhf2007
帧缓冲设备属于字符设备,采用了“文件层-驱动层”的接口方式。Linux为帧缓冲设备定义的驱动层接口为struct fb_info结构。在文件层次上,Linux为其定义了下面的操作函数:struct file_operations
软件运行流程:
在文件层次上,用户调用struct file_operations的函数操作,在struct file_operations中间接调用struct fb_ops的函数来操作硬件.当向内核注册FB设备的时候,也注册了struct fb_ops的指针.当打开fb设备时,先调用fb_drivers[]的xxxfb_init()来初始化设备;
1、开发步骤和框架
涉及的文件:fb.h, fbmem.c, xxxfb.c.
fb.h: 定义了一些结构,变量和宏;
fbmem.c: 主要实现设备入口和初始化,如struct file_operations;
入口点:
static struct {
const char *name;
int (*init)(void);
int (*setup)(char*);
} fb_drivers[] __initdata = {
#ifdef CONFIG_FB_YOURCARD
{ "driver_name", xxxfb_init, xxxfb_setup },
#endif
文件操作:
static struct file_operations fb_fops = {
owner: THIS_MODULE,
read: fb_read,
write: fb_write,
ioctl: fb_ioctl,
mmap: fb_mmap,
open: fb_open,
release: fb_release,
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
get_unmapped_area: get_fb_unmapped_area,
#endif
};
xxxfb.c: 自己添加的设备驱动文件,如struct fb_info;
实现入口点函数: xxxfb_init; xxxfb_setup;
static struct fb_ops xxxfb_ops = {
owner: THIS_MODULE,
fb_open: xxxfb_open, /* only if you need it to do something */
fb_release: xxxfb_release, /* only if you need it to do something */
fb_get_fix: fbgen_get_fix,
fb_get_var: fbgen_get_var,
fb_set_var: fbgen_set_var,
fb_get_cmap: fbgen_get_cmap,
fb_set_cmap: fbgen_set_cmap,
fb_pan_display: fbgen_pan_display,
fb_ioctl: xxxfb_ioctl, /* optional */
};
2、什么是framebuffer 设备
framebuffer 是一种能够提取图形的硬件设备,是用户进入图形界面很好的接口。有了framebuffer,用户的应用程序不需要对底层的驱动的深入了解就能够做出很好的图形。
对于用户而言,它和/dev 下面的其他设备没有什么区别,用户可以把
framebuffer 看成一块内存,既可以向这块内存中写入数据,也可以从这块内存中读取数据。
第一个被注册的framebuffer 的minor 等于0,第二个被注册的framebuffer的minor 等于1,以此类推。
3、framebuffer 内部结构
数据结构:framebuffer 设备很大程度上依靠了下面四个数据结构。这三个结构在fb.h 中声明。
Struct fb_var_screeninfo
Struct fb_fix_screeninfo
Struct fb_info
第一个结构是用来描述图形卡的特性的。通常是被用户设置的。它包括显示屏幕的分辨率、每个像素的比 特数和一些时序变量。其中变量xres定义了屏幕一行所占的像素数,yres定义了屏幕一列所占的 像素数,bits_per_pixel定义了每个像素用多少个位来表示。
第二个结构定义了图形卡的硬件特性,是不能改变的,用户选定了哪一个图形卡,那么它的硬件特性也就 定下来了。它包含了屏幕缓冲区的物理地址和长度。
第三个结构是Linux为帧缓冲设备定义的驱动层接口。它不仅包含了底层函数,而且还有记录设备状态的 数据。每个帧缓冲设备都与一fb_info结构相对应。其中成员变量modename为设备名称, fontname为显示字体,fbops为指向底层操作的函数的指针。定义了当前图形卡framebuffer 设 备的独立状态,一个图形卡可能有两个framebuffer, 在这种情况下,就需要两个fb_info 结构 。这个结构是唯一在内核空间可见的。
4、设计自己的framebuffer 设备驱动
用户首先需要添加下面的代码到fbmem.c
static struct {
const char *name;
int (*init)(void);
int (*setup)(char*);
} fb_drivers[] __initdata = {
#ifdef CONFIG_FB_YOURCARD
{ "driver_name", xxxfb_init, xxxfb_setup },
#endif
其次在xxfb.c 中根据自己的需要重新分配显存大小。例如:
#define VIDEOMEMSIZE (1*1024*1024) /* 1 MB */
再次根据自己的硬件设备修改相应的var 信息。主要修改
xxfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)函数。
5、如何添加framebuffer 设备驱动
在make menuconfig 的时候首先进入Character devices,选中里面的Virtualterminal.如果希望控制台在液晶上输出,则选中Support for console on virtual terminal。(选用了msh(minix shell),再在rc中放入了一条sh < /dev/ttyS0,通过串口输入的键值显示输出就能在LCD上显示了。)
退到上一层界面我们就可以看到Console device 的选项,进入后将光标落在Framebuffer Support 上,按回车键进入,在里面选择自己所需要的framebuffer设备即可。自己所添加的设备驱动的类型(如果在uclinux 下,应该以*选中,而不是M 选中),在编译的时候就会产生相应的.o 文件。
在Advanced low level 中可以配置bpp packed pixel support,然后选中Selectcompiled-in fonts即可。
等操作系统运行以后就会在/dev 下面看到fb 这个设备。它的major 应该是29,第一个设备的minor 应该是0。