Linux驱动-单总线-DS18b20-驱动设备树配置-GPIO复用

news2026/5/7 19:20:42
提示DS18B20驱动配置设备树文章目录前言一、参考资料二、 原理图分析-配置设备树1、字符设备驱动框架-再分析-需求描述2、地板原理图简要分析DS18b20 引脚底板原理图简要分析实物图20pin的原理图pinctrl 引脚复用-可复用的引脚配置图3、配置设备树配置gpio1. ds18b20_gpio: gpio0_b02. compatible ds18b20;3. ds18b20-gpios gpio0 RK_PB0 GPIO_ACTIVE_HIGH;4. pinctrl-names default;5. pinctrl-0 ds18b20_gpio_ctrl;配置pinctrl1. pinctrl2. ds18b20_gpio3. ds18b20_gpio_ctrl: ds18b20-gpio-ctrl4. rockchip,pins 0 RK_PB0 RK_FUNC_GPIO pcfg_pull_none;两段配置的关系核心逻辑三、源码-原理分析-验证1、源码说明-加载驱动2、验证设备树配置的gpio节点是否生成 cd /proc/device-tree/3、检查设备树是否加载进入内核-ls -l /proc/device-tree/gpio0_b04、验证申请的设备号-cat /proc/devices5、验证申请的字符设备类-ls /sys/class/-ls /sys/class/sensors6、验证申请的字符设备 -ls -l /dev/-ls -l /dev/ds18b20总结前言这里还是结合前面的知识点前面文章已经讲解、总结、归纳了驱动框架、字符驱动框架里面还及到平台总线知识点。接下来就是设备树知识点。很早以前我们学习每个知识点都是 加载驱动、按照我们的demo 流程来进行知识点验证前面的温度传感器-DS18B20驱动框架编写 、温度传感器-DS18B20字符设备驱动框架 就是写了框架其实驱动还没有加载成功的比如平台总线驱动还没有识别到没有调用probe函数。一、参考资料这里我们把以前的相关知识点拿到这里规整一下总线设备知识点platform总线注册流程分析在总线下注册设备及设备注册流程分析Linux驱动之platform 总线设备注册流程分析总线驱动相关知识点驱动-在自定义总线上创建驱动-分析驱动注册流程总线、字符设备、相关知识点讯为:第十四期 | 单总线RK3568驱动指南第十四篇 单总线-第158章DS18B20编写字符设备驱动框架涉及到核心知识点alloc_chrdev_region // 动态申请字符设备号驱动-申请字符设备号涉及到核心知识点cdev_init //字符设备初始化 cdev_initcdev_add //字符设备的注册 - cdev_add驱动-注册字符设备涉及到核心知识点class_create() - 创建设备类device_create() - 创建设备节点驱动-创建设备节点gpio-pinctrl知识点GPIO 控制和操作-使用命令通过sysfs文件系统控制GPIO使用C程序通过sysfs文件系统控制gpio操作寄存器来控制GPIO-点亮LED灯将原理图中的一个引脚复用为gpio功能驱动GPIO-获取单个gpio描述符Linux驱动-GPIO基本函数apiLinux驱动-GPIO子系统与pinctrl子系统相结合温度传感器-DS18B20驱动框架编写温度传感器-DS18B20字符设备驱动框架其实我们这里用到的DS18B20外设然后整个链路把知识点串联起来而已之前相关知识点都学过的。 如果忘记 强烈建议自己再去补一补基础的东西忘记了不行的。二、 原理图分析-配置设备树1、字符设备驱动框架-再分析-需求描述在字符驱动设备框架温度传感器-DS18B20字符设备驱动框架中 我们对驱动源码进行了详细的分析的。但是我们没做什么我们只是写了框架平台总线设备并没有加载成功也就是说probe函数这个驱动的灵魂当设备树中compatible ds18b20的设备与驱动匹配成功时内核才会自动调用probe完成字符设备的完整注册流程。所以 我们要做的是什么配置gpio: 驱动层配置一个gpio给DS18b20外设来用配置pinCtrl: 但是系统里面默认的pin点可能是配置了其它的功能、或者 默认情况下不是gpio功能。 那么就需要用pin-ctrl进行引脚复用到GPIO功能这样外设才能正常使用匹配到gpio,实现2、地板原理图简要分析DS18b20 引脚DS18B20引脚如下这里DC 就是信号引脚需要一个GPIO来连接的那么就在主板上面找一个GPIO不就行了嘛。底板原理图简要分析参考资料topeet_rk3568_main_v1_7.pdf底板原理图实物图先看实物图 打算用这个20pin脚里面的GPIO0_B0的拐角作为GPIO控制来做DS18B20的信号连接。20pin的原理图在topeet_rk3568_main_v1_7.pdf底板原理图 里面去找那么就去找J39 的原理图如下我们看到了拐角17 对应的就是GPIO0_B0的拐角全称DVP_PWREN0_H_GPIO0_B0pinctrl 引脚复用-可复用的引脚配置图那么这个引脚DVP_PWREN0_H_GPIO0_B0我想用来做GPIO来用那么就要去配置pinctrl引脚复用继续看 引脚复用继续在topeet_rk3568_main_v1_7.pdf底板原理图 里面去找如下说明引脚DVP_PWREN0_H_GPIO0_B0可以复用的功能有CLK32K_IN 、CLK32K_OUTO、PCIE30X2_BUTTONRSTn、GPIO0_B03、配置设备树文件路径kernel/arch/arm64/boot/dts/rockchip/rk3568/rk3568-evb1-ddr4-v10.dtsi参考文档将原理图中的一个引脚复用为gpio功能-Linux驱动-GPIO子系统与pinctrl子系统相结合要求就是当有GPIO复用功能需求不应该无从下手应该很熟练的去配置。配置gpio在根节点中配置/{.......................ds18b20_gpio:gpio0_b0{compatibleds18b20;ds18b20-gpiosgpio0 RK_PB0 GPIO_ACTIVE_HIGH;pinctrl-namesdefault;pinctrl-0ds18b20_gpio_ctrl;statusokay;};}1. ds18b20_gpio: gpio0_b0ds18b20_gpio节点标签方便其他地方引用gpio0_b0节点名字随便写建议和引脚对应2. compatible “ds18b20”;驱动匹配字符串告诉内核这个设备要去找名字叫 ds18b20 的驱动来匹配、接管内核就是靠这个字段找到对应驱动3. ds18b20-gpios gpio0 RK_PB0 GPIO_ACTIVE_HIGH;这是最重要的一行指定 DS18B20 接在哪个 GPIO但是就是一个gpio描述符gpio0使用 GPIO0 控制器RK_PB0GPIO0_B0 引脚GPIO_ACTIVE_HIGH高电平有效单总线必须这样4. pinctrl-names “default”;定义引脚状态名称default 表示默认工作状态5. pinctrl-0 ds18b20_gpio_ctrl;关联引脚配置意思是去引用 pinctrl 里定义的 ds18b20_gpio_ctrl 引脚配置这是两段配置之间的 “桥梁”配置pinctrl在pinctrl 节点中配置pinctrl 相关信息pinctrl{.............ds18b20_gpio{ds18b20_gpio_ctrl:ds18b20-gpio-ctrl{rockchip,pins0 RK_PB0 RK_FUNC_GPIOpcfg_pull_none;};};}1. pinctrl引用 RK3568 的引脚控制器所有引脚复用、上下拉、驱动能力都在这里配置2. ds18b20_gpio给这组引脚配置起个名字随便写3. ds18b20_gpio_ctrl: ds18b20-gpio-ctrl这是真正被引用的配置节点第一段 pinctrl-0 就是引用它4. rockchip,pins 0 RK_PB0 RK_FUNC_GPIO pcfg_pull_none;参数功能参数 10GPIO 组号GPIO0参数 2RK_PB0引脚编号GPIO0_B0参数 3RK_FUNC_GPIO功能模式普通 GPIO 输入输出模式不是 I2C、UART、PWM 等复用功能参数 4pcfg_pull_none上下拉配置pull_none 无上下拉;DS18B20 必须外部接 4.7k 上拉电阻内部不能开上下拉两段配置的关系核心逻辑第一段设备节点 pinctrl-0ds18b20_gpio_ctrl↓ 引用 第二段pinctrl 引脚配置 ds18b20_gpio_ctrl{...}第一段告诉内核 “这是什么设备、用哪个引脚”第二段告诉内核 “这个引脚要怎么配置GPIO 模式、无上下拉”。核心点小结属性名称作用compatible匹配驱动ds18b20-gpios指定引脚pinctrl-0关联引脚配置rockchip,pins设置引脚为 GPIO 模式 无上下拉三、源码-原理分析-验证1、源码说明-加载驱动这里不演示源码用的是上一节中一摸一样的源码 温度传感器-DS18B20字符设备驱动框架 源码如下#includelinux/init.h#includelinux/module.h#includelinux/platform_device.h#includelinux/of.h#includelinux/fs.h#includelinux/cdev.h#includelinux/kdev_t.h#includelinux/slab.h#includelinux/gpio.h#includelinux/gpio/consumer.h#includelinux/delay.hstruct ds18b20_data{dev_t dev_num;// 什么一个字符设备号就是设备号struct cdev ds18b20_cdev;//声明一个字符设备structclass*ds18b20_class;//声明一个设备类struct device*ds18b20_device;//声明一个设备//device};intds18b20_open(struct inode*inode,struct file*file){return0;}ssize_tds18b20_read(struct file*file,char__user*buf,size_t size,loff_t*offs){return0;}intds18b20_release(struct inode*inode,struct file*file){return0;}struct file_operations ds18b20_fops{.opends18b20_open,.readds18b20_read,.releaseds18b20_release,.ownerTHIS_MODULE,};struct ds18b20_data*ds18b20;intds18b20_probe(struct platform_device*dev){intret;printk(This is probe \n);ds18b20kzalloc(sizeof(*ds18b20),GFP_KERNEL);if(ds18b20NULL){printk(kzalloc error \n);gotoerror_0;}// 第一步骤:申请设备号retalloc_chrdev_region(ds18b20-dev_num,0,1,myds18b20);//通过动态方式进行设备号注册if(ret0){printk(alloc_chrdev_region error \n);ret-EAGAIN;gotoerror_1;}// 第二步字符设备初始化 cdev_initcdev_init(ds18b20-ds18b20_cdev,ds18b20_fops);// 使用 cdev_init()函数初始化 cdev_test 结构体 并链接到cdev_test_ops 结构体ds18b20-ds18b20_cdev.ownerTHIS_MODULE;// 将 owner 字段指向本模块 可以避免在模块的操作正在被使用时卸载该模块// 第三步字符设备的注册 - cdev_addretcdev_add(ds18b20-ds18b20_cdev,ds18b20-dev_num,1);// 使用 cdev_add()函数进行字符设备的添加// 第四步class_create() - 创建设备类ds18b20-ds18b20_classclass_create(THIS_MODULE,sensors);//使用class_create进行类的创建类名称为sensorsif(IS_ERR(ds18b20-ds18b20_class)){printk(class_create error\n);retPTR_ERR(ds18b20-ds18b20_class);gotoerror_2;}// 第五步创建device device_create() - 创建设备节点ds18b20-ds18b20_devicedevice_create(ds18b20-ds18b20_class,NULL,ds18b20-dev_num,NULL,ds18b20);//使用device_create进行设备的创建设备名称为device_testif(IS_ERR(ds18b20-ds18b20_device)){printk(device_create error\n);retPTR_ERR(ds18b20-ds18b20_device);gotoerror_3;}return0;//error_4:// device_destroy(ds18b20-ds18b20_class, ds18b20-dev_num);error_3:class_destroy(ds18b20-ds18b20_class);error_2:cdev_del(ds18b20-ds18b20_cdev);unregister_chrdev_region(ds18b20-dev_num,1);error_1:kfree(ds18b20);error_0:returnret;}conststruct of_device_id ds18b20_match_table[]{{.compatibleds18b20},{},};struct platform_driver ds18b20_driver{.driver{.ownerTHIS_MODULE,.nameds18b20,.of_match_tableds18b20_match_table,},.probeds18b20_probe,};staticint__initds18b20_init(void){intret;retplatform_driver_register(ds18b20_driver);if(ret0){printk(platform_driver_register error\n);return-1;}return0;}staticvoid__exitds18b20_exit(void){device_destroy(ds18b20-ds18b20_class,ds18b20-dev_num);class_destroy(ds18b20-ds18b20_class);cdev_del(ds18b20-ds18b20_cdev);unregister_chrdev_region(ds18b20-dev_num,1);kfree(ds18b20);platform_driver_unregister(ds18b20_driver);}module_init(ds18b20_init);module_exit(ds18b20_exit);MODULE_LICENSE(GPL);编译程序make生成驱动程序ds18b20.ko然后执行驱动[rootRK356X:/mnt/sdcard]# chmod777ds18b20.ko[rootRK356X:/mnt/sdcard]# insmod ds18b20.ko[rootRK356X:/mnt/sdcard]#查看内核日志dmesg看到打印了This is probe这就说明设备树中gpio 配置成功了设备树中的compatible ds18b20;和驱动程序中的.name ds18b20定义驱动名称 name 对应上了。struct platform_driver ds18b20_driver{.driver{.ownerTHIS_MODULE,.nameds18b20,.of_match_tableds18b20_match_table,},.probeds18b20_probe,};[rootRK356X:/]# dmesg2、验证设备树配置的gpio节点是否生成cd /proc/device-tree/gpio配置如下 节点名称是gpio0_b0ds18b20_gpio:gpio0_b0{compatibleds18b20;ds18b20-gpiosgpio0 RK_PB0 GPIO_ACTIVE_HIGH;pinctrl-namesdefault;pinctrl-0ds18b20_gpio_ctrl;statusokay;};执行命令cd /proc/device-tree/如下存在名称为gpio0_b0的设备树节点说明设备树配置成功了的3、检查设备树是否加载进入内核-ls -l /proc/device-tree/gpio0_b0如上只是说明设备树已经配置好了那么相关属性是否配置到内核呢ds18b20_gpio:gpio0_b0{compatibleds18b20;ds18b20-gpiosgpio0 RK_PB0 GPIO_ACTIVE_HIGH;pinctrl-namesdefault;pinctrl-0ds18b20_gpio_ctrl;statusokay;};执行ls -l /proc/device-tree/gpio0_b0命令验证如下实际和自己在设备树中的配置对上了。[rootRK356X:/sys/firmware/devicetree/base]# ls-l/proc/device-tree/gpio0_b0 total0-r--r--r--1root root8Apr2608:06compatible-r--r--r--1root root12Apr2608:06ds18b20-gpios-r--r--r--1root root9Apr2608:06name-r--r--r--1root root4Apr2608:06phandle-r--r--r--1root root4Apr2608:06pinctrl-0-r--r--r--1root root8Apr2608:06pinctrl-names-r--r--r--1root root5Apr2608:06status[rootRK356X:/sys/firmware/devicetree/base]#4、验证申请的设备号-cat /proc/devices在驱动源码中申请设备号参考资料驱动-申请字符设备号// 第一步骤:申请设备号retalloc_chrdev_region(ds18b20-dev_num,0,1,myds18b20);//通过动态方式进行设备号注册查看设备号命令cat /proc/devices我们看到申请的字符设备号了。5、验证申请的字符设备类-ls /sys/class/-ls /sys/class/sensors如上源码创建设备类ds18b20-ds18b20_class class_create(THIS_MODULE,sensors);那就看一下设备类是否生成ls /sys/class/参考资料驱动-创建设备节点继续看一下字符设备类下面对应的软链接到哪一个设备命令ls -l /sys/class/sensors/6、验证申请的字符设备 -ls -l /dev/-ls -l /dev/ds18b20如上源码创建设备类// 第五步创建device device_create() - 创建设备节点ds18b20-ds18b20_devicedevice_create(ds18b20-ds18b20_class,NULL,ds18b20-dev_num,NULL,ds18b20);//使用device_create进行设备的创建设备名称为device_test参考资料驱动-创建设备节点命令ls -l /dev/查看当前设备: 如下结果说明字符设备是创建成功了。总结配置设备树、gpio定义声明、pinctrl配置复用、字符设备、平台总线 这些基本知识点之前都学过这里通过实际案例再次实操务必掌握务必在实际开发中搞清楚开发流程如果遇到问题知道怎么定位问题然后分析问题

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…