当湿度达到70蜂鸣器警报

news2024/11/29 14:52:43

1.编写设备树,添加蜂鸣器等设备

 驱动代码:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include "si7006.h"
#include <linux/of_gpio.h>
#include <linux/gpio.h>
int major;
struct class *cls;
struct device *dev;
//tclient指向的结构体,存储设备驱动和总线驱动匹配成功的信息
struct i2c_client *tclient;
//指向gpio节点
struct device_node *node;
//定义结构体指针指向gpio编号
struct gpio_desc *gpiono;
int rcv;
//获取温湿度的函数
int i2c_read_hum_tem(unsigned char reg)
{
    int  ret;
    char r_buf[]={reg}; //地址放到数组中,读取消息
    unsigned short val; //读的数据
    //设备驱动将要收发的消息放到结构体中
    struct i2c_msg r_msg[]={
        [0]={
            .addr=tclient->addr,
            .flags=0,
            .len=1,  //发送的地址长度是8bit一字节
            .buf=r_buf,
        },
        [1]={
            .addr=tclient->addr,
            .flags=1,
            .len=2,
            .buf=(char*)&val,
        }
    };
    //消息传输
    ret=i2c_transfer(tclient->adapter,r_msg,ARRAY_SIZE(r_msg));
    if(ret!=ARRAY_SIZE(r_msg))
    {
        printk("获取温湿度数据失败\n");
        return -EAGAIN;
    }

    return val;
}
int si7006_open(struct inode *inode, struct file *file)
{
    printk("open\n");
    return 0;
}
long si7006_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
        int tem,hum;
        int ret;
        switch(cmd)
        {
            case GET_HUM:
                hum=i2c_read_hum_tem(0xe5);
                ret=copy_to_user((void*)arg,(void*)&hum,sizeof(int));
                if(ret)
                {
                    printk("copy to user failed\n");
                    return -EINVAL;
                }
                break;
            case GET_TEM:
                tem=i2c_read_hum_tem(0xe3);
                ret=copy_to_user((void*)arg,(void*)&tem,sizeof(int));
                if(ret)
                {
                    printk("copy to user failed\n");
                    return -EINVAL;
                }
                break;
            case FENGM:
                gpiod_set_value(gpiono,1);
                break;
        }
    return 0;
}
int si7006_close(struct inode *inode, struct file *file)
{
    printk("close\n");
    return 0;
}
struct file_operations fops={
    .open=si7006_open,
    .unlocked_ioctl=si7006_ioctl,
    .release=si7006_close,
};
//注册字符设备驱动
int chrdev(void){
        major=register_chrdev(0,"si7006",&fops);
        if(major<0)
        {
            printk("字符设备驱动注册失败\n");
            return major;
        }
        printk("字符设备驱动注册成功\n");
        //自动创建设备节点
        cls=class_create(THIS_MODULE,"si7006");
        if(IS_ERR(cls))
        {
            printk("向上提交目录失败\n");
            return PTR_ERR(cls);
        }
        printk("向上提交目录成功\n");
        dev=device_create(cls,NULL,MKDEV(major,0),NULL,"si7006");
        if(IS_ERR(dev))
        {
            printk("向上提交设备信息失败\n");
            return PTR_ERR(dev);
        }
        printk("向上提交设备信息成功\n");
        return 0;
    }
 //定义一个probe函数
    int si7006_probe(struct i2c_client *client,const struct i2c_device_id *id)
    {
        tclient=client;//将总线驱动指针编程全局的
        
        //注册字符设备驱动
        rcv=chrdev();
        //获取节点信息
        node=of_find_node_by_name(NULL,"extend_dev");
        if(node==NULL)
        {
            printk("通过名字解析设备树节点失败\n");
            return -EFAULT;
        }
        printk("设备树解析成功\n");
        //获取并申请gpio编号,键值fengm
        gpiono=gpiod_get_from_of_node(node,"fengm",0,GPIOD_OUT_LOW,NULL);
        if(IS_ERR(gpiono))
        {
            printk("获取gpiono 失败\n");
            return PTR_ERR(gpiono);
        }
        printk("获取gpiono 成功\n");

        return 0;
    }
    //设备分离后执行remove
    int si7006_remove(struct i2c_client *client)
    {
        gpiod_set_value(gpiono,0);
        //销毁设备节点
        device_destroy(cls,MKDEV(major,0));
        //销毁目录
        class_destroy(cls);
        //驱动注销
        unregister_chrdev(major,"si7006");
        printk("%s:%d",__func__,__LINE__);
        return 0;
    }
   struct of_device_id oftable[]={
        {
            .compatible="hqyj,si7006",
        },
        {},
    };
    //热插拔宏,可以在插入硬件时,自动安装驱动
    MODULE_DEVICE_TABLE(of,oftable);
    //对象初始化
    struct i2c_driver si7006={
        .probe=si7006_probe,
        .remove=si7006_remove,  
        .driver={
            .name="tem_hum_driver",  //按名字匹配,只能匹配一个设备
            .of_match_table=oftable,//设备树匹配     
        }, 
    };

