一个关于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管脚,

通常在设备树中以 reset-gpios = <&gpio1 15 1>;来表示gpio,而在驱动中使用gpio号 = of_get_named_gpio(xxxnode, "reset-gpios", 0);函数返回值来得到gpio号

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

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

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

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

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

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

那要怎么解决这个问题呢?

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

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

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值