[X]关闭

设备树之pinctrl编写

文档创建者:ぉ沙皮狗的忧伤
浏览次数:8498
最后更新:2020-07-31
本帖最后由 ぉ沙皮狗的忧伤 于 2019-11-22 17:30 编辑

pinctrl参考网址https://blog.csdn.net/zhaoxinfan/article/details/70233549
   经过3天的奋斗终于把设备树的硬件信息描述完成了,pinctrl是用来干嘛的呢,是用来配置管脚复用功能,管脚模式例如你这MIO是用在II还是SPI还是GPIO口,假如是GPIO口,那是上拉,还是下拉等等



第一步:在编写驱动代码之前先去配置vivado,生成相应的system.bit.bin文件



最后编译,不要问为什么,人家这样做了是可以的,我也没有去测试一定要配置,个人觉得不用


第二步:撸驱动代码
①、创建pdrv先注册到总线,最后在注销


②、描述platform_driver结构体,先来看driver成员变量plattree_led_of_match,


在这里主要是通过compatible名字在内核链表中来匹配设备树node节点中,从设备树上获取硬件信息

内核提供了很多接口函数用于你从设备树上获取引脚信息,在of.h,of_gpio.h里面,具体需要你们自己去扣


③、driver成员变量name,device驱动根据.name的名字在链表寻找对应设备device,但从设备树获取硬件信息根据of_match_ptr实现的,.name在这里可以随便写,但必须有,我的理解就像人的名字一样,



④、probe函数的编写,
  1)、申请设备,创建类,创建设备
  
  2)、从设备树上获取硬件信息,当设备树驱动匹配成功之后,它就会将从设备树获取的硬件描述platform_device结构体传入到probe里面,我们直接从里面获取GPIO口就行了,申请gpio口,设置为输出模式就可以了

  

  3)、卸载入口函数了,也就是释放gpio口这些东西
   


⑤、小结


首先要具备这样一个思想:设备去找驱动,而不是驱动去找设备

驱动和设备之间的关系:driver就好像Windows鼠标驱动,device就好像你鼠标

两种驱动匹配设备的方式的心得

   1)、假如你不是从设备树获取硬件信息,而是编写driver.ko和device.ko,不管你先挂载哪一个,都会匹配上进入到driver的probe函数中去。如果你先装载设备,内核在链表中没有给你找到匹配的驱动,他就会被搁置,当驱动程序安装时,内核就会给你匹配上;如果你先装载驱动程序,他就会挂载驱动的链表上,当你的设备需要与之匹配的时候就去链表中获取;

   2)、设备树里面硬件描述语言,在内核启动的时候将硬件资源抽象出来形成node节点,由系统统一解析成设备,如果存在驱动代码则与之匹配,没有则搁置在旁等待驱动的安装,在与之匹配









第三步:设备树代码的编写


前面那两步就大致看一下就行,最重要的是最后一步

/*******************************************************************************************************/

首先了分享给大家怎么去写设备树代码

就以GPIO口为例
首先编写一个设备树的硬件描述信息,查看内核提供的例程是必不可少的,即使你写过其他平台的设备树

在kernel/Documentation/devicetree/bindings/gpio/目录下存放的关于设备树的描述例子及文档,我们除了阅读关于自己平台的代码还要去了解通用的代码,比如gpio.txt





看完这些,还是不够,我们还得去看设备树.dts文件中怎么描述的,我们不仅要看米联客的设备树,米尔的,黑金的我都去学习学习,模仿着怎么去写,ok,下面就是我参考这些信息模仿写出来的代码



这样真的行吗,搞一下不就知道了,


gpio口获取正确,也没有错误,但是灯就是没亮,为啥????

很推荐大家去通过寄存器去操作一下,很多东西也许只有你操作很低层的东西,你才会去知道问题的根源在哪,为什么出现这样的错误

我之前通过寄存器操作了gpio,我基本排除我的代码问题,可能是时钟或者GPIO模式没有配置,在dts文件中去看硬件信息看到他有时钟的描述,但始终没有找到管脚功能的硬件描述

通过咨询前辈和上网查阅资料发现原来是需要设置pinctrlhttps://blog.csdn.net/baidu_37503452/article/details/79812244

参考里面的内容发现少了pinctrl这个东西,


ok,于是我们去看设备树找,有没有相似的代码给我们扣,发现了一个这个

我们根据前面的依葫芦画瓢,写成这样,注意:inctrl-names = "default";这里一定要写default,其他的不行,记住就可以,别问为啥



这样就可以了吗,搞一下不就知道了,

面临崩溃的边缘。。。。。我太难了


最后在网上找到了一个比较完整的,具有参考价值的链接
https://blog.csdn.net/zhaoxinfan/article/details/70233549



最后终于完成了设备树代码3.0的编写


====================================================================================
设备树代码语法讲解
在./kernel/Documentation/devicetree/bindings/pinctrl/目录下面xlnx,zynq-pinctrl.txt和pinctrl-bindings.txt里面有详细的描述,我下面就简单的描述一下

1)、 compatible = "plattree_led";除了根节点外所有节点必须具备的节点属性,节点的名称


2)、 address-cells地址的个数
   size-cells长度的个数
   reg = <address size address size address size >


3)、clocks = <&clkc 42>;从clkc父节点继承过来

4)、gpios = <&gpio0 0x07 0x0>;从gpio0父节点那里继承过来,偏移0x07

5)、pinctrl-names = "default"; “sleep”状态,“default”状态,“idle”状态三种状态

6)、pinctrl-0 = <&plattree>;  取plattree标号所在子节点的硬件信息
      
7)、groups是组名 function管脚配置的功能



8)、groups是组名 slew-rate速率 即0是慢速 1是高速 io-standard有限电平


9)、pins是管脚名 bias-pull-up; 上拉模式


10)、pinctrl0的公共部分已经放入头文件即zynq-7000.dtsi里面,这里添加的是私有部分


自己要深入了解去查看内核提供的教程
====================================================================================



文件放在附件中
/*******************************************************************************************************/


总结:学驱动以来发现很多东西,不是困难而是无知,因为不懂的太多



不足之处多多指教!








本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则