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

news2024/11/15 13:45:42

目录

 一、工作方式

二、接口图

三、编写思路

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 128

struct 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

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

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

相关文章

PMP和软考高项知识的重叠和差异

PMP和高项是项目管理证书&#xff0c;备考了高项之后&#xff0c;也可以参加PMP考试&#xff0c;今天我们就来说一说PMP和高项知识的重叠度以及差异。&#xff08;文末PMP资料&#xff09; 一、知识体系的重叠 1、 项目管理过程 PMP和高项都强调项目管理的全过程&#xff0c;包…

电脑屏幕录制指南,2024四大免费录屏软件推荐!

无论是制作教学视频、录制在线课程、捕捉游戏精彩瞬间&#xff0c;还是进行远程技术支持&#xff0c;一款优秀的录屏软件都是必不可少的工具。今天&#xff0c;我们就来聊聊几款免费且功能强大的录屏软件。 Foxit录屏大师 链接&#xff1a;www.foxitsoftware.cn/REC/ Foxit录…

BGP 反射器联邦实验

要求&#xff1a; 1.如图连接网络&#xff0c;合理规划IP地址&#xff0c;AS 200内IGP协议为OSPF 2.R1属于AS 100&#xff1b;R2-R3-R4小AS 234 R5-R6-R7小AS 567&#xff0c;同时声明大AS 200&#xff0c;R8属于AS 300 3.R2-R5 R4-R7 之间为联邦EBGP邻居关系 4.R1-R8之…

实时捕捉与追溯:得物基于 eBPF 打造云上网络连接异常摄像头

近期我们容器 SRE 团队基于 eBPF 技术建设网络连接异常感知能力&#xff0c;灰度上线过程中发现了生产环境 10 以上的应用配置错误、程序 Bug 等问题。在和应用负责同学同步风险过程中&#xff0c;大家都挺好奇我们如何实现在对应用无侵入的情况下发现服务连接异常的。本篇文档…

贷齐乐hpp+php特性注入

