驱动开发11-1 编写IIC驱动-读取温湿度数据
头文件 head.h
#ifndef __HEAD_H__
#define __HEAD_H__
#define GET_HUM _IOR('m', 1, int)
#define GET_TEM _IOR('m', 0, int)
#endif
应用程序 si7006.c
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include "head.h"int main(int argc, char const *argv[])
{char buf[128]={0};unsigned short hum,tem;float hum1,tem1;int fd = open("/dev/si7006",O_RDWR);if(fd < 0){printf("打开设备文件失败\n");exit(-1);}while(1){//读取温湿度数据ioctl(fd,GET_HUM,&hum);ioctl(fd,GET_TEM,&tem);//进行字节序转换hum = ntohs(hum);tem = ntohs(tem);//数据转换hum1 = (float)hum*125/65536-6;tem1 = (float)tem*175.72/65536-46.85;printf("hum = %f tem = %f\n",hum1,tem1);sleep(1);}close(fd);return 0;
}
驱动程序 iic.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/fs.h>
#include <linux/device.h>
#include "head.h"struct i2c_client *client1;
unsigned int major;
struct class *cls;
struct device *dev;
//封装读取温湿度数据的函数
short read_hum_tem_value(char reg)
{short value; //保存读到的温湿度数据char r_buf[] = {reg};//消息结构体的封装struct i2c_msg r_msg[] = {[0] = {.addr = client1->addr,.flags = 0,.len = sizeof(r_buf),.buf = r_buf,},[1] = {.addr =client1->addr,.flags = 1,.len = 2,.buf = (char *)&value,},};//发送消息int ret = i2c_transfer(client1->adapter,r_msg,2);if(ret != 2){printk("消息传输失败\n");return -1;}return value;
}
int mycdev_open(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{short hum,tem;int ret;switch ((cmd)){case GET_HUM:hum = read_hum_tem_value(0xE5);ret = copy_to_user((void *)arg,&hum,2);if(ret){printk("coyp_to_user err %d\n",__LINE__);}break;case GET_TEM:tem = read_hum_tem_value(0xE5);ret = copy_to_user((void *)arg,&tem,2);if(ret){printk("coyp_to_user err %d\n",__LINE__);}break;}return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
//定义操作方法结构体变量并复制
struct file_operations fops = {.open = mycdev_open,.unlocked_ioctl = mycdev_ioctl,.release = mycdev_close,
};
//给对象分配空间并且初始化
int i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{client1 = client;int ret;//float hum1,tem1;printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);//字符设备驱动的注册major = register_chrdev(0,"si7006",&fops);if(major < 0){printk("字符设备驱动注册失败\n");ret = major;goto out1;}printk("字符设备驱动注册成功\n");//向上提交目录cls = class_create(THIS_MODULE,"si7006");if(IS_ERR(cls)){printk("向上提交目录失败\n");ret = -PTR_ERR(cls);goto out2;}printk("向上提交目录成功\n");//向上提交设备节点信息dev = device_create(cls,NULL,MKDEV(major,0),NULL,"si7006");if(IS_ERR(dev)){printk("向上提交设备节点失败\n");ret = -PTR_ERR(dev);goto out3;}printk("向上提交设备节点成功\n");return 0;
out3:class_destroy(cls);
out2:unregister_chrdev(major,"si7006");
out1:return ret;
}
int i2c_remove(struct i2c_client *client)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);//设备信息的注销device_destroy(cls,MKDEV(major,0));//设备节点的销毁class_destroy(cls);//驱动的注销unregister_chrdev(major,"si7006");return 0;
}
//定义设备树匹配的表
struct of_device_id oftable[]={{.compatible="hqyj,si7006",},{},
};
struct i2c_driver i2c_drv={.probe=i2c_probe,.remove=i2c_remove,.driver={.name="si7006",.of_match_table=oftable,},
};
module_i2c_driver(i2c_drv);
MODULE_LICENSE("GPL");
效果演示


相关文章:
驱动开发11-1 编写IIC驱动-读取温湿度数据
头文件 head.h #ifndef __HEAD_H__ #define __HEAD_H__ #define GET_HUM _IOR(m, 1, int) #define GET_TEM _IOR(m, 0, int) #endif 应用程序 si7006.c #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #inc…...
上海中优城市万豪酒店推出全新国际IP童趣主题房,独特住宿体验中国首秀
2023年10月30日,中国上海 – 近日,上海中优城市万豪酒店正式推出由全球品牌娱乐公司孩之宝官方授权打造的小马宝莉和变形金刚主题客房,以创意客房、新奇体验和丰富礼遇,为童游家庭或年轻的动漫迷们开启沉浸式入住之旅,…...
zsh和bash之间互相切换
zsh->bash exec bashbash->zsh exec zsh...
Java - window系统快捷键大全
Ctrl 快捷键 介绍 Ctrl F 在当前文件进行文本查找 (必备) Ctrl R 在当前文件进行文本替换 (必备) Ctrl Z 撤销 (必备) Ctrl Y 删除光标所在行 或 删除选中的行 (必备) Ctrl X …...
深入理解数据结构(1)—用链表实现栈
栈是一种数据结构,链表也是一种数据结构。它们都是由基础的语法实现的。 如果一个数据结构可以用另外的数据结构来实现,那么可以有力的证明——“数据结构是一种思想”,是一种讲语法组合起来实现某种功能的手段 一、栈的特点——要实现哪些功…...
Jtti:debian安装firewalld错误怎么办
如果在Debian系统上安装Firewalld时出现错误,可以尝试以下步骤来解决问题: 更新软件包列表: 首先确保您的Debian系统的软件包列表是最新的。运行以下命令: sudo apt update 安装Firewalld: 使用以下命令安装Firewalld&…...
如何理解python中的*args和**kwargs
args用于表示可变数量的位置参数(Positional Arguments) kwargs 用于表示可变数量的关键字参数(Keyword Arguments)。 *args 来接收不定数量的位置参数 实例: def exampleFunc(*args):print(type(args))for arg in args:print…...
软考之软件工程基础理论知识
软件工程基础 软件开发方法 结构化方法 将整个系统的开发过程分为若干阶段,然后依次进行,前一阶段是后一阶段的工作依据按顺序完成。应用最广泛。特点是注重开发过程的整体性和全局性。缺点是开发周期长文档设计说明繁琐,工作效率低开发前要…...
香港服务器不稳定的几种情况
近年来,随着互联网的迅猛发展,香港作为一个重要的网络枢纽地区,扮演着连接中国内地和国际网络的重要角色。一些用户表示在使用香港服务器时可能会遇到不稳定的情况,导致访问困难、加载缓慢甚至无法连接。 为什么香港服务器会…...
报修软件有什么用?企业如何做好设备管理与维护?
在当今的商业环境中,设备设施的维护和管理已经成为企业运营的重要环节。无论是学校、酒店、物业等大型企事业单位,还是运维集成商、制造工厂等企业单位,都需要对设备设施进行有效的管理。报修软件作为一种智能化的解决方案,为设备…...
Go语言的键盘输入和打印输出
键盘输入和打印输出 一、打印输出 1.1 fmt包 fmt包实现了类似C语言printf和scanf的格式化I/O。格式化verb(‘verb’)源自C语言但更简单。 详见官网fmt的API:https://golang.google.cn/pkg/fmt/ 1.2 导入包 import "fmt"1.3 常…...
jenkins实践篇(2)—— 自动打tag的可回滚发布模式
大家好,我是蓝胖子,在上一篇我简单介绍了如何基于特定分支做自动编译和发布,在生产环境中,为了更加安全和快速回滚,我采取的是通过对代码打tag的方式来进行部署,下面我将详细介绍整个发布过程的逻辑。 发布…...
golang worker channel 模式
大概流程就是job -> JobQueue调度器循环获取JobQueue ,获取到的job ,再去异步获取等待可用的 worker,取出 chan Job,将job 写入改worker的 chan Jobworker 处理任务,先处理 case job : <-w.JobChannel: 处理完成后再将 chan…...
舔狗日记之好一条舔狗
闲来没事,爬了下vx《舔狗日记》,感觉挺有意思的,分享出来给大家看看。 PS:仅供娱乐,侵删。 舔狗2023 舔狗日记 2023年10月11日 晴天 你们根本不懂舔狗的快乐。被舔的人,无法预知接下来会不会继续被舔&…...
【地理位置识别】IP归属地应用的特点
IP归属地应用是一类用于确定特定IP地址的地理位置信息(通常是城市、地区或国家)的工具和服务。以下是IP归属地应用的几个主要特点: 地理位置识别: IP归属地应用主要用于确定IP地址的地理位置。这可以帮助组织更好地了解其网站访问…...
华为实验基础(2):路由器基础
一、路由器的分类 1、从功能、性能和应用方面划分: (1) 骨干路由器 :骨干路由器是实现主干网络互连的关键设备,通常采用模块化结构,通过热备 份、双电源和双数据通路等冗余技术提高可靠性 ,华…...
婚姻管理系统-使用bbst数据结构
使用到希尔排序和归并排序,文件存储 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <string.h> //名字的最大长度 #define NameMax 30 //全局的文件指针变量 FILE* file, * file_admin, * file_divorce; /…...
软件架构的概念
1.软件架构演化 为了适应用户的新需求、业务环境和运行环境的变化等,软件架构需要不断地进行自身的演化,也就是说软件架构的演化就是为了维持软件架构自身的有用性。 本质上讲,软件架构的演化就是软件整体结构的演化,演化过程涵盖…...
kubernetes存储-secrets
一、从文件创建 二、编写yaml文件 三、将Secret挂载到Volume中 四、向指定路径映射 secret 密钥 五、将Secret设置为环境变量 六、存储docker registry的认证信息...
Springboot使用EasyExcel导入导出Excel文件
1,准备Excel文件和数据库表结果 2,导入代码 1,引入依赖 <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifac…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...
聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇
根据 QYResearch 发布的市场报告显示,全球市场规模预计在 2031 年达到 9848 万美元,2025 - 2031 年期间年复合增长率(CAGR)为 3.7%。在竞争格局上,市场集中度较高,2024 年全球前十强厂商占据约 74.0% 的市场…...
轻量级Docker管理工具Docker Switchboard
简介 什么是 Docker Switchboard ? Docker Switchboard 是一个轻量级的 Web 应用程序,用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器,使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...
深入解析光敏传感技术:嵌入式仿真平台如何重塑电子工程教学
一、光敏传感技术的物理本质与系统级实现挑战 光敏电阻作为经典的光电传感器件,其工作原理根植于半导体材料的光电导效应。当入射光子能量超过材料带隙宽度时,价带电子受激发跃迁至导带,形成电子-空穴对,导致材料电导率显著提升。…...
Linux入门课的思维导图
耗时两周,终于把慕课网上的Linux的基础入门课实操、总结完了! 第一次以Blog的形式做学习记录,过程很有意思,但也很耗时。 课程时长5h,涉及到很多专有名词,要去逐个查找,以前接触过的概念因为时…...
CppCon 2015 学习:Simple, Extensible Pattern Matching in C++14
什么是 Pattern Matching(模式匹配) ❝ 模式匹配就是一种“描述式”的写法,不需要你手动判断、提取数据,而是直接描述你希望的数据结构是什么样子,系统自动判断并提取。❞ 你给的定义拆解: ✴ Instead of …...
