编写基于Linux的lcd驱动(8)

 

static struct {        const char *name;        int (*init)(void);        int (*setup)(void);    } fb_drivers[] __initdata= { ....};   

如果一个frambuffer 驱动模块是静态链接到内核的,那么必须在这个结构中加入新项,如果用动态加载模块的方法,就不用考虑这个结构了。

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    };   

这是面向应用程序的接口,fbmem.c中实现了这些操作。
2) register_framebuffer(struct fb_info *fb_info) 函数 和 unregister_framebuffer(struct fb_info *fb_info)函数
这个函数是frambuffer设备驱动程序的底层接口。驱动程序用这两个函数向内核注册和注销自己。驱动程序所做的所有底层工作就是填充一个fb_info结构体然后注册自己
4 LCD控制器驱动程序的结构框架
LCD 驱动操作LCD设备。而frambuffer核心(fbmem.c)管理这些驱动。在linux /drivers /fb /skeleton.c中,编写了一个frambuffer驱动结构的框架。他用一些代码展示了如何编写frambuffer驱动。因为这个太简单了,他除了填充一个frambuffer的fb_info结构体并注册到内核外什么都没做。为了编写一个可用的LCD控制器驱动,还必须做其他的一些工作。具体需要做些什么呢,我们知道设备驱动程序将硬件抽象化并向应用程序提供接口。所以根据系统调用接口的需要,我们实现相应的底层硬件操作,那就是我们在3.2小节提到的 file_operations 结构体
4.1 为设备分配一块显示内存
仔细研究fbmem.c后,我们发现 open()和release() 文件操作方法的实现不需要底层硬件的支持。但是 read(),write()和mmap() 需要一个通用的操作函数fb_get_fix(),这个函数必须由驱动程序的作者编写另外驱动程序还必须为设备分配一块内存作为显示缓存,因为大多数LCD控制器都没有自己的缓存。这块内存的开始地址和大小将会填充在fb_fix_screeninfo结构的smem_start和smem_len域。而且内存必须是物理连续的。
4.2 fbops 函数的实现
现在还有个文件操作没有讨论的就是Ioctl()了,应用程序使用系统调用ioctl来操作LCD硬件。在fb_ops定义的方法来支持这些操作。
注意: 这里的fbops结构不是上层的系统调用接口(注:是在fb_info中的)。下面我们讨论该实现什么样的方法。ioctl()系统调用在fbmem.c中实现,因此我们在这个实现中会发现相关的命令与fb_ops方法 
FBIOGET_VSCREENINFO fb_get_var 
FBIOPUT_VSCREENINFO fb_set_var 
FBIOGET_FSCREENINFO fb_get_fix 
FBIOPUTCMAP fb_set_cmap 
FBIOGETCMAP fb_get_cmap 
FBIOPAN_DISPLAY fb_pan_display 
现在我们知道应该实现这些fb_XXX_XXX函数。应用程序的作者可以通过调用FBIOXXXX来操作lcd。我们如何来实现这些操作呢?最好是先参考一下linux/drivers/video/fbgen.c和在the linux/drivers/video目录下其他的显示驱动程序。在这些函数中,fb_set_var()最重要。他用来设置显示模式和实现其他功能的。下面是fb_set_var()实现的通用步骤: 
    1) 检查模式设置是否必须
    2) 设置模式
    3) 设置调色板
    4) 根据先前的配置,设置LCD控制器的寄存器
这四步说明了底层操作的实现。好奇的童鞋会问:应用程序的图像数据是怎样显示在屏幕上的。驱动程序分配一块内存作为显存。然后设置显存的开始地址和长度到对应的LCD控制器的相应寄存器(这个操作一般由fb_set_var())实现。内存中的数据会通过LCD控制器自动显示到屏幕上(详情请参照特定的LCD控制器)。另一方面显存被mmap()到了用户空间。因此,当用户将数据拷贝到映射的内存的时候,数据就会显示到屏幕上了。

参考资料:
1 液晶显示技术 
2 液晶显示器件 
3 linux/Documentation/fb/framebuffer.txt 
4 linux/Documentation/fb/interal.txt 
5 Linux Framebuffer Driver Writing HOWTO 
http:/linux-fbdev.sourceforge.net/HOWTO /index.html 
6 linux/include/linux/fb.h 
7 linux/drivers/video/fbmem.c 
8 linux/drivers/video/skeletonfb.c 
9 linux/drivers/video/fbgen.c 
10 linux/drivers/video/tgafb.c 
11 s3c2410 microprocessor user manual 
s3c2410fb.h, s3c2410fb.c, s3c2410fb.c-pre, s3c2410fb.c-mono 
A kind of arm-based widely used MCU, with integrated LCD controller. 
12 sed1335 datasheet 
A kind of widely used LCD controller

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwzjfs.html