Linux驱动-LCD驱动框架
2024年5月 · 预计阅读时间: 4 分钟
#
从应用视角到内核,看LCD驱动程序整体流程如图:
查看qemu中百问网编写的fb_test程序。
fb-test.c
#
1.APP-先看main函数先调用fb_open
打开frame buffer,传入默认0,表示打开fb0,返回一个fb_info
结构体。获得LCD的信息后,就可以操作屏幕了
fb_open
,获取fb_info
#
2.APP-#
应用程序open、ioctl、mmap定义在common.c
中
主要包括以下三个步骤:
fd = open(str, O_RDWR) -> open("/dev/fb0", O_RDWR)
调用系统调用-open打开fb0IOCTRL1 -> ioctl
获取LCD信息mmap
虚拟内存映射: 应用程序中需要映射一块虚拟内存到显存的物理地址void ptr = mmap(0, fb_info->var.yres_virtual fb_info->fix.line_length, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
接下来,将详细解析以上系统调用的过程。
file_operations
的fb_open
#
2.1 驱动框架中APP:
在fbmem.c
,提供了frame buffer操作的框架,就是完成字符设备驱动程序的基本流程,然后再去调用下层的具体单板驱动程序。
info = get_fb_info(fbidx);
通过传入的次设备号获取显存信息,实际是通过一个数组registered_fb
获得,注册过程看下面第4小节。在打开过程中,也会把
info
放入到file中,file->private_data = info;
,后面会用到
file_operations
的fb_ioctl
#
2.2 驱动框架中应用程序的ioctl会调用到驱动的fb_ioctl
fbmem.c
这里就是先从file中获得fb_info
,然后传入do_fb_ioctl
,根据不同的ioctrl命令cmd
,获取信息。如FBIOGET_VSCREENINFO
就是将LCD的可变参数信息var
,拷贝到用户空间的arg
.
file_operations
的fb_mmap
#
2.3 驱动框架中同样的,应用程序的mmap
也会调用到驱动程序中的fb_mmap
可以看到最后就是调用内核函数vm_iomap_memory
vm_iomap_memory
是Linux内核中用于映射设备内存到用户空间的函数。它允许用户空间程序直接访问设备内存,而不需要通过内核态的中间层。
fb_info
过程#
3.具体LCD驱动中,注册既然上面fb_open
是通过获取一个数组的某一项获得fb_info
,那么一开始LCD初始化就会注册这个fb_info
到数组中。
比如,我们编写的imx6ull的LCD驱动,在装载module的时候,就会分配/配置/注册fb_info
。
在下层实现的具体单板的LCD驱动中,会注册到上层框架fbmem.c
此函数上一节编程已经看过了。这里主要看register_framebuffer
调用do_register_framebuffer