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

玉林网站建设公司湖北网络营销网站

玉林网站建设公司,湖北网络营销网站,西安网页设计制作介绍,外贸商城网站 定制文章目录 前言一、SR501模块介绍二、设备树编写三、驱动编写1.确定主设备号2.编写file_operations结构体3.注册file_operations结构体4.出口函数编写5.probe函数和remove函数编写6.中断编写7.测试程序编写8.全部驱动程序 总结 前言 本篇文章将给大家介绍一下SR501驱动程序的编…

文章目录

  • 前言
  • 一、SR501模块介绍
  • 二、设备树编写
  • 三、驱动编写
    • 1.确定主设备号
    • 2.编写file_operations结构体
    • 3.注册file_operations结构体
    • 4.出口函数编写
    • 5.probe函数和remove函数编写
    • 6.中断编写
    • 7.测试程序编写
    • 8.全部驱动程序
  • 总结


前言

本篇文章将给大家介绍一下SR501驱动程序的编写。

一、SR501模块介绍

SR501是一种基于红外线感应原理的人体感应模块,通常被用于安防等一系列自动控制场景中。它主要通过红外线传感器检测感应区域内的人体热辐射,当检测到人体进入这个区域时,输出高电平信号;当人体离开这个区域时,输出低电平信号。

SR501模块整体封装在一块小板子上,板子上有两个旋钮,可以通过旋转它们来调节感应灵敏度和输出信号类型,以适应不同的应用场景。此外,模块还具有自动感应和手动感应两种模式,可以通过调节模式选择开关来进行调节。

SR501模块拥有许多优点,例如可以灵敏地探测人体,响应速度快、稳定性好、安装简单等等,因此被广泛应用于各种人体感应应用场景中。

SR501接线:
VCC----电源
GND----GND
OUT-----GPIO(设置为输入模式)

二、设备树编写

这里我将SR501模块接到了GPIO4_19:

这里主要需要注意的就是compatible属性,使用这个属性来和我们编写的驱动进行匹配。

sr501{compatible = "my,sr501";gpios = <&gpio4 19 GPIO_ACTIVE_HIGH>;};

三、驱动编写

1.确定主设备号

主设备设置为0让系统自动帮我们分配主设备号。

static int major=0;/*主设备号*/

2.编写file_operations结构体

我们需要提供这个结构体并且编写其中的open和read函数,供应用程序使用。

static ssize_t sr501_read (struct file *file, char __user *buf, size_t size, loff_t *off)
{int err;wait_event_interruptible(sr501_wq, sr501_data);err = copy_to_user(buf, &sr501_data, 4);sr501_data = 0;return 0;}static int sr501_open (struct inode *inode, struct file *file)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}static struct file_operations sr501_ops={.owner		= THIS_MODULE,.open		= sr501_open,.read		= sr501_read,	
};

3.注册file_operations结构体

在Linux中注册其实就是指在Linux内核中添加我们自己编写的这个file_operations结构体。这个注册的工作在入口函数中完成。

static int __init sr501_init(void)
{int err;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);/*确定主设备号*/major=register_chrdev(major, "mysr501", &sr501_ops);/*创建类*/sr501_class=class_create(THIS_MODULE, "sr501");if (IS_ERR(sr501_class)) {printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major, "mysr501");return PTR_ERR(sr501_class);}init_waitqueue_head(&sr501_wq);//初始化队列err=platform_driver_register(&sr501);return 0;
}

4.出口函数编写

有入口函数就会有出口函数,在入口函数中做的是设备的注册等工作,那么出口函数就是做相反的工作,将设备注销。

static void __exit sr501_exit(void)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);platform_driver_unregister(&sr501);class_destroy(sr501_class);unregister_chrdev(major, "mysr501");	
}module_init(sr501_init);
module_exit(sr501_exit);MODULE_LICENSE("GPL");

5.probe函数和remove函数编写

创建platform_driver结构体和of_device_id结构体,使用of_device_id结构体中的compatible 属性和设备树进行匹配,匹配完成后会调用到probe函数。

static const struct of_device_id my_sr501[] = {{ .compatible = "my,sr501" },{ },
};static struct platform_driver sr501={.driver = {.name = "sr501",.of_match_table = my_sr501,	},.probe = sr501_probe,.remove	= sr501_remove,	
};
static int sr501_probe(struct platform_device *pdev)
{int err;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);/*1.获取硬件信息*/sr501_gpio=gpiod_get(&pdev->dev, NULL, GPIOD_IN);if (IS_ERR(sr501_gpio)) {printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);}/*得到irq*/irq = gpiod_to_irq(sr501_gpio);/*申请中断并设置为双边沿触发*/err = request_irq(irq, sr501_isr, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, "sr501", NULL);if (err != 0) {printk("request_irq is err\n");}/*2.创建设备节点*/	device_create(sr501_class, NULL, MKDEV(major, 0), NULL, "sr501");return 0;	
}static int sr501_remove(struct platform_device *pdev)
{		printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);device_destroy(sr501_class, MKDEV(major, 0));free_irq(irq, NULL);gpiod_put(sr501_gpio);return 0;
}

6.中断编写

这里我们使用中断来实现SR501的核心功能,因为当检测到有人的时候SR501表现为高电平,没有人的时候SR501则表现为低电平。那么这样我们就可以把SR501的引脚配置为中断引脚,当电平发生变化的时候就会产生中断。

这里使用到了wait_queue_head_t 定义了一个等待队列,当有人的时候使用wake_up函数唤醒等待队列读取数据。

static wait_queue_head_t sr501_wq;/*等待队列*/static irqreturn_t sr501_isr(int irq, void *dev_id)
{int val = gpiod_get_value(sr501_gpio);if(val){sr501_data = 1;wake_up(&sr501_wq);}return IRQ_HANDLED; // IRQ_WAKE_THREAD;
}

