编写字符设备驱动程序五步:
- 分配设备号
- 编写完善file_operations
- 注册设备(
register_chrdev(major,name,fops)
) - 入口函数
- 出口函数
驱动程序如何访问硬件:
查看芯片手册,确定寄存器的物理地址,把物理地址通过ioremap映射为虚拟地址,操作虚拟地址。
LCD的驱动程序在fbmen.c。这是一个框架,最终会操作到不同的芯片。在其中的open、read函数等只是一个中转函数。在open函数中,会获取具体的硬件的fb_info结构体,如果这个fb_info里面有调用fb_open函数,就会进入这个fb_open函数。
也就是,对硬件部分都会抽象出一个fb_info结构体,对不同的硬件,抽象出不同的fb_info结构体
ioctl:将输入参数与
进入do_fb_ioctl:会根据cmd进入不同的case:
在fb_info结构体中,有一个成员var,var里面保存可变的屏幕信息,fix里面保存着固定的屏幕信息。fbops结构体保存操作结构体。fb_info结构体:
无论是什么操作,最终都会进入fbmem.c找到fb_info结构体。
怎么编写Framebuffer驱动程序
- 分配fb_info结构体
- framebuffer_alloc
- 设置fb_info
- var
- fix(fb_fix_screeninfo,主要包含显存信息、每行像素占据的字节数)
- fbops
- 硬件相关操作(比如上电等)
- 注册fb_info
register_framebuffer(&fb_info)
注册
举例参考
以s3c2410fb为例:
从入口函数开始看
匹配成功后,调用probe函数,
跳转
调用framebuffer_alloc
分配一个fb_info结构体
分配好之后需要进行设置,ioremap分配映射寄存器
设置var、fix以及中断、时钟使能等硬件相关操作:
var.xres在这里进行幅值赋值
应用程序调用open、read、write等标准函数,fbmem.c的驱动程序会调用file_operations中的open、read、write函数,函数起中转作用,会把具体的请求转发到硬件相关的驱动程序中。在硬件系相关的驱动程序中抽象出一个fb_info结构体,我们编写驱动程序的时候只要实现最下层的驱动程序即可。