3.X内核下设备树–platform设备驱动

1。历史的车轮总是向前,技术更替。在linus 同学发出那句 WFK 后内核进入了设备树时代(站在驱动工程师角度)。

前几天我已经被mach-imx 中的文件折磨的夜不能眠。我终于在一个清晨,喝完一杯咖啡后决定放弃蹩脚的传统device描述方式。

这里我先不讨论内核实现流程的源代码,简单描述下语法,和我的第一个test_platform_device

设备树文件 arch\arm\boot\dts 在修改dst文件后要make dtbs,

http://www.xuebuyuan.com/2128963.html 这篇文章可以恶补下设备书的基础

如图是一个完整节点
这里写图片描述
这里写图片描述

Documentation\devicetree\bindings 文件夹中有很多的样例可以供开发人员参考

2。 我的测试

我在我的设备树中添加如下代码(这里我把一个ds18b20做成platform设备,仅仅为了练习)
这里写图片描述

    my-ds18b20 {compatible = "ds18b20";gpios = <&gpio2 3 1>;   //有更改,以这里为准};

我ds18b20使用的是GPIO2_3 管脚。

这里的gpios = <&gpio2 3 0>; 在 imx6qdl.dtsi 文件中定义
这里写图片描述
然后执行 # make dtbs

生成的dtbs文件在dts文件同一目录,烧写 内核 和 DTBS 文件

编写ds18b20的driver 端(为了使结构简单明了,我屏蔽了其他代码,留下了骨架)

#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/interrupt.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/crc32.h>
#include <linux/mii.h>
#include <linux/of.h>
#include <linux/of_net.h>
#include <linux/ethtool.h>
#include <linux/dm9000.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/slab.h>#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/io.h>static int ds18b20_probe(struct platform_device *pdev)
{struct resource *addr_res = NULL;   /* resources found */printk("probe!!!!!!!!!! \n");addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);if (addr_res == NULL) printk("get_re error");return 0;
}static int ds18b20_drv_remove(struct platform_device *pdev)
{return 0;
}static const struct of_device_id ds18b20_of_matches[] = {{ .compatible = "my-ds18b20", },    //和dts文件中名字匹配{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ds18b20_of_matches);static struct platform_driver ds18b20_driver = {.driver = {.name    = "ds18b20",       //可以与dts文件中名字不同.owner   = THIS_MODULE,.of_match_table = of_match_ptr(ds18b20_of_matches),},.probe   = ds18b20_probe,.remove  = ds18b20_drv_remove,};module_platform_driver(ds18b20_driver);MODULE_LICENSE("GPL");

编译,拷贝,加载模块

这里写图片描述

/************************以下为完全测试*************************/

这里写图片描述
成功获取到温度,有个小bug就是第一获取时温度有问题

以下是完全代码

#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/interrupt.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/crc32.h>
#include <linux/mii.h>
#include <linux/of.h>
#include <linux/of_gpio.h>#include <linux/of_net.h>
#include <linux/ethtool.h>
#include <linux/dm9000.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/slab.h>#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/io.h>int ds18_gpio = -1;#define GPIO_DS18B20    ds18_gpio#define DS18B20_IO_UP   gpio_set_value(GPIO_DS18B20, 1)
#define DS18B20_IO_DOWN     gpio_set_value(GPIO_DS18B20, 0)#define DS18B20_OUT     gpio_direction_output(GPIO_DS18B20, 1)
#define DS18B20_IN      gpio_direction_input(GPIO_DS18B20)static void ds18_write(uint16_t data )
{uint8_t i, temp;DS18B20_OUT;for(i=0; i<8; i++){temp = data & 0x01;data = data >> 1;if(temp)         //写1{DS18B20_IO_DOWN;udelay(6); DS18B20_IO_UP;udelay(64); }           else{DS18B20_IO_DOWN;udelay(60);DS18B20_IO_UP;udelay(10);}}}static uint8_t ds18_read(void)   //读位
{uint8_t data;DS18B20_OUT;DS18B20_IO_DOWN;udelay(6);DS18B20_IO_UP;DS18B20_IN;udelay(9);if(gpio_get_value(GPIO_DS18B20)==1){data =1;}else{data =0;}udelay(45);return data;
}static uint8_t ds18_reads(void){uint8_t i = 0,temp = 0,mydata = 0;for(i=0;i<8;i++){temp = ds18_read();mydata = mydata | (temp<<i); }udelay(2);return mydata;}static uint8_t ds18_reset(void){DS18B20_OUT;DS18B20_IO_DOWN;udelay(300);udelay(300);DS18B20_IO_UP;DS18B20_IN;  // 600 usudelay(100);if (gpio_get_value(GPIO_DS18B20) == 0){printk("reset bingo \n");return 0;}printk("reset fail \n");return -1;}static long ds18b20_ctl(struct file * file,unsigned int cmd,unsigned long num)
{uint8_t tp_msb = 0,tp_lsb = 0;uint32_t data;if(cmd){    //readprintk("star read \n");if (ds18_reset() != 0)goto error1;ds18_write(0xCC);udelay(1);ds18_write(0x44);     //转换温度//mdelay(100);//ssleep(1);if (ds18_reset() != 0)goto error1;ds18_write(0xCC);udelay(1);ds18_write(0xBE);   //读取温度tp_lsb=  ds18_reads();udelay(1);tp_msb=  ds18_reads();data = tp_msb<<8;data = data | tp_lsb;if( data < 0 )      data = (~data+1) * 625;    elsedata = data * 625;  printk("tmp = %d \n", data);}return 0;error1:printk("read error \n");return -1;}struct file_operations ds18b20_fops = {.unlocked_ioctl= ds18b20_ctl,};struct miscdevice  ds18b20_misc={.minor = 200,.name = "misc_ds18b20",.fops = &ds18b20_fops,};static int ds18b20_probe(struct platform_device *pdev)
{struct resource *addr_res = NULL;   /* resources found */int re = -1;printk("probe!!!!!!!!!! \n");ds18_gpio = of_get_named_gpio(pdev->dev.of_node, "gpios", 0);printk("%d\n", ds18_gpio);re = gpio_request(ds18_gpio, "ds18b20");if (re != 0) return -1;if (ds18_gpio > 0){gpio_direction_output(ds18_gpio, 1);}re = ds18_reset();            //检测是否存在if (!re){printk("finded ds18b20 \n");misc_register(&ds18b20_misc);return 0;}else{gpio_free(GPIO_DS18B20);printk("no find ds18b20 \n");return -1;}return 0;
}static int ds18b20_drv_remove(struct platform_device *pdev)
{gpio_free(ds18_gpio);return 0;
}static const struct of_device_id ds18b20_of_matches[] = {{ .compatible = "ds18b20", },{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ds18b20_of_matches);static struct platform_driver ds18b20_driver = {.driver = {.name    = "ds18b20",.owner   = THIS_MODULE,.of_match_table = of_match_ptr(ds18b20_of_matches),},.probe   = ds18b20_probe,.remove  = ds18b20_drv_remove,};module_platform_driver(ds18b20_driver);MODULE_LICENSE("GPL");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/265893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

六核cpu安装SQL Server 2005时报错,提示启动服务失败

2019独角兽企业重金招聘Python工程师标准>>> 新买的IBM3650M4的服务器上安装SQL server2005 安装到一半时&#xff0c;报"提示&#xff1a;SQL Server 服务无法启动。"错。 一开始以为是操作系统的问题&#xff0c;先重装了一遍&#xff0c;还是不行&…

网络编程知识预备(1) ——了解OSI网络模型

参考&#xff1a;简单了解OSI网络模型 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-03-18 20:07:09 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/114968802?spm1001.2014.3001.5502 根据需求摘抄自下面这篇文章&#xff0c;内容非常详…

antd表格显示分页怎么取消_真相!Word里怎么也删不掉的文档空白页原来是这样...

大家好&#xff0c;我是你们的海宝老师在Word里&#xff0c;经常会遇到这种情况&#xff1a;文档莫名其妙地多出一个或多个空白页&#xff0c;没啥内容却怎么也删不掉。不着急&#xff0c;咱们来一一分析。1、标题前的空白页像这种标题前面有空白&#xff0c;基本就是【段落】设…

网络编程知识预备(2) ——三次握手与四次挥手、流量控制(滑动窗口)、拥塞控制、半连接状态、2MSL

参考&#xff1a;浅显易懂的三次握手与四次挥手 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-03-19 09:33:20 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/114990198?spm1001.2014.3001.5502 参考&#xff1a;&#xff08;四十七&…

面向对象2

python之路——面向对象进阶 阅读目录 isinstance和issubclass反射setattr  delattr  getattr  hasattr__str__和__repr____del__item系列__getitem__  __setitem__  __delitem____new____call____len____hash____eq__回到顶部isinstance和issubclass isinstance(obj…

DM9000网卡原理与基地址设置

从上面可以看出DM9000的地址总线就一根&#xff0c;它不像CS8900那样地址总线和数据总线都齐全。而这里只有一根地址线(CMD)&#xff0c;16跟数据线&#xff0c;所以可以确定位宽为16位&#xff0c;而地址线为什么只有一根&#xff0c;这是DM9000决定的&#xff0c;看手册可以知…

网络编程知识预备(3) ——SOCKET、TCP、HTTP之间的区别与联系

参考&#xff1a;SOCKET,TCP,HTTP之间的区别与联系 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-03-19 11:54:01 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/114992140?spm1001.2014.3001.5502 参考&#xff1a;TCP连接、Http连接与S…

debian 9 安装后的配置,debian 9 开发环境。

注意&#xff1a;以下命令用sudo或者以root用户进行 一.Xterm&#xff08;在安装KDE桌面情况下&#xff09;的配置&#xff08;可以黏贴&#xff0c;复制&#xff09;&#xff1a; 首先在根目录下编辑文件.Xresources(没有可以创建) rootdebian:~# vim ~/.Xresources rootdebi…

嵌入式RT3070 AP模式移植

环境&#xff1a;ubuntu1~14.04.3 编译器&#xff1a;arm-none-linux-gnueabi-gcc-4.8.3 无线网卡为RT3070&#xff0c;驱动分为STA驱动和SoftAP驱动两种&#xff0c;STA驱动支持无线网卡工作在STA模式下&#xff0c;而SoftAP的驱动支持无线网卡工作在软AP的模式下&#xff0…

Wireshark抓包介绍和TCP三次握手分析

wireshark介绍 wireshark的官方下载网站&#xff1a; http://www.wireshark.org/ wireshark是非常流行的网络封包分析软件&#xff0c;功能十分强大。可以截取各种网络封包&#xff0c;显示网络封包的详细信息。 wireshark是开源软件&#xff0c;可以放心使用。 可以运行在Wind…

网络编程知识预备(4) ——了解应用层的HTTP协议与HTTPS协议

参考&#xff1a;简单了解HTTP协议与HTTPS协议 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-03-15 10:55:13 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/114807328?spm1001.2014.3001.5502 编程实现人脸识别需要基于人工智能平台&…

Django之orm查询

ORM相关 MVC或者MVC框架中包括一个重要的部分&#xff0c;就是ORM&#xff0c;它实现了数据模型与数据库的解耦&#xff0c;即数据模型的设计不需要依赖于特定的数据库&#xff0c;通过简单的配置就可以轻松更换数据库&#xff0c;这极大的减轻了开发人员的工作量&#xff0c;不…

智能家居 (2) ——设计模式的引入

目录设计模式的概念引入工厂模式的实现animal.hmainPro.ccat.cdog.cperson.c工厂模式的功能验证往期文章设计模式的概念引入 工厂模式的实现 所有代码最好在Source Insight下编写&#xff0c;并将所有代码进行关联&#xff0c;方便读写。 animal.h #include <stdio.h>s…

卷积核和全连接层的区别_「动手学计算机视觉」第十六讲:卷积神经网络之AlexNet...

前言前文详细介绍了卷积神经网络的开山之作LeNet&#xff0c;虽然近几年卷积神经网络非常热门&#xff0c;但是在LeNet出现后的十几年里&#xff0c;在目标识别领域卷积神经网络一直被传统目标识别算法(特征提取分类器)所压制&#xff0c;直到2012年AlexNet(ImageNet Classific…

vnc配置备忘录

因为我开发板上要用到Qt&#xff0c;所以我在服务器上安装了Qt的开发环境&#xff0c;为了能远程连接到服务器我安装了VNC&#xff0c; 中间也是遇到了很多问题&#xff0c;比如连接上去后&#xff0c;只显示一个控制台的窗口&#xff0c;只能使用命令行。后来几经周折才搞定先…

网络编程知识预备(5) ——libcurl库安装及其编程访问百度首页

本文为学习笔记&#xff0c;整合课程内容以及下列文章&#xff1a; 其中&#xff0c;libcurl函数库常用字段解读部分&#xff1a; 参考博文&#xff1a;原文地址 作者&#xff1a;冬冬他哥哥 目录Libcurl库简介Libcurl等三方库的通用编译方法三方库使用前通读方法库的配置、编…

智能家居 (9) ——人脸识别摄像头安装实现监控功能

目录摄像头模块安装安装mjpg-streamer库开启监控功能往期文章摄像头模块安装 注意&#xff1a;安装要下电安装&#xff0c;不能带电&#xff01;连接其他硬件模块的时候也是。 安装mjpg-streamer库 树莓派利用pi Camera模块&#xff0c;通过mjpg-streamer软件获取视频&#xf…

设备树和pinctrl粗解

上次文章中 我以DS18b20为例&#xff0c;在设备树中定义了ds18b20的资源&#xff08;device&#xff09;&#xff0c;当时是依葫芦画瓢&#xff0c;没有深入探究&#xff0c;本文主要探讨下pin在设备树中的描述 参考文章&#xff1a;Linux内核中的GPIO系统之&#xff08;3&…

八大排序算法(C语言实现)

摘自&#xff1a;八大排序算法&#xff08;C语言实现&#xff09; 作者&#xff1a;2021dragon 发布时间&#xff1a; 2021-05-16 10:46:37 网址&#xff1a;https://blog.csdn.net/chenlong_cxy/article/details/116563972 目录 直接插入排序希尔排序选择排序堆排序冒泡排序快…

codeforces 1060 A

https://codeforces.com/contest/1060/problem/A 题意&#xff1a;电话号码是以8开头的11位数&#xff0c;给你n 个数问最多可以有多少个电话号码 题解&#xff1a;min&#xff08;8的个数&#xff0c;n/11&#xff09; 代码如下&#xff1a; #include <map> #include &l…