一个关于AD热插拔驱动的解读(开发思路的记录)

个人理解:

设备驱动:可分为设备(device)和驱动(driver)两个部分(个人理解)

设备:硬件外设相关信息的代码(固定的,如板子的 卡、中断地址,偏硬件)

驱动:对硬件相关的操作,一些机制的实现(偏软件)

按照这种的分离的思想的话,platform平台总线就非常适合。

platform总线概念:

platform的灵魂是:device(设备)driver(驱动)platform_bus(platform总线),其特点是设

备,驱动分层动态的管理和加载。

按照的总线的要求我们注册好device和driver后,bus会在内核启动的时候对二者进行匹配,按照我们定义的device_driver结构体中的.name和.of_match_table各项先后进行匹配。匹配上之后会去就调用driver驱动结构体里的.probe函数来使总线将设备和驱动联系起来。

通过查看/sys/bus/platform/目录,可以看到两个文件:devices和drivers。它们分别用来存放platform的设备和驱动。

就像现在的linux内核中有设备树这个东西,就是更加方便了。我们不需要再去专门去写一个platform_devcie 文件了,只需要设备树文件dts里面的根节点下,写一个自己的设备节点即可。然后我们再写一个plarform_driver与之匹配。

通用部分:

module_init();

__init xxxx();//入口函数

platform_driver_register();//注册platform_driver

static struct platform_driver //内部就包含.probe、.、.name、.of_match_table

.of_match_table = 全局的struct of_device_id;//struct of_device_id是结构体数组,可以用于表示多个设备

MODULE_DEVICE_TABLE(,struct  of_device_id ….)//用于设备树的节点匹配

如上文说的,当driver和device匹配上之后会去调用调用driver驱动结构体里的.probe函数来使总线将设备和驱动联系起来。

自由发挥部分:

我们这里的应用场景:是AD芯片接CPU的GPIO管脚,

通常在设备树中以 来表示gpio,而在驱动中使用函数返回值来得到gpio

gpio_request:驱动中要想使用某一个gpio,就必须先调用gpio_request接口来向内核申请,得到允许后才可以去使用这个gpio

gpio_to_irq()通过gpio 得到对应的软件中断 , 该中断 是request_irq()函数的第一个参数.

request_irq()根据软件中断 和中断处理函数,注册中断。

中断的内容这边就简单的描述一下,通过i2c读写相关的寄存器信息(类似分辨率、帧率信息、接口在位状态等)。

通过将这些信息反馈回到应用层,应用层设置判断对应的业务处理,模拟热插拔。

但是在实际的操作的过程中遇到了一个问题就是:i2c无法读取AD寄存器的信息。难道是i2c适配有问题。其实并不是,通过查阅资料发现i2c读写也是中断操作,那么问题就明显了。是中断的嵌套引起的i2c读写异常。

那要怎么解决这个问题呢p>

笔者这里采用的是中断底半部机制中的工作队列的方式延迟处理i2c读写。gpio中断处理函数创建一个work 结构体,INIT_WORK()将work和工作处理函数建立关系。工作处理函数执行i2c读写。

PS:中断顶半部,执行硬件中断的处理操作短而急促,不能处理延时。而中断底半部则专门用于处理这些延时操作问题。常见的底半部机制有:软中断、tasklet和工作队列。

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年2月6日
下一篇 2022年2月7日

相关推荐