module_i2c_driver(si7006);
MODULE_LICENSE("GPL");

 应用层代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include "si7006.h"
int main(int argc, char const *argv[])
{
    int hum,tem;
    float hum1,tem1;
    int ret;
    int ubuf[20];
    int fd=open("/dev/si7006",O_RDWR);
    if(fd<0)
    {
        printf("打开设备文件失败\n");
        exit(-1);
    }
    while(1)
    {
        //通过ioctl获取温湿度,放到tem,hum所在的地址
        ioctl(fd,GET_TEM,&tem);
        ioctl(fd,GET_HUM,&hum);
        //大端转小端
        hum=ntohs(hum);
        tem=ntohs(tem);
        //温湿度转换
        hum1=125.0*hum/65536-6;
        tem1=175.72*tem/65536-46.85;
        printf("tem:%f hum=%f\n",tem1,hum1);
        //当湿度达到70触发警报---PB6蜂鸣器
        if(hum1>=70)
        {
            ioctl(fd,FENGM);
            printf("警报\n");
        }
        sleep(1);

    }
    return 0;
}

头文件:

#ifndef __SI7006_H__
#define __SI7006_H__
//命令码封装,方向,大小,类型m,功能0
#define GET_TEM _IOR('m',0,int)
#define GET_HUM _IOR('m',1,int)
#define FENGM _IOW('u',3,int)
#endif

报错:

 [root@fsmp1a /]#rmmod driver.ko
rmmod: can't unload module 'driver': Device or resource busy

解决办法:

vi  /proc/devices

删除驱动信息,重启开发板

实验现象: 

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

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

相关文章

QCSPCChart for Java R3x0 Crack

Java 的 SPC 控制图工具 版本 3.04 QCSPCChart添加变量控制图&#xff08;X-Bar R、X-Bar Sigma、Individual Range、Median Range、EWMA、MA、MAMR、MAMS 和 CuSum 图&#xff09;、属性控制图&#xff08;p-、np-、c-、u- 和DPMO 图&#xff09;、频率直方图和 Pareto 图到…

[附源码]Python计算机毕业设计Django的旅游景点管理系统的设计与实现

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

[附源码]Python计算机毕业设计SSM老年公寓管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

计算机编程

文章目录计算机编程计算机编程语言计算机编程 人与人之间信息&#xff08;如想法、思想等&#xff09;的交流和传递&#xff0c;需要借助双方都能听得懂的语言。人和计算机之间实现交流也是如此&#xff0c;需要借助一种人和计算机都能理解的语言&#xff0c;这种语言称为编程…

LCHub低代码社区:旧的低代码,腾讯怎么讲出新故事

腾讯微搭的对手从来都不是钉钉。 低代码是 " 旧瓶装新酒 " 吗? 低代码风潮在国内兴盛已有两年,但也并不是已经被所有人接受,有不少开发者还保有否定、抵触的态度。 那为什么我们还认为这是一个不可逆的趋势呢? 这里先看下被否定的原因,LCHub在调研中听到的主…

怎么把PDF转换成图片?这三种转换方法都可以实现

怎么把PDF文件的内容转换成图片来使用呢&#xff1f;大家在办公或者是学习的过程中没少使用过PDF文件&#xff0c;有的文件我们翻阅起来会比较费时间&#xff0c;因为文件的内容多&#xff0c;这时候我们只需要把文件内容转成图片就可以解决这一问题&#xff0c;想要使用哪部分…

手把手带你开发你的第一个前端脚手架

开发一个简单的脚手架 1.创建 npm 项目 首先创建一个文件夹&#xff0c;然后进入到该文件夹目录下&#xff0c;执行 npm init -y 2.创建脚手架入口文件bin/index.js&#xff0c;在index.js中添加如下代码 #!/usr/bin/env nodeconsole.log(hello cli) 3.配置 package.json&a…

YOLOv5如何训练自己的数据集

目录 一、标注 1.1 标注软件下载labelimg 下载地址&#xff1a;mirrors / tzutalin / labelimg GitCode 1.2 json转txt 1.3 xml转txt 二、修改配置文件 2.1 建立文件目录 2.2 修改wzry_parameter.yaml文件 三、开始训练 3.1 2.结果 四、识别检测detect.py 1.调参找…

Jetson NX系统烧录以及CUDA、cudnn、pytorch等环境的安装

安装虚拟机和Ubuntu18.04环境 这两步比较简单&#xff0c;所以略了。虚拟机的配置需要注意硬盘空间大一点&#xff0c;至少40G。 安装sdk-manager NVIDIA SDK Manager下载地址&#xff1a;https://developer.nvidia.com/drive/sdk-manager sudo dpkg -i sdkmanager_1.9.0-…

YOLOv5和YOLOv7环境(GPU)搭建测试成功

本来是用doc写的&#xff0c;直接复制到这里很多图片加载缓慢&#xff0c;我直接把doc上传到资源里面了&#xff0c;0积分下载&#xff1a; (10条消息) YOLOv5和YOLOv7开发环境搭建和demo运行-Python文档类资源-CSDN文库 一、环境搭建 1.1 环境搭建参考链接 YOLO实践应用之…

uni-app 超详细教程(一)(从菜鸟到大佬)

一&#xff0c;uni-app 介绍 &#xff1a; 官方网页 uni-app 是一个使用 Vue.js 开发所有前端应用的框架&#xff0c;开发者编写一套代码&#xff0c;可发布到iOS、Android、Web&#xff08;响应式&#xff09;、以及各种小程序&#xff08;微信/支付宝/百度/头条/飞书/QQ/快手…

百度集团副总裁吴甜发布文心大模型最新升级,AI应用步入新阶段

11月30日&#xff0c;由深度学习技术与应用国家工程研究中心主办、百度飞桨承办的WAVE SUMMIT2022深度学习开发者峰会如期举行。百度集团副总裁、深度学习技术及应用国家工程研究中心副主任吴甜带来了文心大模型的最新升级&#xff0c;包括新增11个大模型&#xff0c;大模型总量…

PyQt5_寻找顶(底)背离并可视化

技术指标的背离是指技术指标曲线的波动方向与价格曲线的趋势方向不一致&#xff0c;是使用技术指标最为重要的一点。在股市中&#xff0c;常见的技术指标的背离分为两种常见的形式&#xff0c;即顶背离和底背离。背离是预示市场走势即将见顶或者见底的依据&#xff0c;在价格还…

计算机组成原理习题课第四章-1(唐朔飞)

计算机组成原理习题课第四章-1&#xff08;唐朔飞&#xff09; ✨欢迎关注&#x1f5b1;点赞&#x1f380;收藏⭐留言✒ &#x1f52e;本文由京与旧铺原创&#xff0c;csdn首发&#xff01; &#x1f618;系列专栏&#xff1a;java学习 &#x1f4bb;首发时间&#xff1a;&…

k8s部署手册

一、基础配置 1.修改主机名 hostnamectl set-hostname k8s-master01 hostnamectl set-hostname k8s-master02 hostnamectl set-hostname k8s-master03 hostnamectl set-hostname k8s-node01 hostnamectl set-hostname k8s-node022.添加 主机名与IP地址解析 cat > /etc/hos…

LINUX安装openssl

openssl 官网下载 https://www.openssl.org/source/old/ 1、解压openssl包&#xff1a; tar -xzf openssl-1.1.1n.tar.gz2、得到openssl-1.1.1n目录&#xff0c;然后进入openssl-1.1.1n目录中&#xff0c;安装openssl到 /usr/local/openssl 目录&#xff0c;安装之后&#xff…

[附源码]Python计算机毕业设计SSM联动共享汽车管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

如何在 SwiftUI 中创建条形图

条形图以矩形条的形式呈现数据的类别,其宽度和高度与它们表示的值成比例。本文将展示如何创建一个垂直条形图,其中矩形的高度将代表每个类别的值。 系列文章 如何在 SwiftUI 中创建条形图SwiftUI 中的水平条形图在 iOS 16 中用 SwiftUI Charts 创建一个折线图在 iOS16 中用 …

在 Node.js 中操作 Redis

在 Node.js 中操作 Redis Node.js 中可以操作 Redis 的软件包推荐列表&#xff1a;https://redis.io/clients#nodejs。 推荐下面两个&#xff1a; node-redisioredis 这里主要以 ioredis 为例。 ioredis 是功能强大的 Redis 客户端&#xff0c;已被世界上最大的在线商务公司…

MyBatis详解(一)

MyBatis简单介绍 【1】MyBatis是一个持久层的ORM框架【Object Relational Mapping&#xff0c;对象关系映射】&#xff0c;使用简单&#xff0c;学习成本较低。可以执行自己手写的SQL语句&#xff0c;比较灵活。但是MyBatis的自动化程度不高&#xff0c;移植性也不高&#xff…