2月22日作业,按键中断LED灯控制

1.使用GPIO子系统,编写LED驱动,应用程序测试
在这里插入图片描述
mychrdev.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
int major; // 保存申请的主设备号
char kbuf[128]={0};struct gpio_desc *gpiono1;
struct gpio_desc *gpiono2;
struct gpio_desc *gpiono3;
struct device_node *dnode;//保存解析到的设备树节点地址
// 封装常用的操作方法
int mychrdev_open(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
ssize_t mychrdev_read(struct file *file, char __user *ubuf, size_t size, loff_t *lof)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);unsigned int ret;ret=copy_to_user(ubuf,kbuf,size);if(ret){printk("copy_to_user err\n");return -ret;}return 0;
}
ssize_t mychrdev_write(struct file *file, const char __user *ubuf, size_t size, loff_t *lof)
{//ubuf就是应用程序中write函数第二个参数传过来的值//size就是应用程序中write函数第三个参数传过来的值printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);unsigned int ret;ret=copy_from_user(kbuf,ubuf,size);if(ret){printk("copy_from_user err\n");return -ret;}if(kbuf[0]=='0')//关灯{gpiod_set_value(gpiono1,0);//输出低电平gpiod_set_value(gpiono2,0);//输出低电平gpiod_set_value(gpiono3,0);//输出低电平}else if(kbuf[0]=='1')//开led1灯{gpiod_set_value(gpiono1,1);//输出高电平}else if(kbuf[0]=='2')//开led2灯{gpiod_set_value(gpiono2,1);//输出高电平}else if(kbuf[0]=='3')//开led3灯{gpiod_set_value(gpiono3,1);//输出高电平}return 0;
}
int mychrdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
struct file_operations fops = {.open=mychrdev_open,.release=mychrdev_close,.read=mychrdev_read,.write=mychrdev_write,
};
static int __init mycdev_init(void)
{// 注册字符设备驱动major = register_chrdev(0, "mychrdev", &fops);if (major < 0){printk("注册字符设备驱动失败%d\n", __LINE__);}printk("注册字符设备驱动成功 major=%d\n", major);//解析LED灯设备树节点dnode=of_find_node_by_path("/leds");if(dnode==NULL){printk("解析设备树节点失败\n");return -ENXIO;}printk("解析设备树节点成功\n");//解析LED1的gpio编号gpiono1=gpiod_get_from_of_node(dnode,"led1-gpio",0, GPIOD_OUT_LOW,NULL);if(gpiono1==NULL){printk("解析gpio编号失败\n");return -ENXIO;}printk("解析gpio编号成功\n");gpiono2=gpiod_get_from_of_node(dnode,"led2-gpio",0, GPIOD_OUT_LOW,NULL);if(gpiono2==NULL){printk("解析gpio编号失败\n");return -ENXIO;}printk("解析gpio编号成功\n");gpiono3=gpiod_get_from_of_node(dnode,"led3-gpio",0, GPIOD_OUT_LOW,NULL);if(gpiono3==NULL){printk("解析gpio编号失败\n");return -ENXIO;}printk("解析gpio编号成功\n");return 0;
}
static void __exit mycdev_exit(void)
{//释放gpio编号gpiod_put(gpiono1);gpiod_put(gpiono2);gpiod_put(gpiono3);// 注销字符设备驱动unregister_chrdev(major, "mychrdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

led.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char const *argv[])
{char buf[128] = {};int fd = open("/dev/mychrdev", O_RDWR);if (fd < 0){printf("打开设备文件失败\n");return -1;}while (1){printf("请输入控制码:1(led1开灯) 2(led2开灯) 3(led3开灯) 0(关灯)>");fgets(buf, sizeof(buf), stdin); // 从终端输入一个数据buf[strlen(buf) - 1] = '\0';write(fd, buf, sizeof(buf));}close(fd);return 0;
}

2.注册三个按键的中断,只需要写内核代码
在这里插入图片描述
myled.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/of_irq.h>
/*myirq{compatible = "hqyj,myirq";interrupt-parent = <&gpiof>;interrupts=<9 0>,<7 0>,<8 0>;
};
*/struct device_node *dnode_led; // 保存解析到的led设备树节点地址
struct device_node *dnode_int; // 保存解析到的中断设备树节点地址
unsigned int irqno1;       // 按键1软中断号
unsigned int irqno2;       // 按键2软中断号
unsigned int irqno3;       // 按键3软中断号
struct gpio_desc *gpiono1; // led1设备号
struct gpio_desc *gpiono2; // led2设备号
struct gpio_desc *gpiono3; // led3设备号// 中断处理函数1
irqreturn_t myirq_handler1(int irq, void *dev)
{printk("key1_intc\n");//关灯三 开灯一gpiod_set_value(gpiono3, 0);gpiod_set_value(gpiono1, 1);return IRQ_HANDLED;
}
// 中断处理函数2
irqreturn_t myirq_handler2(int irq, void *dev)
{printk("key2_intc\n");//关灯一 开灯二gpiod_set_value(gpiono1, 0);gpiod_set_value(gpiono2, 1);return IRQ_HANDLED;
}
// 中断处理函数3
irqreturn_t myirq_handler3(int irq, void *dev)
{printk("key3_intc\n");//关灯二 开灯三gpiod_set_value(gpiono2, 0);gpiod_set_value(gpiono3, 1);return IRQ_HANDLED;
}static int __init mycdev_init(void)
{// 解析按键的设备树节点dnode_int = of_find_compatible_node(NULL, NULL, "hqyj,myirq");if (dnode_int == NULL){printk("解析设备树节点失败\n");return -ENXIO;}printk("解析设备树节点成功\n");// 解析LED灯设备树节点dnode_led = of_find_node_by_path("/leds");if (dnode_led == NULL){printk("解析设备树节点失败\n");return -ENXIO;}printk("解析设备树节点成功\n");// 解析按键1的软中断号irqno1 = irq_of_parse_and_map(dnode_int, 0);if (!irqno1){printk("解析按键1软中断号失败\n");return -ENXIO;}printk("解析按键1软中断号成功%d\n", irqno1);// 解析按键2的软中断号irqno2 = irq_of_parse_and_map(dnode_int, 1);if (!irqno2){printk("解析按键2软中断号失败\n");return -ENXIO;}printk("解析按键2软中断号成功%d\n", irqno2);// 解析按键3的软中断号irqno3 = irq_of_parse_and_map(dnode_int, 2);if (!irqno3){printk("解析按键3软中断号失败\n");return -ENXIO;}printk("解析按键3软中断号成功%d\n", irqno3);// 注册按键1中断int ret1 = request_irq(irqno1, myirq_handler1, IRQF_TRIGGER_FALLING, "key1", (void *)1);if (ret1){printk("中断注册失败\n");return ret1;}printk("中断注册成功\n");// 注册按键2中断int ret2 = request_irq(irqno2, myirq_handler2, IRQF_TRIGGER_FALLING, "key2", (void *)2);if (ret2){printk("中断注册失败\n");return ret2;}printk("中断注册成功\n");// 注册按键3中断int ret3 = request_irq(irqno3, myirq_handler3, IRQF_TRIGGER_FALLING, "key3", (void *)3);if (ret3){printk("中断注册失败\n");return ret3;}printk("中断注册成功\n");// 解析LED1的gpio编号gpiono1 = gpiod_get_from_of_node(dnode_led, "led1-gpio", 0, GPIOD_OUT_LOW, NULL);if (gpiono1 == NULL){printk("解析gpio编号失败\n");return -ENXIO;}printk("解析gpio编号成功\n");// 解析LED2的gpio编号gpiono2 = gpiod_get_from_of_node(dnode_led, "led2-gpio", 0, GPIOD_OUT_LOW, NULL);if (gpiono2 == NULL){printk("解析gpio编号失败\n");return -ENXIO;}printk("解析gpio编号成功\n");// 解析LED3的gpio编号gpiono3 = gpiod_get_from_of_node(dnode_led, "led3-gpio", 0, GPIOD_OUT_LOW, NULL);if (gpiono3 == NULL){printk("解析gpio编号失败\n");return -ENXIO;}printk("解析gpio编号成功\n");return 0;
}
static void __exit mycdev_exit(void)
{// 释放软中断号free_irq(irqno1, (void *)1);free_irq(irqno2, (void *)2);free_irq(irqno3, (void *)3);// 释放gpio编号gpiod_put(gpiono1);gpiod_put(gpiono2);gpiod_put(gpiono3);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

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

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

相关文章

微软Azure OpenAI的 GPT 接口使用小结

直接使用OpenAI的 GPT服务&#xff0c;在国内环境使用上会一些相关问题&#xff0c;微软提供了OpenAI的服务&#xff0c;基本上可以满足的相关的需要。下面提供一些简单的使用操作&#xff0c;来让你快速使用到 GPT 的服务。 前提&#xff1a;注册Azure的账户&#xff0c;并绑…

OpenCV中的normalize函数以及NORM_MINMAX、NORM_INF、NORM_L1、NORM_L2具体应用介绍

在OpenCV中&#xff0c;normalize函数用于将图像或矩阵的值规范化到一个特定的范围内。这在图像处理中非常有用&#xff0c;比如在调整图像的对比度、准备数据进行机器学习处理时。规范化可以提高不同图像之间的可比性&#xff0c;或是为了满足特定算法对数据范围的要求。 nor…

数的反码和补码表示

2.反码 反码的表示方法是: 正数的反码是其本身负数的反码是在其原码的基础上,符号位不变&#xff0c;其余各个位取反 [1][000000011原[000000011反[-1][10000001]原[11111110]反 3.补码 补码的表示方法是: 正数的补码就是其本身 负数的补码是在其原码的基础上,符号位不变,其余各…

36、IO进程线程/进程和线程之间的通信练习

一、使用有名管道完成两个进程的相互通信(提示&#xff1a;可以使用多进程或多线程完成)。 代码1&#xff1a;创建两个有名管道文件 #include<myhead.h>int main(int argc, const char *argv[]) {if(mkfifo("./mingtohua",0664)-1)//创建小明向小华发信息的管…

Stable Diffusion 绘画入门教程(webui)-ControlNet(深度Depth)

上篇文章介绍了线稿约束&#xff0c;这篇文章介绍下深度Depth 文章目录 一、选大模型二、写提示词三、基础参数设置四、启用ControlNet 顾名思义&#xff0c;就是把原图预处理为深度图&#xff0c;而深度图可以区分出图像中各元素的远近关系&#xff0c;那么啥事深度图&#xf…

c/c++ | 字符串函数总结 | 为什么总喜欢纠结sizeof 和strlen 呢?

其实时间长了&#xff0c;稍微研究后&#xff0c;再来品味&#xff0c;别有一番滋味 总是看着混乱&#xff0c;但是静下来看&#xff0c;还是能琢磨透的&#xff0c;只是看着复杂&#xff0c;本质是两套风格&#xff0c;然后又要有交集&#xff0c;所以就看起来复杂 // 首先字符…

目标管理SMART原则

SMART原则是一种目标管理方法&#xff0c;它包括以下五个要素&#xff1a; 具体性&#xff08;Specific&#xff09;&#xff1a;目标应该是明确的&#xff0c;具体地说明要达成的行为标准。例如&#xff0c;一个目标可能描述为“减少客户投诉率”&#xff0c;而不是“增强客户…

本机防攻击简介

定义 在网络中&#xff0c;存在着大量针对CPU&#xff08;Central Processing Unit&#xff09;的恶意攻击报文以及需要正常上送CPU的各类报文。针对CPU的恶意攻击报文会导致CPU长时间繁忙的处理攻击报文&#xff0c;从而引发其他业务的中断甚至系统的中断&#xff1b;大量正常…

惠尔顿 网络安全审计系统 任意文件读取漏洞复现

0x01 产品简介 惠尔顿网络安全审计产品致力于满足军工四证、军工保密室建设、国家涉密网络建设的审计要求&#xff0c;规范网络行为&#xff0c;满足国家的规范&#xff1b;支持1-3线路的internet接入、1-3对网桥&#xff1b;含强大的上网行为管理、审计、监控模块&#xff1b…

【2024软件测试面试必会技能】Requests(5):Requests模块_设置代理

设置代理 代理&#xff08;英语&#xff1a;Proxy&#xff09;&#xff0c;也称网络代理&#xff0c;是一种特殊的网络服务&#xff0c;英文全称是&#xff08;Proxy Server&#xff09;&#xff0c;其功 能就是代理网络用户去取得网络信息。形象的说&#xff1a;它是网络信息…

正向代理和反向代理释义

代理 客户端 代理 服务端 对客户端而言&#xff0c;代理是服务端&#xff1b;对服务端而言&#xff0c;代理是客户端。这个很好理解吧&#xff0c;以祖孙三代关系为例&#xff0c;爸爸在儿子面前是爸爸&#xff0c;爸爸在爷爷面前是儿子。 无论是正向代理还是反向代理&#…

Android14 InputManager-ANR原理

目标窗口查找时&#xff0c;作为派发目标的窗口必须已经准备好接收新的输入事件&#xff0c;否则判定窗口处于未响应状态&#xff0c;终止事件的派发过程&#xff0c;并在一段时间后再试。倘若5s后窗口仍然未准备好接收输入事件&#xff0c;将导致ANR。直接引发ANR的原因有很多…

操作系统学习记录

系统篇 内核 应用和底层硬件&#xff08;CPU、内存、硬盘等&#xff09;的连接桥梁。 用户态和内核态 CPU和进程可以在两种态下运行。 内核态可以直接访问所有硬件资源&#xff0c;用户态需要通过“系统调用”陷入到内核态才能否则只能访问用户空间地址的内存&#xff08;虚…

P8630 [蓝桥杯 2015 国 B] 密文搜索

P8630 [蓝桥杯 2015 国 B] 密文搜索 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P8630 题目分析 基本上是hash的板子&#xff0c;但实际上对于密码串&#xff0c;只要判断主串中任意连续的八个位置是否存在密码串即可&#xff1b;那么我们…

PHP学习笔记1——html标签以及头部元素页面布局

html是一种超文本标识符号&#xff0c;用来在网页中指定显示页面格式显示 基本格式 <!doctype html> <html><head><title></title> </head><body> </body></html> 包含声明&#xff0c;框架html&#xff0c;头部head&a…

怎么把公众号文章链接做成二维码?扫码查看公众号推文的方法

公众号是现在给用户分享内容的一种方式&#xff0c;通过输出优质的公众号文章内容来为关注者提供信息和内容。当我们发布公众号文章后&#xff0c;有些情况下会需要将公众号内容生成二维码之后&#xff0c;印刷到传单、展板上来显示&#xff0c;那么如何将公众号的文章链接转二…

Commonjs 和 Es Module详解

一 前言 今天我们来深度分析一下 Commonjs 和 Es Module&#xff0c;希望通过本文的学习&#xff0c;能够让大家彻底明白 Commonjs 和 Es Module 原理&#xff0c;能够一次性搞定面试中遇到的大部分有关 Commonjs 和 Es Module 的问题。 带上疑问开始今天的分析&#xff1a; …

数字化转型导师坚鹏:城市数字化转型顶层规划方法

城市数字化转型顶层规划方法 课程背景&#xff1a; 很多城市存在以下问题&#xff1a; 不知道如何系统地开展数字化转型工作&#xff1f; 不清楚如何科学地制定数字化转型战略&#xff1f; 不知道如何高效地实施数字化转型战略&#xff1f; 课程特色&#xff1a; 有…

基于SpringBoot的在线拍卖系统设计与实现(源码+调试+LW+PPT)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于SpringBoot的在线拍…

C++编程知识

&#xff08;1&#xff09;把数组中的所有元素赋值为一个值 memset(arr,0x3f,sizeof(arr))//最大值 memset(arr,0,sizeof(distance));//赋值为0&#xff08;2&#xff09;找最大最小值的下标 int zuixiao-1//设置dist-1只是因为方便选取第一个数作为比较对象而已 for(i0;i<…