文章目录 运行过程waf第一层waf拦截第二层waf拦截 数据库查询语句注入思路注入 运行过程 foreach ($_REQUEST as $key > $value) {$_REQUEST[$key] dowith_sql($value);}$request_uri explode("?", $_SERVER[REQUEST_URI]);if (isset($request_uri[1])) {$rewr…

77.游戏分析工具计算数据偏移

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;易道云信息技术研究院 上一个内容&#xff1a;76.游戏分析工具读取内存存到对象数据分析器一 以它的代码为基础进行修改 COBJContext…

免费领取 | S-SDLC差距分析2024发布会,服务名额先到先得

​2024全新版S-SDLC研发安全能力成熟度模型即将发布&#xff01;可帮助企业进一步引入行业最佳实践&#xff0c;弥补安全开发能力短板&#xff0c;快速提升软件安全开发整体水平。 8月15日&#xff0c;我们将开启直播&#xff0c;正式发布2024全新版S-SDLC研发安全能力成熟度模…

代码随想录算法训练营第十五天

力扣题部分: 110.平衡二叉树 题目链接:. - 力扣&#xff08;LeetCode&#xff09; 题面: 给定一个二叉树&#xff0c;判断它是否是平衡二叉树 平衡二叉树 是指该树所有节点的左右子树的深度相差不超过 1 思路(递归): 还是递归三部曲(关于三部曲的具体内容和对递归看法建议可见昨…

Vulnhub JIS-CTF靶机详解

项目地址 https://www.vulnhub.com/entry/jis-ctf-vulnupload,228/https://www.vulnhub.com/entry/jis-ctf-vulnupload,228/ 修改靶机的网卡 开机时长按shift&#xff0c;进入此页面 选择root模式进入 将只读模式改为读写模式 mount -o remount,rw / 查看本机的网卡名称 …

【数据分享】《青海省统计年鉴》2000-2023

而今天要限时免费分享的数据就是2000-2023年间出版的《青海省统计年鉴》并以多格式提供免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 青海省&#xff0c;位于中国西北部&#xff0c;青藏高原的东北部&#xff0c;是一个资源丰富、民族众多的地区。…

利用WebSocket实现来单提醒和用户催单

文章目录 概要整体架构流程技术细节小结 概要 来单提醒&#xff1a; 业务场景&#xff1a;在电商平台、外卖平台等应用场景中&#xff0c;当有新的订单产生时&#xff0c;系统需要及时通知相关人员处理新订单。 目的&#xff1a;确保订单能够得到快速响应&#xff0c;提高客户…

XSS盲打与cookie劫持

目录 【学习目标、重难点知识】 【学习目标】 【重难点知识】 XSS盲打&#xff08;加载远程攻击payload&#xff09; XSS偷cookie cookie收集 在线XSS收集平台的使用 1. BeeF框架的使用 BeeF简介 安装和使用 XSS 一些实战应用 1. XSS PDF 2. 公网投毒 3. 网站挂马…

WUP-CH34X ch34x系列芯片USB转串口通信uniapp插件使用说明

插件地址&#xff1a;WUP-CH34X 系列芯片USB转串口通信安卓库 简介 本文档是针对 CH340/CH341/CH342/CH343/CH344/CH347/CH9101/CH9102/CH9103/CH9104/CH9143的 USB 转串口安卓库的开发说明文档。 主要介绍如何使用芯片的 USB 转异步串口功能&#xff08;以下简称 CH34XUART…

python 使用正则表达式判断图片路径是否是超链接

在Python中&#xff0c;判断一个给定的字符串&#xff08;假设为图片路径&#xff09;是否是网页链接&#xff08;URL&#xff09;&#xff0c;你可以通过检查该字符串是否符合URL的基本格式来实现。虽然这个方法不能保证链接一定指向图片&#xff0c;但它能判断该字符串是否是…

La-Z-Boy EDI项目测试流程详解

在此前的文章《家居EDI&#xff1a;La-Z-Boy EDI 项目案例》中&#xff0c;为大家介绍了La-Z-Boy的EDI 需求以及在知行之桥EDI系统中的具体实现&#xff0c;本文主要为大家介绍La-Z-Boy EDI项目测试流程。 梳理需求文档 La-Z-Boy 提供的EDI资料主要包括&#xff1a;EDI 850订…

在IntelliJ IDEA中利用Git拉取项目

1 访问gitee或github&#xff0c;找到项目对应的仓库&#xff0c;并复制仓库地址。 2 打开IDEA&#xff0c;依次选择菜单:File->New->Project from Version Control 3 在弹出框中输入仓库路径(从第一步中gitee或github复制的路径)并点击Clone 4 在弹出框中输入gite…

Mybatis框架——使用案例详细教程

文章目录 一、项目创建1.1 创建 Idea 项目1.2 导入必要依赖 二、数据库配置2.1 创建数据库2.2 配置数据库连接信息 三、MyBatis 配置3.1 创建配置文件 mybatis-config.xml3.2 创建 SqlSessionFactory 实例 四、项目测试和运行4.1 创建实体类4.2 创建 mapper.xml 文件4.3 创建 m…

CentOS7安装Docker教程(含最新镜像地址)

文章目录 1 安装前必读2 安装Docker的详细步骤3 配置镜像加速 1 安装前必读 在安装 Docker 之前&#xff0c;先说一下配置&#xff0c;我这里是Centos7 Linux 内核&#xff1a;官方建议 3.10 以上&#xff0c;3.8以上貌似也可。 注意&#xff1a;本文的命令使用的是 root 用户…

UE基础 —— 工具和编辑器

目录 Level Editor Static Mesh Editor Material Editor Blueprint Editor Physics Asset Editor Behavior Tree Editor Niagara Editor UMG UI Editor Font Editor Sequencer Editor Animation Editor Control Rig Editor Sound Cue Editor Media Editor nDisp…

JUC-变量的线程安全

成员变量和静态变量是否线程安全&#xff1f; 如果它们没有共享&#xff0c;则线程安全&#xff0c;即没有被外部访问。 如果它们被共享了&#xff0c;根据它们的状态是否能够改变&#xff0c;又分两种情况 如果只有读操作&#xff0c;则线程安全 如果有读写操作&#xff0c;…