【驱动开发day8作业】

 作业1:

应用层代码

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>int main(int argc, char const *argv[])
{char buf[128] = {0};int a, b;int fd;while (1){// 从终端读取fd = open("/dev/mycdev0", O_RDWR);if (fd < 0){printf("打开设备文件失败\n");exit(-1);}printf("请输入按键>");printf("0:LED1 1:LED2 2:LED3\n");printf("请输入>");scanf("%d", &b);printf("请输入指令\n");printf("0(关灯) 1(开灯)\n");printf("请输入>");scanf("%d", &a);switch (a){case 1:ioctl(fd, 1, b); // 开灯break;case 0:ioctl(fd, 0, b);break;}close(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/gpio.h>
#include <linux/of_gpio.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/cdev.h>struct device_node *dev_led;struct gpio_desc *gpiono1;
struct gpio_desc *gpiono2;
struct gpio_desc *gpiono3;dev_t devid;
struct cdev *cdev;
unsigned int major = 500;
unsigned int minor = 0;
struct class *cls;
struct device *dev;
int mycdev_open(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{switch (arg){case 0:if (cmd == 1){// 亮灯gpiod_set_value(gpiono1, 1);}else{// 灭灯gpiod_set_value(gpiono1, 0);}break;case 1:if (cmd == 1){// 亮灯gpiod_set_value(gpiono2, 1);}else{// 灭灯gpiod_set_value(gpiono2, 0);}break;case 2:if (cmd == 1){// 亮灯gpiod_set_value(gpiono3, 1);}else{// 灭灯gpiod_set_value(gpiono3, 0);}break;}return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}// 定义操作方法灯结构体变量并赋值
struct file_operations fops = {.open = mycdev_open,.unlocked_ioctl = mycdev_ioctl,.release = mycdev_close,
};static int __init mycdev_init(void)
{int ret;// 1.申请对象空间 cdev_alloccdev = cdev_alloc();if (cdev == NULL){printk("申请驱动对象空间失败\n");ret = -EFAULT;goto OUT1;}printk("申请驱动对象空间成功\n");// 2.初始化对象  cdev_initcdev_init(cdev, &fops);// 3.申请设备号  register_chrdev_region()/alloc_chrdev_region()// 动态申请if (major == 0){ret = alloc_chrdev_region(&devid, minor, 3, "mycdev");if (ret != 0){printk("动态申请设备号失败\n");goto OUT2;}// 统一后面的操作major = MAJOR(devid); // 根据设备号获取主设备号minor = MINOR(devid);}// 静态指定申请else{ret = register_chrdev_region(MKDEV(major, minor), 3, "mycdev");if (ret != 0){printk("静态指定设备号失败\n");goto OUT2;}}printk("申请设备号成功\n");// 4.注册驱动对象 cdev_add()ret = cdev_add(cdev, MKDEV(major, minor), 3);if (ret != 0){printk("注册设备驱动对象失败\n");goto OUT3;}printk("注册设备驱动对象成功\n");// 5.向上提交目录  class_create()cls = class_create(THIS_MODULE, "mycdev");if (IS_ERR(cls)){printk("向上提交目录失败\n");goto OUT4;}printk("向上提交目录成功\n");// 6.向上提交设备信息 device_create()int i;for (i = 0; i < 3; i++){dev = device_create(cls, NULL, MKDEV(major, i), NULL, "mycdev%d", i);}if (IS_ERR(dev)){printk("向上提交设备节点信息失败\n");goto OUT5;}printk("向上提交设备节点信息成功\n");//*******************************************************************//// 根据灯设备树节点的路径解析设备树信息dev_led = of_find_node_by_path("/leds");if (dev_led == NULL){printk("解析灯设备树节点失败\n");return -EFAULT;}printk("解析灯设备树节点成功\n");// led1申请gpio_desc对象并设置输出为低电平gpiono1 = gpiod_get_from_of_node(dev_led, "led1-gpios", 0, GPIOD_OUT_LOW, NULL);if (IS_ERR(gpiono1)){printk("申请gpio1对象失败\n");return -PTR_ERR(gpiono1);}printk("申请gpio1对象成功\n");// led2申请gpio_desc对象并设置输出为低电平gpiono2 = gpiod_get_from_of_node(dev_led, "led2-gpios", 0, GPIOD_OUT_LOW, NULL);if (IS_ERR(gpiono2)){printk("申请gpio2对象失败\n");return -PTR_ERR(gpiono2);}printk("申请gpio2对象成功\n");// led3申请gpio_desc对象并设置输出为低电平gpiono3 = gpiod_get_from_of_node(dev_led, "led3-gpios", 0, GPIOD_OUT_LOW, NULL);if (IS_ERR(gpiono3)){printk("申请gpio3对象失败\n");return -PTR_ERR(gpiono3);}printk("申请gpio3对象成功\n");return 0;OUT5:// 将提交成功的设备信息销毁for (--i; i >= 0; i--){device_destroy(cls, MKDEV(major, i));}
OUT4:class_destroy(cls);
OUT3:unregister_chrdev_region(MKDEV(major, minor), 3);
OUT2:kfree(cdev);
OUT1:return ret;
}
static void __exit mycdev_exit(void)
{// 1.销毁设备信息  device_destroyint i;for (i = 0; i < 3; i++){device_destroy(cls, MKDEV(major, i));}// 2.销毁目录    class_destroyclass_destroy(cls);// 3.注销驱动对象  cdev_delcdev_del(cdev);// 4.释放设备号   unregister_chrdev_region()unregister_chrdev_region(MKDEV(major, minor), 3);// 5.释放对象空间   kfree()kfree(cdev);// 灭灯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);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

作业2

驱动代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
/*myirq{interrupt-parent=<&gpiof>;//引用中断父节点interrupts=<9 0>,<7 0>,<8 0>;//声明和中断父节点的关系 9表示索引号,0表示默认设置
};
*/
struct device_node *dev_irq;
struct device_node *dev_led;
unsigned int irqno1;
unsigned int irqno2;
unsigned int irqno3;
struct gpio_desc *gpiono1;
struct gpio_desc *gpiono2;
struct gpio_desc *gpiono3;
//中断处理函数
irqreturn_t myirq_handler1(int irq, void *dev)
{//led1gpiod_set_value(gpiono1,!gpiod_get_value(gpiono1));printk("KEY1_INTERRUPT\n");return IRQ_HANDLED;
}
irqreturn_t myirq_handler2(int irq, void *dev)
{//led2gpiod_set_value(gpiono2,!gpiod_get_value(gpiono2));printk("KEY2_INTERRUPT\n");return IRQ_HANDLED;
}
irqreturn_t myirq_handler3(int irq, void *dev)
{//led3gpiod_set_value(gpiono3,!gpiod_get_value(gpiono3));printk("KEY3_INTERRUPT\n");return IRQ_HANDLED;
}
static int __init mycdev_init(void)
{int ret;//解析按键的设备树节点dev_irq=of_find_node_by_path("/myirq");if(dev_irq==NULL){printk("解析中断设备树节点失败\n");return -EFAULT;}printk("解析中断设备树节点成功\n");//根据设备树节点解析KEY1出软中断号irqno1=irq_of_parse_and_map(dev_irq,0);//按键1索引号为0if(!irqno1){printk("解析软中断号失败\n");return -ENXIO;}printk("解析key1软中断号成功 irqno1=%d\n",irqno1);//根据设备树节点解析KEY2出软中断号irqno2=irq_of_parse_and_map(dev_irq,1);//按键1索引号为1if(!irqno2){printk("解析软中断号失败\n");return -ENXIO;}printk("解析key2软中断号成功 irqno2=%d\n",irqno2);//根据设备树节点解析KEY3出软中断号irqno3=irq_of_parse_and_map(dev_irq,2);//按键1索引号为2if(!irqno3){printk("解析软中断号失败\n");return -ENXIO;}printk("解析key3软中断号成功 irqno3=%d\n",irqno3);//注册key1中断ret=request_irq(irqno1,myirq_handler1,IRQF_TRIGGER_FALLING,"key1",NULL);if(ret){printk("注册中断key1失败\n");return ret;}printk("注册key1中断成功\n");//注册key2中断ret=request_irq(irqno2,myirq_handler2,IRQF_TRIGGER_FALLING,"key2",NULL);if(ret){printk("注册key2中断失败\n");return ret;}printk("注册key2中断成功\n");//注册key3中断ret=request_irq(irqno3,myirq_handler3,IRQF_TRIGGER_FALLING,"key3",NULL);if(ret){printk("注册key3中断失败\n");return ret;}printk("注册key3中断成功\n");//*******************************************************************//// 根据灯设备树节点的路径解析设备树信息dev_led = of_find_node_by_path("/leds");if (dev_led == NULL){printk("解析灯设备树节点失败\n");return -EFAULT;}printk("解析灯设备树节点成功\n");// led1申请gpio_desc对象并设置输出为低电平gpiono1 = gpiod_get_from_of_node(dev_led, "led1-gpios", 0, GPIOD_OUT_LOW, NULL);if (IS_ERR(gpiono1)){printk("申请gpio1对象失败\n");return -PTR_ERR(gpiono1);}printk("申请gpio1对象成功\n");// led2申请gpio_desc对象并设置输出为低电平gpiono2 = gpiod_get_from_of_node(dev_led, "led2-gpios", 0, GPIOD_OUT_LOW, NULL);if (IS_ERR(gpiono2)){printk("申请gpio2对象失败\n");return -PTR_ERR(gpiono2);}printk("申请gpio2对象成功\n");// led3申请gpio_desc对象并设置输出为低电平gpiono3 = gpiod_get_from_of_node(dev_led, "led3-gpios", 0, GPIOD_OUT_LOW, NULL);if (IS_ERR(gpiono3)){printk("申请gpio3对象失败\n");return -PTR_ERR(gpiono3);}printk("申请gpio3对象成功\n");return 0;
}
static void __exit mycdev_exit(void)
{//注销key1中断free_irq(irqno1,NULL);//注销key2中断free_irq(irqno2,NULL);//注销key3中断free_irq(irqno3,NULL);// 灭灯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);}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

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

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

相关文章

Docker安装es以及ik分词器

1、拉取镜像 docker pull elasticsearch:7.10.12、下载对应版本的ik分词、并将它们解压到ik文件夹下&#xff0c;如图 https://github.com/medcl/elasticsearch-analysis-ik/releases 3、在服务器上创建文件夹 mkdir /usr/elklog/elk/es mkdir /usr/elklog/elk/es/data mkdi…

Web3教程| 如何发现并追踪“聪明钱”?

在加密领域&#xff0c;聪明钱&#xff08;Smart Money&#xff09;是指拥有专业知识、对市场有深入了解以及具有信息优势的专业投资机构或个人投资者。 聪明钱一直以来都是加密市场中的关注焦点&#xff0c;因为这些实体通常可以获得普通交易者不易获得的信息和资源&#xff0…

【Web开发指南】如何用MyEclipse进行JavaScript开发?

由于MyEclipse中有高级语法高亮显示、智能内容辅助和准确验证等特性&#xff0c;进行JavaScript编码不再是一项繁琐的任务。 MyEclipse v2023.1.2离线版下载 JavaScript项目 在MyEclipse 2021及以后的版本中&#xff0c;大多数JavaScript支持都是开箱即用的JavaScript源代码…

【运维】hive 终端突然不能使用:Hive Schema version does not match metastore‘s schema version

文章目录 一. 问题描述二. 常规排查1. 元数据库2. hive-site.xml相关meta连接信息检查 三. 正解 一. 问题描述 进入hive终端&#xff0c;执行如下命令报错&#xff1a; hive> show tables; FAILED: SemanticException org.apache.hadoop.hive.ql.metadata.HiveException: …

冒泡排序算法

冒泡排序 算法说明与代码实现&#xff1a; 简单分析&#xff0c;外循环次数为数据len(arr)-1次&#xff0c;内循环为len(arr)-外循环次数 下面是使用Go语言实现冒泡排序算法的示例&#xff1a; package mainimport "fmt"func bubbleSort(arr []int) {n : len(arr…

【JavaEE】简单了解JVM

目录 一、JVM中的内存区域划分 二、JVM的类加载机制 1、类加载的触发时机 2、双亲委派模型 1.1、向上委派 1.2、向下委派 三、JVM中的垃圾回收机制&#xff08;GC&#xff09; 1、确认垃圾 1.1、引用计数&#xff08;Java实际上没有使用这个方案&#xff0c;但是Pytho…

【HttpRunnerManager】搭建接口自动化测试平台实战

目录 一、需要准备的知识点 二、我搭建的环境 三、搭建过程 四、访问链接 五、两个问题点 【整整200集】超超超详细的Python接口自动化测试进阶教程&#xff0c;真实模拟企业项目实战&#xff01;&#xff01; 一、需要准备的知识点 1. linux: 安装 python3、nginx 安装和…

emWin - BMP图片显示

BmpCvt.exe 用途 利用BMP图片&#xff0c;进行GUI显示&#xff1b;ICON等图标都是小BMP图片&#xff0c;核心是将BMP图片&#xff0c;转成emWin支持的方式&#xff0c;最终显示到TFT屏上 使用BmpCvt.exe工具&#xff0c;将各个图片转成相应的C文件. emWin有关的工具&#xff…

测试|Selenium介绍及环境搭建

测试|Selenium介绍及环境搭建 1.Selenium是什么 Selenium是用来做web网站 UI自动化的测试工具/测试框架。 我们这里说的Selenium是Selenium2.0&#xff0c;它由Selenium IDE&#xff0c;Webdriver, Selenium Grid组成。 Selenium IDE是用于Selenium测试的完成集成开发环境&…

云计算——云计算关键技术

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​ 目录 前言 一.云计算关键技术 1.虚拟化技术 2.分布式数据存储技术 &#xff08;1&…

天下风云出我辈,AI准独角兽实在智能获评“十大数字经济风云企业

时值盛夏&#xff0c;各地全力拼经济的氛围同样热火朝天。在浙江省经济强区余杭区这片创业热土上&#xff0c;人工智能助力数字经济建设正焕发出蓬勃生机。 7月28日&#xff0c;经专家评审、公开投票&#xff0c;由中共杭州市余杭区委组织部&#xff08;区委两新工委&#xff…

如何解决制造业数字化改造的障碍?

制造业的数字化转型可能是一个复杂且具有挑战性的过程&#xff0c;但解决以下障碍有助于为成功实施铺平道路&#xff1a; 抵制变革&#xff1a;数字化转型中最常见的挑战之一是员工的抵制&#xff0c;尤其是那些习惯传统方法的员工。为了克服这一问题&#xff0c;组织需要培养一…

JDBC-笔记

JDBC 1. JDBC介绍 JDBC&#xff08;Java Database Connectivity&#xff09;是一种用于连接和操作数据库的 Java API。 通过Java操作数据库的流程 第一步&#xff1a;编写Java代码 第二步&#xff1a;Java代码将SQL发送到MySQL服务端 第三步&#xff1a;MySQL服务端接收到SQ…

Spring中IOC容器常用的接口和具体的实现类

在Spring框架没有出现之前&#xff0c;在Java语言中&#xff0c;程序员们创建对象一般都是通过关键字new来完成&#xff0c;那时流行一句话“万物即可new&#xff0c;包括女朋友”。但是这种创建对象的方式维护成本很高&#xff0c;而且对于类之间的相互关联关系很不友好。鉴于…

【Web】web

dns与域名 网络是基于tcp/ip协议进行通信和连接的 应用层——传输层——网络层——数据链路层——物理层 每一定的台主机都有一个唯一且固定的地址标识——IP地址 IP地址的做用&#xff1a;1.区分用户和计算机&#xff1b;2.进行通信 IP地址由32位二进制数组成&#xff0c;…

读取application-dev.properties的中文乱码【bug】

读取application-dev.properties的中文编码【bug】 2023-7-30 22:37:46 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星月云 博客主页是https://blog.csdn.net/qq_51625007 禁止其他平台发布时删除以上此话 bug 读取application-dev.propert…

ATFX汇市月报:7月美联储坚定加息,8月成利率决议空档期

7月汇市行情回顾—— 7月份&#xff0c;美元指数下跌1.01%&#xff0c;收盘在101.88点&#xff0c; 欧元升值0.76%&#xff0c;收盘价1.0997点&#xff1b; 日元升值1.41%&#xff0c;收盘价142.27点&#xff1b; 英镑升值1.08%&#xff0c;收盘价1.2835点&#xff1b; 瑞…

TSINGSEE青犀视频AI算法引擎中台在渣土车智慧管控场景中的应用

一、行业背景 随着社会的发展和人们生活水平的不断进步&#xff0c;大家对环境卫生和空气质量的要求越来越重视。渣土车是建筑垃圾的运输主力&#xff0c;也存在行驶频繁、不合规、不合法的操作&#xff0c;可能对交通安全、环境卫生和城市形象造成影响。比如在施工工地&#x…

【C++】C/C++内存管理

1、C/C内存分布 【1】栈又叫堆栈 – 非静态局部变量/函数参数/返回值等等&#xff0c;栈是向下增长的。 【2】内存映射段 – 是高效的I/O映射方式&#xff0c;用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存&#xff0c;做进程间通信 【3】堆 – 用于程序运…

Java面向对象的三大特征

Java面向对象的三大特征 java面向对象的三大特征&#xff1a;“封装、继承、多态”。更多Java技术知识&#xff0c;请登陆疯狂软件教育官网。微信搜索微信号&#xff1a;疯狂软件&#xff0c;参加2015年优惠活动&#xff0c;有机会获得优惠劵和代金劵。 以本文为例&#xff0c…