📄 嵌入式linux下彩色lcd驱动的设计与实现 .txt
字号:
将屏幕缓冲区映射到用户空间。
映射后就可以直接读写屏幕缓冲区,进行绘图和图片显示了。
典型程序段如下:
#include <linux/fb.h>
int main()
{
int fbfd = 0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long int screensize = 0;
/*打开设备文件*/
fbfd = open("/dev/fb0", O_RDWR);
/*取得屏幕相关参数*/
ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo);
ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo);
/*计算屏幕缓冲区大小*/
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
/*映射屏幕缓冲区到用户地址空间*/
fbp=(char*)mmap(0,screensize,PROT_READ|PROT_WRITE,MAP_SHARED, fbfd, 0);
/*下面可通过fbp指针读写缓冲区*/
……
}
四、帧缓冲驱动的编写
帧缓冲设备属于字符设备,与声音设备一样,也采用“文件层-驱动层”的接口方式。在文件层次上,Linux为其定义了
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, /* 关闭操作 */
};
其中的成员函数都在文件linux/driver/video/fbmem.c中定义。
由于显示设备的特殊性,在驱动层的接口中不但要包含底层函数,还要有一些纪录设备状态的数据。Linux为帧缓冲设备定义的驱动层接口为struct fb_info结构,在include/linux/fb.h中定义。这个结构比较长,限于篇幅,文章中就不全部列出了。幸运的是,嵌入式系统要求的显示操作比较简单,只涉及到结构中少数几个成员,下面只对编写驱动中要用到的几个关键成员作一说明。
fb_info中纪录了帧缓冲设备的全部信息,包括设备的设置参数,状态以及操作函数指针。每一个帧缓冲设备都必须对应一个fb_info结构。其中成员变量Modename为设备名称, fontname为显示字体,fbops为指向底层操作的函数的指针,这些函数是需要驱动程序开发人员编写的。成员fb_var_screeninfo和 fb_fix_screeninfo也是结构体。其中fb_var_screeninfo记录用户可修改的显示控制器参数,包括屏幕分辨率和每个像素点的比特数。fb_var_screeninfo中的xres定义屏幕一行有多少个点, yres定义屏幕一列有多少个点,
bits_per_pixel 定义每个点用多少个字节表示。而fb_fix_screeninfo中记录用户不能修改的显示控制器的参数,如屏幕缓冲区的物理地址,长度。当对帧缓冲设备进行映射操作的时候,就是从fb_fix_screeninfo中取得缓冲区物理地址的。上面所说的数据成员都是需要在驱动程序中设置的。
在了解了上面所述的概念后,编写帧缓冲驱动的实际工作并不复杂,需要做的工作是:
1.编写初始化函数:初始化函数首先初始化LCD控制器,设置显示模式和显示颜色数,然后分配LCD显示缓冲区。在Linux可通过kmalloc函数分配一片连续的空间。笔者采用的LCD显示方式为240x320,16位彩色。需要分配的显示缓冲区为240x320x2 = 150k字节,缓冲区通常分配在片外SDRAM中,起始地址保存在LCD控制器寄存器中。最后是初始化一个fb_info结构,填充其中的成员变量,并调用register_framebuffer(&fb_info)将fb_info登记入内核。
2. 编写结构fb_info中函数指针fb_ops对应的成员函数:对于嵌入式系统的简单实现,只需要下列三个函数就可以了:
struct fb_ops {
……..
int (*fb_get_fix)(struct fb_fix_screeninfo *fix, int con, struct fb_info *info);
int (*fb_get_var)(struct fb_var_screeninfo *var, int con, struct fb_info *info);
int (*fb_set_var)(struct fb_var_screeninfo *var, int con,struct fb_info *info);
…….
};
struct fb_ops在include/linux/fb.h中定义。这些函数都是用来设置/获取fb_info结构中的成员变量的。当应用程序对设备文件进行 Ioctl操作时候会调用它们,读者可参考前文中的应用程序例子。例如,对于fb_get_fix(),应用程序传入的是 fb_fix_screeninfo结构,在函数中对其成员变量赋值,主要是smem_start(缓冲区起始地址)和smem_len(缓冲区长度),最终返回给应用程序。而fb_set_var()函数的传入参数是fb_var_screeninfo,函数中需要对xres,yres,和 bits_per_pixel赋值。
驱动程序编写完成后,开发者可选择将其编译为动态加载模块,或静态地编译入内核中。由于篇幅所限,有关这方面的内容请读者参考相关驱动程序文档。
五、结束语
由于篇幅所限,本文中仅对帧缓冲设备驱动的基本原理和框架做了简单介绍。幸运的是,在Linux的发布版本中,包含了大量的设备驱动程序源代码,其中 drvers/video下提供了多种显示卡的帧缓冲设备驱动程序程序,用户自己的驱动程序可参考成熟的代码编写或直接修改得到。
参考资料
《MC928MX1 User Manual》
《Linux frame buffer driver howto》
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -