当前位置: 首页 > news >正文

Linux驱动入门实验班——SR501红外模块驱动(附百问网视频链接)

目录

 一、工作方式

二、接口图

三、编写思路

1.构造file_operations结构体

2.实现read函数

3.编写入口函数

4.编写中断处理函数

5.编写出口函数

6.声明出入口函数以及协议

四、源码

五、课程链接


一、工作方式

SR501人体红外感应模块有两种工作模式:
        通过跳线来设置是否可以重复触发,默认为L。其中L表示不可重复,H表示可重复。含义如下:

①不可重复触发方式:

感应到人体并输出高电平后,延时时间一结束,输出将自动从高电平变为低电平。

②重复触发方式:

        感应到人体后输出高电平后,在延时时间段内,如果有人体在其感应范围内活动,其输出将一直保持高电平,直到人离开后才延时将高电平变为低电平(感应模块检测到人体的每一次活动后会自动顺延一个延时时间段,并且以最后一次活动的时间为延时时间的起始点)。

在本次实验中,我们使用的是不可重复触发方式。

二、接口图

根据下面接口图,我们可以算出SR501模块所在的引脚编号为115。

三、编写思路

1.构造file_operations结构体

        对于SR501模块我们只需要读取他即可。

static struct file_operations sr501_drv = {.owner = THIS_MODULE,.read = sr501_drv_read,
};

2.实现read函数

先是构造了,一个环形buf用来存放数据,读取也是直接从这个环形buf中读取数据。此外,还引入了对应用层是使用阻塞还是非阻塞方式执行的判断。

使用到的函数:

  • wait_event_interruptible()
  •  copy_to_user()
  • DECLARE_WAIT_QUEUE_HEAD()

3.编写入口函数

先将gpio编号转换为中断号,然后再申请中断,然后就是注册file_operations结构体

使用到的函数:

  • gpio_to_irq()
  • request_irq()
  • register_chrdev()
  • class_create()
  • device_create()

4.编写中断处理函数

每当产生上升沿或者下降沿时,就会触发中断,这时候就读取引脚电平,将数据放入环形buf。

使用到的函数:

  •  gpio_get_value()

5.编写出口函数

 释放掉入口函数中注册的资源。

使用到的函数:

  • device_destroy()
  • class_destroy()
  • unregister_chrdev()
  • free_irq()

6.声明出入口函数以及协议

  • module_init()
  • module_exit()
  • MODULE_LICENSE("GPL")

四、源码

驱动

#include "asm-generic/errno-base.h"
#include "asm-generic/gpio.h"
#include "asm/uaccess.h"
#include <linux/module.h>
#include <linux/poll.h>#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/timer.h>#define BUF_LEN 128struct gpio_desc{int gpio;int irq;char *name;int key;struct timer_list key_time;
};static struct gpio_desc gpios[2] = {{115, 0, "sr501"},
};static int major;
static struct class *sr501_class;
static struct fasync_struct *sr501_fasync;static int r, w;
static int g_buf[BUF_LEN];static int is_empty(void)
{return (r == w);
}static int is_full(void)
{return (r = ((w + 1) % BUF_LEN));
}static void put_val(int val)
{if (!is_full()){g_buf[w] = val;w = (w + 1) % BUF_LEN;}
}static int get_val(void)
{int val = 0;if (!is_empty()){val = g_buf[r];r = (r + 1) % BUF_LEN;}return val;
}static DECLARE_WAIT_QUEUE_HEAD(gpio_wait);static ssize_t sr501_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{int val;int ret;if (!is_empty() && (file->f_flags & O_NONBLOCK)){return -EINVAL;}wait_event_interruptible(gpio_wait, !is_empty());val = get_val();ret = copy_to_user(buf, &val, 4);return 4;
}static struct file_operations sr501_drv = {.owner = THIS_MODULE,.read = sr501_drv_read,
};static irqreturn_t sr501_isr(int irq, void *dev_id)
{int val;int key;struct gpio_desc *gpio_desc = dev_id;val = gpio_get_value(gpio_desc->gpio);key = (gpio_desc->key) | (val << 8);put_val(key);wake_up_interruptible(&gpio_wait);return IRQ_HANDLED;
}static int __init sr501_drv_init(void)
{int ret;int count = sizeof(gpios) / sizeof(gpios[0]);int i;for (i = 0; i < count; i++){gpios[i].irq = gpio_to_irq(gpios[i].gpio);ret = request_irq(gpios[i].irq, sr501_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, gpios[i].name, &gpios[i]);}major = register_chrdev(0, "sr501_drv",&sr501_drv);sr501_class = class_create(THIS_MODULE, "sr501_class");device_create(sr501_class, NULL, MKDEV(major, 0), NULL, "sr501_drv");return ret;
}static void __exit sr501_drv_exit(void)
{int i;int count = sizeof(gpios) / sizeof(gpios[0]);device_destroy(sr501_class, MKDEV(major, 0));class_destroy(sr501_class);unregister_chrdev(major, "sr501_drv");for (i = 0; i < count; i++){free_irq(gpios[i].irq, &gpios[i]);}
}module_init(sr501_drv_init);
module_exit(sr501_drv_exit);MODULE_LICENSE
("GPL");

应用


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <poll.h>
#include <signal.h>int main(int argc, char **argv)
{int fd;int val;if (argc != 2){printf("Usage : %s <dev>\n", argv[0]);return -1;}fd = open(argv[1], O_RDWR);if (fd == -1){printf("open %s error\n", argv[1]);return -1;}while (1){if (read(fd, &val, 4) == 4){printf("get sr501 : %d\n", val);}else{printf("get sr501 : error\n");}}close(fd);return 0;
}

五、课程链接

40_模板1实战_SR501红外模块驱动编程 (100ask.net)icon-default.png?t=N7T8https://video.100ask.net/p/t_pc/course_pc_detail/video/v_636c762ce4b0276efeaea816?product_id=p_634cbce4e4b00a4f37500252&content_app_id=&type=6

相关文章:

Linux驱动入门实验班——SR501红外模块驱动(附百问网视频链接)

目录 一、工作方式 二、接口图 三、编写思路 1.构造file_operations结构体 2.实现read函数 3.编写入口函数 4.编写中断处理函数 5.编写出口函数 6.声明出入口函数以及协议 四、源码 五、课程链接 一、工作方式 SR501人体红外感应模块有两种工作模式&#xff1a; …...

windows C++- Com技术简介(上)

在介绍C和winrt与COM组件技术的关系之前&#xff0c;有必要介绍一下com组件技术&#xff0c;这项技术比较古老&#xff0c;但是它一直作为windows的基石存在。COM 是一类独立于平台且面向对象的分布式系统&#xff0c;用于创建可交互的二进制软件组件。 COM 技术是 Microsoft O…...

Jenkins持续集成工具学习

一、从装修厨房看项目开发效率优化 二、持续集成工具 三、JavaEE项目部署方式对比 四、JenkinsSVN持续集成环境搭建 五、JenkinsGitHub持续集成环境搭建...

Redis:查询是否包含某个字符/字符串之三

上一篇&#xff1a;Redis&#xff1a;查询是否包含某个字符/字符串之二-CSDN博客 摘要&#xff1a; 遍历key&#xff0c;在跟进value的类型遍历value是否包含指定字符串 search_strings &#xff0c;这里使用redis-py库&#xff0c;默认只能处理utf-8编码&#xff0c;如果存在…...

【Redis】数据类型详解及其应用场景

目录 Redis 常⻅数据类型预备知识基本全局命令小结 数据结构和内部编码单线程架构引出单线程模型为什么单线程还能这么快 Redis 常⻅数据类型 Redis 提供了 5 种数据结构&#xff0c;理解每种数据结构的特点对于 Redis 开发运维⾮常重要&#xff0c;同时掌握每种数据结构的常⻅…...

PARA-Drive:设计并行模型实现端到端自动驾驶

论文链接 https://openaccess.thecvf.com/content/CVPR2024/papers/Weng_PARA-Drive_Parallelized_Architecture_for_Real-time_Autonomous_Driving_CVPR_2024_paper.pdfhttps://openaccess.thecvf.com/content/CVPR2024/papers/Weng_PARA-Drive_Parallelized_Architecture_fo…...

vs2022 x64 C/C++和汇编混编 遇到的坑

vs2022 x64 C/C和汇编混编 遇到的坑 遇到的问题二、问题复现1.出错代码2.问题分析2.1 堆栈对齐问题 3.解决方案 总结奇数和偶数个寄存器的影响为什么 sub rsp, 8 对奇数个寄存器有用&#xff1f;结论 遇到的问题 0x00007FFFFAE24A29 (msvcp140.dll)处(位于 TestCompileConsole…...

PHP概述、环境搭建与基本语法讲解

目录 【学习目标、重难点知识】 什么是网站&#xff1f; 1. PHP 介绍 1.1. PHP 概述 1.1.1. PHP 是什么&#xff1f; 1.1.2. PHP 都能做什么&#xff1f; 1.2. PHP 环境搭建 1.2.1. PhpStudy 2. PHP 基本语法 2.1. PHP 语法入门 2.1.1. 第一个 PHP 程序 2.1.2. PHP …...

实现信创Linux麦克风摄像头录制(源码,银河麒麟、统信UOS)

随着信创国产化浪潮的来临&#xff0c;在国产操作系统上的应用开发的需求越来越多&#xff0c;其中一个就是需要在银河麒麟或统信UOS上实现录制摄像头视频和麦克风声音&#xff0c;将它们录制成一个mp4文件。那么这个要如何实现了&#xff1f; 一. 技术方案 要完成这些功能&a…...

深度学习9--目标检测

1.概念介绍 目标检测不仅可以检测数字&#xff0c;而且可以检测动物的种类、汽车的种类等。例如&#xff0c;自动驾驶车辆需要自动识别前方物体是车辆还是行人&#xff0c;需要自动识别道路两 旁的指示牌和前方的红绿灯颜色。对于自动检测的算法&#xff0c;有两个要求&#xf…...

第131天:内网安全-横向移动Kerberos 攻击SPN扫描WinRMWinRSRDP

案例一&#xff1a;域横向移动-RDP-明文&NTLM RDP利用的三种方式 1.直接在当前被控主机上进行远程连接 2.建立节点进行连接 3.端口转发&#xff0c;&#xff08;访问当前主机的2222端口等于访问目标的3389&#xff09; 第一种方式(动静太大) 直接利用被控主机进行远程连接…...

微信小程序的四种弹窗使用

​ 在做小程序的过程中&#xff0c;弹窗也算是非常实用的功能了&#xff0c;这几天写的几个功能就用到了弹窗&#xff0c;也可能是初学者的问题&#xff0c;比较菜&#xff0c;想找一个可以带图片的自定义的弹窗&#xff0c;&#xff0c;这里简单介绍一下官方封装好的四个弹窗…...

我的第一个CUDA程序

MatAdd算法 实现两个矩阵对应元素相加 #include <stdio.h> #include <stdlib.h>// 矩阵加法函数 void MatAdd(int height, int width) {// 在主机内存中为 A、B 和 C 分配内存float* A (float*)malloc(height * width * sizeof(float));float* B (float*)malloc…...

workerman下的webman路由浏览器跨域的一种问题

软件版本 "php": ">7.2", "workerman/webman-framework": "^1.5.0",问题情景 使用“分组路由”做API接口前后端分离跨域&#xff0c;在接口测试工具调试是能正常获取数据的&#xff1b;但在网页浏览器上调试就遇到了CORS、404的错…...

Windows11 -MASKRCNN-部署测试

文章目录 Detectron2环境配置搭建python 环境安装Cuda \CUDNN 、PyTorch、 torchvision、cudatoolkit1、Cuda \CUDNN2、 PyTorch、 torchvision、cudatoolkit进入python测试&#xff1a;错误信息 3、detectron2环境在安装detecteron中&#xff0c;遇到报错&#xff1a;编译的时…...

函数(子程序)的常见、易混淆概念详解【对初学者有帮助】

C语⾔中的函数也被称做子程序&#xff0c;意思就是⼀个完成某项特定的任务的⼀小段代码。 C语⾔标准中提供了许多库函数&#xff0c;点击下面的链接可以查看c语言的库函数和头文件。 C/C官⽅的链接&#xff1a;https://zh.cppreference.com/w/c/header 目录 一、函数头与函…...

TiDB-从0到1-DM工具

TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCCTiDB-从0到1-部署篇TiDB-从0到1-配置篇TiDB-从0到1-集群扩缩容TiDB-从0到1-数据导出导入TiDB-从0到1-BR工具 一、DM原理 支持全量抽取数据\检测新的数据变化同步到下游实例…...

AppScan——Web 应用安全扫描的得力工具

一、引言 在当今数字化时代&#xff0c;Web 应用成为企业业务的重要支撑&#xff0c;但同时也面临着各种安全威胁。AppScan 作为一款专业的 Web 应用安全扫描工具&#xff0c;为保障 Web 应用的安全性提供了有力的支持。本文将对 AppScan 进行详细介绍&#xff0c;包括其功能、…...

虚幻5|AI行为树,进阶篇

一&#xff0c;打开敌人的角色蓝图&#xff0c;编写以下蓝图&#xff0c;该蓝图只是创建一个敌人并非ai行为树 1.编写蓝图 2.打开主界面&#xff0c;创建一个导航网格体积&#xff0c;上一章都有讲&#xff0c;在添加体积这里面&#xff0c;找到导航网格体积&#xff0c;点击创…...

在 Spring Boot 中配置 Tomcat 监听多个端口

在现代微服务架构中&#xff0c;应用程序可能需要监听多个端口&#xff0c;以支持不同的服务或协议。Spring Boot 提供了灵活的配置选项&#xff0c;使得这一需求变得简单而高效。本文将介绍如何在 Spring Boot 中配置 Tomcat 以监听多个端口&#xff0c;并简要说明其中一些关键…...

stm32f407新建项目工程及烧录

1、新建一个文件夹&#xff0c;打开keil5将项目工程放入文件夹中 2、弹出选择对应型号设备 3、弹出选择对应库 可以看见出现下图&#xff1a;感叹号表示有错 最后如图所示&#xff1a;点击ok就行了 4、创建对应的文件夹存放文件 4、建立main.c 5、添加对应的设置 最后写一个空白…...

c++中加不加const的值传递和引用传递的区别

文章目录 可以修改参数值的比较值传递(int x)和引用传递(int &x)使用const不修改参数值的比较值传递(const int x)和引用传递(const int &x)1. const int x 示例2. const int &x 示例 可以修改参数值的比较值传递(int x)和引用传递(int &x) #include <iost…...

Qt的窗口设置

本文介绍Qt的窗口设置。 采用Qt开发界面程序&#xff0c;会涉及到窗口的设置&#xff0c;如窗口标题栏是否显示&#xff0c;是否有最小&#xff0c;最大化按钮等&#xff0c;窗口当前显示最小化&#xff0c;最大化等。本文简要介绍常用的窗口设置方法。 1.窗口属性 窗口属性…...

51单片机-LCD1602显示屏

简介 是一个液晶显示屏&#xff0c;通过电压对显示区域进行控制&#xff0c;有电就显示。 能够同时显示32个字符&#xff0c;分为两行&#xff0c;一行显示16个字符。可以显示的内容只能是字母、数字或者一些特殊符号。 使用ASCII码来让LCD1602来显示对应的字符。 电路图 …...

多模态分析代理 MAIA:多智能体解决 视觉模型 黑盒问题

多模态分析代理 MAIA&#xff1a;多智能体解决 视觉模型 黑盒问题 论文&#xff1a;https://arxiv.org/pdf/2404.14394 代码&#xff1a;https://github.com/multimodal-interpretability/maia 提出背景 神经网络方法提取的特征&#xff0c;没有可解释性。 数据在通过多个层…...

AT360-6T杭州中科微单频高精度授时模块场景应用

AT360-6T是一款高性能多系统卫星定位授时模块&#xff0c;基于自主研发的北斗多系统SOC芯片&#xff0c;可以同时接收中国的BDS(北斗二号和北斗三号)、美国的GPS、俄罗斯的GLONASS、欧盟的 GALILEO 和日本的QZSS等多个卫星导航系统的GNSS信号来实现多系统联合定位授时&#xff…...

Python酷库之旅-第三方库Pandas(081)

目录 一、用法精讲 336、pandas.Series.str.rpartition方法 336-1、语法 336-2、参数 336-3、功能 336-4、返回值 336-5、说明 336-6、用法 336-6-1、数据准备 336-6-2、代码示例 336-6-3、结果输出 337、pandas.Series.str.slice方法 337-1、语法 337-2、参数 …...

C语言基础⑩——构造类型(结构体)

一、数据类型分类 1、基本类型 整数型 短整型&#xff1a;short&#xff08;2个字节&#xff09;&#xff1b;整型&#xff08;默认&#xff09;&#xff1a;int&#xff08;4个字节&#xff09;&#xff1b;长整型&#xff1a;long&#xff08;8个字节&#xff09;&#xf…...

宝兰德荣获openEuler项目群青铜捐赠人称号,共筑开源生态繁荣新篇章

近日&#xff0c;开放原子开源基金会正式公布了新增捐赠人名单&#xff0c;宝兰德凭借在开源领域的卓越贡献与深厚实力&#xff0c;被授予openEuler项目群青铜捐赠人称号。 开放原子开源基金会是致力于推动全球开源事业发展的非营利机构&#xff0c;于2020年6月在北京成立。开放…...

【Python单元测试】学习笔记3

文章目录 08.PyTest框架什么是PyTestPyTest的优点PyTest的测试环境PyTest常用参数跳过测试 09.PyTest fixture基础PyTest fixture定义和使用引用多个Fixture 10. conftest.pyconftest.py的用途 11. 参数化测试用例为什么需要参数化测试用例使用parameterizer插件实现使用pytest…...

尼高网站设计公司/香水推广软文

大家好&#xff0c;我是乔戈里。最近有一位小学弟成功去了腾讯&#xff0c;洋哥找他要了一些面试相关的资料&#xff0c;内容涵盖计算机基础、Java、分布式、大厂面经&#xff0c;质量非常高&#xff01;&#xff01;&#xff01;不要再看那些到处拼凑出来的面试题了&#xff0…...

怎么编写自己的网站/太原seo排名优化公司

前言什么是Mysql&#xff1f;你真的知道吗&#xff1f;MySQL官方对索引的定义为&#xff1a;索引(Index)是帮助MySQL高效获取数据的数据结构。数据库查询是数据库的最主要功能之一&#xff0c;我们都希望查询数据的速度能尽可能的快&#xff0c;因此数据库系统的设计者会从查询…...

wordpress慕课/宁波seo推荐推广平台

推荐算法(1)&#xff1a;协同过滤总结 推荐算法(2)&#xff1a;基于内容的推荐 推荐算法&#xff08;3&#xff09;&#xff1a;利用用户标签数据 推荐算法&#xff08;4&#xff09;利用上下文信息 推荐算法&#xff08;5&#xff09;利用社交网络数据 推荐算法&#xff08;6&…...

网站默认首页/网络广告策划书范文

volatile关键字区分C程序员和嵌入式系统程序员的最基本的问题:嵌入式系统程序员经常同硬件、中断、RTOS等等打交道&#xff0c;所有这些都要求使用volatile变量。不懂得volatile内容将会带来灾难。 volatile的作用是作为指令关键字&#xff0c;确保本条指令不会因编译器的优化而…...

体育网站界面该怎样做/网站seo策划方案案例分析

原文链接&#xff1a;https://blog.csdn.net/know9163/article/details/80554769#commentBox Eclipse背景颜色设置&#xff08;设置成豆沙绿色保护眼睛&#xff0c;码农保护色&#xff09; 原文链接&#xff1a;https://blog.csdn.net/l0605020112/article/details/25829121转载…...

网站建设课程设计的必要性/互联网推广引流公司

2.2. 数据的绑定 前面说过了&#xff0c;SpringMVC是方法级的映射&#xff0c;那么Spring是如何处理方法签名的&#xff0c;又是如何将表单数据绑定到方法参数中的&#xff1f;下面我们就来讨论这个问题。2.2.1. 处理方法签名 首先&#xff0c;我们可以在方法签名中放入CookieV…...