Linux驱动之LCD框架介绍

在裸机编程的时候,曾经编写过LCD的测试程序,对这一部分不是很了解的可以先去看一下,我们今天要做的是基于Linux内核框架下的LCD驱动程序,内核版本,Linux-2.6.22.6
内核中已经集成了LCD的驱动框架,在driver/video/fbmem.c,打开这个文件,发现它是符合字符设备驱动的编写流程,下面是它的入口函数
在这里插入图片描述
注册了一个字符设备驱动,主设备号FB_MAJOR是29,要注意的是在入口函数里注册了类,但是并没有在类下注册设备,先来看看它的操作函数集合中的函数
在这里插入图片描述
在这里插入图片描述
上面的是open函数的详情,首先是获取打开设备的次设备号int fbidx = iminor(inode);然后定义了一个结构体struct fb_info *info;,这个结构体很重要,后面都是围绕这个结构体来进行的。接着为这个结构体赋值,是从数组registered_fb中获取以次设备号为下标的成员,然后调用这个结构体中的open函数info->fbops->fb_open,这个套路其实和之前我们分析的输入子系统的框架差不多,为了证明我们的猜想。再去看看是如何读数据的
在这里插入图片描述
上面只是read函数的部分代码,但是不难看出在read函数里也是一开始就去获取打开的设备的次设备号,然后从registered_fb数组里获取次设备号为下标的数组项为定义的结构体赋值然后调用其read函数

看到这里就有一个问题,数组是registered_fb在哪里被设置的?
其实我们也可以猜到一部分了,上面看的代码fbmem.c只是软件层面上抽象出来的一层逻辑代码,那么,以分层的思想去思考LCD的驱动框架,数组registered_fb必定是在每一个具体的单板中被设置进去的,上层不关心具体的单板内容,单板也不知道软件逻辑,

那现在就来分析一款具体的单板的LCD程序,看看是不是和我们想的是一样的呢?
drivers/video/s3c2410fb.c
在这里插入图片描述上面是它的入口函数,在入口函数里注册了一个平台软件驱动platform_driver_register(&s3c2410fb_driver);,我们知道当注册一个平台软件驱动的时候就会去内核里便利设备链表,通过结构体中的name进行匹配。如果存在s3c2412-lcd的平台设备驱动就会调用probe函数,
我们先假设内核中存在这么一个设备,然后来看它的probe函数,
在这里插入图片描述
在这里插入图片描述
这个函数体有些庞大,具体的我就不截图了,在probe函数中定义一个fbinfo结构体,然后获取设备数据
mach_info = pdev->dev.platform_data;,然后通过一些计算为fbinfo赋值,这里就不再细究,想要了解的可以去看源码,
最终调用了函函数,如下
在这里插入图片描述
在这里插入图片描述
在函数register_framebuffer中其实就是在数组registered_fb中找出一个空闲的下标,把设置好的fbinfo结构体放进去,这就算是注册好了,就是这么简单。并且在这个函数里通过device_create注册了具体的设备,与前面相对应,在找到设备时才去注册设备,

现在来看内核中的与之对应的设备驱动arch/arm/mach-s3c2440/mach-smdk2440.c
平台设备结构体数组里包含了LCD的结构体
在这里插入图片描述
在arch/arm/plat-s3c24xx/devs.c,名字和之前的完全匹配,通过上面的分析,我们知道是通过s3c_device_lcd.dev.platform_data进行设置的在这里插入图片描述
搜索,
在这里插入图片描述
继续查找s3c24xx_fb_set_platdata函数被谁调用,又回到了arch/arm/mach-s3c2440/mach-smdk2440.c
在这里插入图片描述
搜索smdk2440_fb_info
在这里插入图片描述
在这里插入图片描述
终于找到了,这些不就是LCD控制器那些寄存器的值吗,所以,与单板具体相关的LCD就是在这里被设置好,放进了内核数组里的,到这里LCD的驱动框架就已经分析完了

总结

内核里的LCD框架可以分为两层,(其实看得多的话就会发现,不止是LCD,其他的都是这样的框架)
1、软件抽象层,在这里是drivers/video/fbmem.c
  软件抽象层主要是和上面的应用进行交互,它只处理应用的请求,里边定义了软件层的逻辑代码
  在fbmem.c的入口函数里定义了一个字符设备的驱动,应用程序通过打开设备节点调用到字符设备
  fops中的open、read、write等函数,fbmem.c -> fops -> open函数只是一个中转,它是通过
  获取打开的设备的次设备号来从数组registered_fb中获取下标对应的数组项,然后调用数组项
  里的open函数,read也是这样,那么,我们就要知道,这个数组是在哪里被设置的,里边的成员从哪里来?

2、硬件设备层,里边是具体的硬件设备的信息,与软件抽象层交互,完成应用程序的请求
   这里我们分析的是drivers/video/s3c2410fb.c
   在它的入口函数注册了一个平台软件驱动s3c2410fb_driver,通过匹配平台设备驱动,执行其probe函数
   在它的probe函数里,通过获取平台设备的设备数据pdev->dev.platform_data,进一步设置分配的fbinfo
   结构体,然后注册fbinfo结构体(也就是放进数组),到这里上面的问题就已经得以解答,registered_fb
   数组的内容是在具体的单板文件中被设置的,
   在与架构相关的文件中有每个单板的平台设备结构体,里边包含LCD的结构体,和LCD控制器的寄存器的值,在
   单板初始化的时候被编译进内核中,平台软件驱动就可以获取到其中的数据,注册fbinfo结构体
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值