7.测试程序编写

有了驱动程序后相应的也需要一个应用程序来测试驱动代码是否正确,在应用程序中使用read函数来读取数据。

#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>
#include <unistd.h>/** ./sr501_test /dev/sr501**/
int main(int argc, char **argv)
{int fd;int data;/* 1. 判断参数 */if (argc != 2) {printf("Usage: %s <dev>\n", argv[0]);return -1;}/* 2. 打开文件 */
//	fd = open(argv[1], O_RDWR | O_NONBLOCK);fd = open(argv[1], O_RDWR);if (fd == -1){printf("can not open file %s\n", argv[1]);return -1;}while (1){read(fd, &data, 4);if (data){printf("have people\n");}else{printf("no people\n");}			sleep(1);}close(fd);return 0;
}

8.全部驱动程序

#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>
#include <linux/workqueue.h>
#include <asm/current.h>
#include <linux/delay.h>
#include <linux/timex.h>static int major=0;/*主设备号*/
static struct class *sr501_class;
static struct gpio_desc *sr501_gpio;/*sr501 gpio*/
static int sr501_data = 0;
static int irq;/*中断号*/
static wait_queue_head_t sr501_wq;/*等待队列*/static ssize_t sr501_read (struct file *file, char __user *buf, size_t size, loff_t *off)
{int err;wait_event_interruptible(sr501_wq, sr501_data);err = copy_to_user(buf, &sr501_data, 4);sr501_data = 0;return 0;}static int sr501_open (struct inode *inode, struct file *file)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}static struct file_operations sr501_ops={.owner		= THIS_MODULE,.open		= sr501_open,.read		= sr501_read,	
};static irqreturn_t sr501_isr(int irq, void *dev_id)
{int val = gpiod_get_value(sr501_gpio);if(val){sr501_data = 1;wake_up(&sr501_wq);}return IRQ_HANDLED; // IRQ_WAKE_THREAD;
}static int sr501_probe(struct platform_device *pdev)
{int err;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);/*1.获取硬件信息*/sr501_gpio=gpiod_get(&pdev->dev, NULL, GPIOD_IN);if (IS_ERR(sr501_gpio)) {printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);}/*得到irq*/irq = gpiod_to_irq(sr501_gpio);/*申请中断并设置为双边沿触发*/err = request_irq(irq, sr501_isr, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, "sr501", NULL);if (err != 0) {printk("request_irq is err\n");}/*2.创建设备节点*/	device_create(sr501_class, NULL, MKDEV(major, 0), NULL, "sr501");return 0;	
}static int sr501_remove(struct platform_device *pdev)
{		printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);device_destroy(sr501_class, MKDEV(major, 0));free_irq(irq, NULL);gpiod_put(sr501_gpio);return 0;
}static const struct of_device_id my_sr501[] = {{ .compatible = "my,sr501" },{ },
};static struct platform_driver sr501={.driver = {.name = "sr501",.of_match_table = my_sr501,	},.probe = sr501_probe,.remove	= sr501_remove,	
};static int __init sr501_init(void)
{int err;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);/*确定主设备号*/major=register_chrdev(major, "mysr501", &sr501_ops);/*创建类*/sr501_class=class_create(THIS_MODULE, "sr501");if (IS_ERR(sr501_class)) {printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major, "mysr501");return PTR_ERR(sr501_class);}init_waitqueue_head(&sr501_wq);//初始化队列err=platform_driver_register(&sr501);return 0;
}static void __exit sr501_exit(void)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);platform_driver_unregister(&sr501);class_destroy(sr501_class);unregister_chrdev(major, "mysr501");	
}module_init(sr501_init);
module_exit(sr501_exit);MODULE_LICENSE("GPL");

总结

本篇文章就讲解到这里,只要掌握Linux驱动的核心框架写一个驱动程序并不是那么困难。

http://www.zhongyajixie.com/news/9067.html

相关文章:

  • 家用电脑桌面做网站国际新闻视频
  • 南宁模板建站哪家好惠州网络营销
  • wordpress 上传网站长沙做网站推广公司咨询
  • web产品销售网站开发百度网站的优化方案
  • 邢台做网站咨询网站推广的方法和途径
  • 网站建设完工确认书处理器优化软件
  • 网站开发需要什么知识专业搜索引擎seo公司
  • 网站建设与管理维护如何注册域名网站
  • 哪些公司做网站维护的百度软件中心下载
  • 江门做网站公司独立站怎么建站
  • 软件开发步骤包括哪些网站seo优化排名
  • 免费模板样机素材网站博客营销
  • 网站开发菜鸟适合用什么软件营销网络的建设怎么写
  • 网站建设it职位百度指数明星人气榜
  • 成都网站建设推广服务百度明星人气榜入口
  • 小说网站怎么做推广广州市口碑seo推广外包
  • 昆明网站建设有限公司刷赞抖音推广网站
  • 藁城区建设局网站公关公司的主要业务
  • 动态网站开发常见语言seo推广培训
  • 图片瀑布流网站学seo的培训学校
  • 宁波网站建设多少钱一年搜索推广和信息流推广的区别
  • 三种类型的企业网站网络推广吧
  • 网站开发在线打开word互联网营销方式
  • 大亚湾规划建设局网站seo高手是怎样炼成的
  • 金融企业网站源码设计公司
  • 推荐成都网站建设黄页88网络营销宝典
  • 网站改版不换域名怎么做百度公司地址在哪里
  • wordpress tob5.0英文关键词seo
  • 长沙好的网站优化品牌广告公司业务推广
  • 建立网站 英语怎么说长春网站建设制作