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

驱动开发(中断)

头文件:

#ifndef __LED_H__
#define __LED_H__#define PHY_LED1_MODER 0X50006000
#define PHY_LED1_ODR  0X50006014
#define PHY_LED1_RCC 0X50000A28#define PHY_LED2_MODER 0X50007000
#define PHY_LED2_ODR  0X50007014
#define PHY_LED2_RCC  0X50000A28#define PHY_LED3_MODER 0X50006000
#define PHY_LED3_ODR  0X50006014
#define PHY_LED3_RCC  0X50000A28
//风扇
#define PHY_FAN_MODER 0X50006000
#define PHY_FAN_ODR  0X50006014
#define PHY_FAN_RCC 0X50000A28
//蜂鸣器
#define PHY_BUZZER_MODER 0X50003000
#define PHY_BUZZER_ODR  0X50003014
#define PHY_BUZZER_RCC 0X50000A28
//马达
#define PHY_MOTOR_MODER 0X50007000
#define PHY_MOTOR_ODR  0X50007014
#define PHY_MOTOR_RCC 0X50000A28
//功能码
#define LED_ON _IO('l',1)
#define LED_OFF _IO('l',0)
#define FAN_ON _IO('f',1)
#define FAN_OFF _IO('f',0)
#define BUZZER_ON _IO('b',1)
#define BUZZER_OFF _IO('b',0)
#define MOTOR_ON _IO('m',1)
#define MOTOR_OFF _IO('m',0)
#endif

 

应用层程序:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include "head.h"
int main(int argc, char const *argv[])
{char buf[128] = {0};int led1_fd, led2_fd, led3_fd;// 打开led设备文件led1_fd = open("/dev/mycdev0", O_RDWR);if (led1_fd < 0){printf("打开led1设备文件失败\n");exit(-1);}led2_fd = open("/dev/mycdev1", O_RDWR);if (led2_fd < 0){printf("打开led2设备文件失败\n");exit(-1);}led3_fd = open("/dev/mycdev2", O_RDWR);if (led3_fd < 0){printf("打开led3设备文件失败\n");exit(-1);}int a, b;while (1){printf("请选择要控制的器件: 1(led灯1) 2 (led灯2) 3 (led灯3) ");scanf("%d", &a);printf("请输入指令:0(关闭) 1 (打开)");scanf("%d", &b);switch (b){case 1:switch (a){case 1:ioctl(led1_fd, LED_ON, a);break;case 2:ioctl(led2_fd, LED_ON, a);break;case 3:ioctl(led3_fd, LED_ON, a);break;}break;case 0:switch (a){case 1:ioctl(led1_fd, LED_OFF, a);break;case 2:ioctl(led2_fd, LED_OFF, a);break;case 3:ioctl(led3_fd, LED_OFF, a);break;}break;}}close(led1_fd);close(led2_fd);close(led3_fd);return 0;
}

驱动程序:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/poll.h>
#include "head.h"
struct cdev* mycdev;
struct class* cls;
struct device* dev_d;
unsigned int major = 500;
unsigned int minor = 0;
dev_t devno;
char kbuf[128] = {0};
wait_queue_head_t wq_head;
int condition = 0;
struct device_node *dev,*led_dev;
unsigned int irqno1,irqno2,irqno3;
struct gpio_desc* gpiono1,*gpiono2,*gpiono3;
// 封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{int a = inode->i_rdev;file->private_data = (void *)MINOR(a);printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}
long mychrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{	unsigned int a;printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);a = (unsigned int)file->private_data;switch(a){case 0:if(cmd == LED_ON){gpiod_set_value(gpiono1,1);}else{gpiod_set_value(gpiono1,0);}break;case 1:if(cmd == LED_ON){gpiod_set_value(gpiono2,1);}else{gpiod_set_value(gpiono2,0);}break;case 2:if(cmd == LED_ON){gpiod_set_value(gpiono3,1);}else{gpiod_set_value(gpiono3,0);}break;}return 0;
}
irqreturn_t myirq_handler(int irq,void *dev)
{gpiod_set_value(gpiono1,!gpiod_get_value(gpiono1));return IRQ_HANDLED;
}
irqreturn_t myirq2_handler(int irq,void *dev)
{gpiod_set_value(gpiono2,!gpiod_get_value(gpiono2));return IRQ_HANDLED;
}
irqreturn_t myirq3_handler(int irq,void *dev)
{gpiod_set_value(gpiono3,!gpiod_get_value(gpiono3));return IRQ_HANDLED;
}
//对设备文件进行操作的结构体
struct file_operations fops = {.open = mycdev_open,//打开.unlocked_ioctl = mychrdev_ioctl,//硬件功能的选择.release = mycdev_close,//关闭
};
static int __init mycdev_init(void)
{int i;major = register_chrdev(0,"mycdev",&fops);if(major<0){printk("注册设备驱动失败\n");return major;}printk("注册设备驱动成功major=%d\n",major);//************自动申请设备节点*********************//1、向上提交目录cls = class_create(THIS_MODULE, "mycdev");if(IS_ERR(cls)){printk("向上提交目录失败\n");return -PTR_ERR(cls);}printk("向上提交目录成功\n");// 2、向上提交设备节点信息for (i = 0; i < 3; i++){dev_d = device_create(cls, NULL, MKDEV(major, i), NULL, "mycdev%d", i);if (IS_ERR(dev_d)){printk("提交led设备信息失败\n");return -PTR_ERR(dev_d);}}printk("提交设备信息成功\n");/***********************************///解析设备树的节点int ret;dev = of_find_node_by_name(NULL,"myirq");if(dev == NULL){printk("解析设备树节点失败\n");return -EIO;}printk("解析myirq设备树节点成功\n");led_dev = of_find_node_by_name(NULL,"leds");if(led_dev == NULL){printk("解析led设备树节点失败\n");return -EIO;}printk("解析led设备树节点成功\n");gpiono1 = gpiod_get_from_of_node(led_dev,"led1-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono1)){printk("申请gpio对象失败\n");return -PTR_ERR(gpiono1);}gpiono2 = gpiod_get_from_of_node(led_dev,"led2-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono2)){printk("申请gpio2对象失败\n");return -PTR_ERR(gpiono2);}gpiono3 = gpiod_get_from_of_node(led_dev,"led3-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono3)){printk("申请gpio3对象失败\n");return -PTR_ERR(gpiono3);}//根据设备树节点解析出软中断号irqno1 = irq_of_parse_and_map(dev,0);if(!irqno1){printk("解析led1软中断号失败\n");return -ENXIO;}printk("解析软led1中断号成功irqno=%d\n",irqno1);irqno2 = irq_of_parse_and_map(dev,1);if(!irqno2){printk("解析led2软中断号失败\n");return -ENXIO;}printk("解析led2软中断号成功irqno=%d\n",irqno2);irqno3 = irq_of_parse_and_map(dev,2);if(!irqno3){printk("解析led3软中断号失败\n");return -ENXIO;}printk("解析led3软中断号成功irqno=%d\n",irqno3);//注册中断ret = request_irq(irqno1,myirq_handler,IRQF_TRIGGER_FALLING,"key1",NULL);if(ret){printk("key1软中断号注册失败\n");return ret;}printk("key1软中断号注册成功\n");ret = request_irq(irqno2,myirq2_handler,IRQF_TRIGGER_FALLING,"key2",NULL);if(ret){printk("key2软中断号注册失败\n");return ret;}printk("key2软中断号注册成功\n");ret = request_irq(irqno3,myirq3_handler,IRQF_TRIGGER_FALLING,"key3",NULL);if(ret){printk("key3软中断号注册失败\n");return ret;}printk("key3软中断号注册成功\n");return 0;
}
static void __exit mycdev_exit(void)
{int i;//灭灯gpiod_set_value(gpiono1,0);//释放gpio编号gpiod_put(gpiono1);//灭灯gpiod_set_value(gpiono2,0);//释放gpio编号gpiod_put(gpiono2);//灭灯gpiod_set_value(gpiono3,0);//释放gpio编号gpiod_put(gpiono3);//注销中断号free_irq(irqno1,NULL);free_irq(irqno2,NULL);free_irq(irqno3,NULL);//销毁节点信息for (i = 0; i < 3; i++){device_destroy(cls, MKDEV(major, i));}//销毁目录信息class_destroy(cls);//注销字符设备驱动unregister_chrdev(major,"mycdev");}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

相关文章:

驱动开发(中断)

头文件&#xff1a; #ifndef __LED_H__ #define __LED_H__#define PHY_LED1_MODER 0X50006000 #define PHY_LED1_ODR 0X50006014 #define PHY_LED1_RCC 0X50000A28#define PHY_LED2_MODER 0X50007000 #define PHY_LED2_ODR 0X50007014 #define PHY_LED2_RCC 0X50000A28#def…...

TypeScript最新语法总结

注意注意&#xff01;&#xff01;&#xff01;本文介绍的是最新的TypeScript4的重要语法 第一部分&#xff1a;TypeScript的简介 TypeScript 是由微软开发的一款开源的编程语言&#xff0c;TypeScript 是 Javascript 的超集&#xff0c;遵循最新的 ES6、ES5 规范&#xff0c…...

sentinel组件

目录 定义 4.加SentinelResource,blockHander是超过阈值之后执行的函数 5.设置阈值 6.springboot集成sentinel 定义 1.sentinel知道当前流量大小&#xff0c;在浏览器和后端之间加sentinel控制流量&#xff0c;避免大批量的瞬时请求都达到服务上&#xff0c;将服务压垮 2.…...

26 MFC序列化函数

文章目录 Serialize对于存储文件的序列化 Serialize Serialize 是一个在 MFC (Microsoft Foundation Classes) 中常用的函数或概念。它用于将对象的数据进行序列化和反序列化&#xff0c;便于在不同的场景中保存、传输和恢复对象的状态。 在 MFC 中&#xff0c;Serialize 函数…...

GC 深入(小白,对gc有一个进一步的了解)

垃圾回收器的搭配 一般固定 一般这年轻代垃圾回收器&#xff0c;老年代垃圾回收器&#xff0c;如上图搭配着使用 1.8呢默认就是最后边那哥俩 jvm调优 一个就是增加吞吐量 一个就是减少STW的时间。 三色标记算法&#xff08;理解根可达算法&#xff09; 并发的可达性分析 有…...

CSS前端面试

文章目录 rem、em、vh、px各自代表的含义&#xff1f;盒模型poison 定位属性flex属性让元素水平垂直居中页面适配的方法有哪些 rem、em、vh、px各自代表的含义&#xff1f; px&#xff1a;绝对单位&#xff0c;页面按精确像素展示 em&#xff1a;相对单位&#xff0c;基准点为…...

VB+SQL餐饮管理系统设计与实现

第一章 前言 1.1 绪论 当今世界已进入了在计算机信息管理领域中激烈竞争的时代,应用计算机已经变得十分普遍了,如同我们离不开的自行车、汽车一样。我们应该承认,谁掌握的知识多,信息量大,信息处理速度快,批量大,谁的效率就高,谁就能够在各种竞争中立于不败之地。随着…...

React入门学习笔记2

jsx语法规则 定义虚拟DOM时&#xff0c;不要写引号。标签中混入JS表达式时要用{ }。样式的类名指定不要用class&#xff0c;要用className。内联样式&#xff0c;要用style{{key&#xff1a;value}}的形式去写。只有一个根标签标签必须闭合标签首字母 )若小写字母开头&#xf…...

Palo Alto Networks® PA-220R 下一代防火墙 确保恶劣工况下的网络安全

一、主要安全功能 1、每时每刻在各端口对全部应用进行分类 • 将 App-ID 用于工业协议和应用&#xff0c;例如 Modbus、 DNP3、IEC 60870-5-104、Siemens S7、OSIsoft PI 等。 • 不论采用何种端口、SSL/SSH 加密或者其他规避技术&#xff0c;都会识别应用。 • 使用…...

架构训练营学习笔记:5-2 负载均衡架构

多级负载架构 设计关键点 性能需求、维护复杂度之间做取舍。 一可以去掉F5、LVS &#xff1a; F5 是成本较高&#xff0c;LVS 是复杂&#xff0c;对于性能没那么高需求&#xff0c;可以去掉。 二 去掉ng: 服务网关服务 适应于初创公司快速验证&#xff0c;内部的 小系统…...

二叉树的性质、前中后序遍历【详细】

1. 树概念2.二叉树的概念1.2二叉树的性质 3.二叉树遍历3.2前序遍历3.2 中序遍历3.3 后序遍历 1. 树概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合&#xff0c;有二叉树&#xff0c;N叉树等等。 子树…...

涨姿势了,有意思的气泡 Loading 效果

今日&#xff0c;群友提问&#xff0c;如何实现这么一个 Loading 效果&#xff1a; 这个确实有点意思&#xff0c;但是这是 CSS 能够完成的&#xff1f; 没错&#xff0c;这个效果中的核心气泡效果&#xff0c;其实借助 CSS 中的滤镜&#xff0c;能够比较轻松的实现&#xff0…...

单片机中断系统

单片机中断系统 中断的概念&#xff1a; CPU在处理某一事件A时&#xff0c;发生了另一事件B请求CPU迅速去处理&#xff08;中断发生&#xff09;&#xff1b;CPU暂时中断当前的工作&#xff0c;转去处理事件B&#xff08;中断响应和中断服务&#xff09;&#xff1b;待CPU将事…...

二、JVM-深入运行时数据区

深入运行时数据区 计算机体系结构 JVM的设计实际上遵循了遵循冯诺依曼计算机结构 CPU与内存交互图&#xff1a; 硬件一致性协议&#xff1a; MSI、MESI、MOSI、Synapse、Firely、DragonProtocol 摩尔定律 摩尔定律是由英特尔(Intel)创始人之一戈登摩尔(Gordon Moore)提出来…...

随机验证码vue实现,登录验证码随机验证码数字和字母类型的

1、组件 <!--loginCode登录验证码组件--> <template> <canvas id"canvasCode" :width"contentWidth" :height"contentHeight" /> </template> <script> export default { name: LoginCode, props: { identif…...

xlrd与xlwt操作Excel文件详解

Python操作Excel的模块有很多&#xff0c;并且各有优劣&#xff0c;不同模块支持的操作和文件类型也有不同。下面是各个模块的支持情况&#xff1a; .xls.xlsx获取文件内容写入数据修改文件内容保存样式调整插入图片xlrd√√√xlwt√√√√√xlutils√√√√xlwings√√√√√…...

A Survey of Embodied AI: From Simulators to Research Tasks 论文阅读

论文信息&#xff1a; 题目&#xff1a;A Survey of Embodied AI: From Simulators to Research Tasks 作者&#xff1a;Jiafei Duan, Samson Yu 来源&#xff1a;arXiv 时间&#xff1a;2022 Abstract 通过评估当前的九个具体人工智能模拟器与我们提出的七个功能&#xff0…...

spark-sql数据重复之File Output Committer问题

前言 我们先来回顾下之前介绍过的三种Committer&#xff1a;FileOutputCommitter V1、FileOutputCommitter V2、S3A Committer&#xff0c;其基本代表了整体的演进趋势。 核心代码讲解详细参照&#xff1a;Spark CommitCoordinator 保证数据一致性 OutputCommitter commitTask…...

面试热题(前中序遍历构建树)

给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 题目中是给定两个数组&#xff0c;一个是存放这颗树的前序遍历的数组&#xff0c;一个是存放这棵树的…...

美术:贴图

游戏模型制作流程&#xff0c;SP和BP根据情况来选择软件对UV进行处理 3Dmax 制作模型和动画&#xff08;橘肉&#xff09;RizomUV 对模型进行展UV&#xff08;橘皮&#xff09;Substance Painter 纹理手绘&#xff08;给橘皮制定想要的皮肤&#xff09;BodyPaint 3D 纹理手绘&a…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...