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

【驱动开发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");

相关文章:

【驱动开发day8作业】

作业1&#xff1a; 应用层代码 #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…...

yxBUG记录

1、 原因&#xff1a;前端参数method方法名写错。 2、Field ‘REC_ID‘ doesn‘t have a default value 问题是id的生成问题。 项目的表不是自增。项目有封装好的方法。调用方法即可。 params.put("rec_id",getSequence("表名")) 3、sql语句有问题 检…...

uniapp引入inconfont自定义导航栏

app,h5端引入 uniapp本身的全局设置中有个iconfontsrc属性 所以只需要 1.iconfont将需要的icon添加至项目 2.下载到本地解压后,将其中的ttf文件,放在static静态目录下 3.在page.json中对全局文件进行配置tabBar(导航图标) “iconfontSrc”: “static/font/iconfont.ttf”, …...

OSLog与NSLog对比

NSLog: NSLog的文档&#xff0c;第一句话就说&#xff1a;Logs an error message to the Apple System Log facility.&#xff0c;所以首先&#xff0c;NSLog就不是设计作为普通的debug log的&#xff0c;而是error log&#xff1b;其次&#xff0c;NSLog也并非是printf的简单…...

全网最细,Fiddler修改接口返回数据详细步骤实战,辅助接口测试...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 在测试的过程中&a…...

Mysql自动同步的详细设置步骤

以下步骤是真实的测试过程&#xff0c;将其记录下来&#xff0c;与大家共同学习。 一、环境说明&#xff1a; 1、主数据库&#xff1a; &#xff08;1&#xff09;操作系统&#xff1a;安装在虚拟机中的CentOS Linux release 7.4.1708 (Core) [rootlocalhost ~]# cat /etc/redh…...

opencv-38 形态学操作-闭运算(先膨胀,后腐蚀)cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

闭运算是先膨胀、后腐蚀的运算&#xff0c;它有助于关闭前景物体内部的小孔&#xff0c;或去除物体上的小黑点&#xff0c;还可以将不同的前景图像进行连接。 例如&#xff0c;在图 8-17 中&#xff0c;通过先膨胀后腐蚀的闭运算去除了原始图像内部的小孔&#xff08;内部闭合的…...

jenkins gitlab多分支构建发布

内容背景介绍 这个是新手教程,普及概念为主 公司现在还使用单分支发布测试环境和生产,多人协同开发同一个项目导致测试环境占用等待等情况 测试环境占用等待问题 测试环境代码直接合并到 master,容易导致误发布到生产的情况 避免多版本同时发布测试不完善的情况出现 中间件…...

刷题笔记 day8

1004 最大连续1的个数 III 这道题要求将原数组中的0翻转成1&#xff0c;求出最大元素全是1的子数组长度&#xff0c;看这道题第一感觉还要将里面的0变成1&#xff0c;感觉这道题解决起来很麻烦&#xff0c;但是我们可以转变思路&#xff0c;找出其最大子数组&#xff0c;使得子…...

C 语言的表达式

表达式 expression 表达式由运算符和运算对象组成。 最简单的表达式是一个单独的运算对象&#xff0c;以此为基础可以建立复杂的表达式。 一些表达式由子表达式&#xff08;subexpression&#xff09;组成。子表达式即较小的表达式。 这些都是一些表达式&#xff1a; -4 a…...

C++设计模式创建型之单例模式

一、概述 单例模式也称单态模式&#xff0c;是一种创建型模式&#xff0c;用于创建只能产生一个对象实例的类。例如&#xff0c;项目中只存在一个声音管理系统、一个配置系统、一个文件管理系统、一个日志系统等&#xff0c;甚至如果吧整个Windows操作系统看成一个项目&#xf…...

杂记 | 记录一次使用Docker安装gitlab-ce的过程(含配置交换内存)

文章目录 01 准备工作02 &#xff08;可选&#xff09;配置交换内存03 编辑docker-compose.yml04 启动并修改配置05 nginx反向代理06 &#xff08;可选&#xff09;修改配置文件07 访问并登录 01 准备工作 最近想自建一个gitlab服务来保存自己的项目&#xff0c;于是找到gitla…...

MyBatis@Param注解的用法

一、前言 本人在学习mybatis的过程中遇到的一个让人不爽的bug&#xff0c;在查找了些相关的资料后得以解决&#xff0c;遂记录。 二、报错及解决 mapper中有一方法&#xff1a; Select("select * from emp " "where name like concat(%, #{name}, %) "…...

Shader 编程:GLSL 重要的内置函数

该原创文章首发于微信公众号&#xff1a;字节流动 未经作者&#xff08;微信ID&#xff1a;Byte-Flow&#xff09;允许&#xff0c;禁止转载 前面发了一些关于 Shader 编程的文章&#xff0c;有读者反馈太碎片化了&#xff0c;希望这里能整理出来一个系列&#xff0c;方便系统的…...

浏览器同源策略

浏览器同源策略 同源策略&#xff1a;是一个重要的浏览器的安全策略&#xff0c;用于限制一个源的文档或者它加载的脚本如何能与另一个源的资源进行交互 它能帮助阻隔恶意文档&#xff0c;减少可能被攻击的媒介 例如&#xff1a;被钓鱼网站收集信息&#xff0c;使用ajax发起…...

GD32F103的EXTI中断和EXTI事件

GD32F103的EXTI可以产生中断&#xff0c;也产生事件信号。 GD32F03的EXTI触发源: 1、I/O管脚的16根线&#xff1b; 2、内部模块的4根线(包括LVD、RTC闹钟、USB唤醒、以太网唤醒)。 通过配置GPIO模块的AFIO_EXTISSx寄存器&#xff0c;所有的GPIO管脚都可以被选作EXTI的触发源…...

了解 spring MVC + 使用spring MVC - springboot

前言 本篇介绍什么是spring MVC &#xff0c;如何使用spring MVC&#xff0c;了解如何连接客户端与后端&#xff0c;如何从前端获取各种参数&#xff1b;如有错误&#xff0c;请在评论区指正&#xff0c;让我们一起交流&#xff0c;共同进步&#xff01; 文章目录 前言1. 什么…...

C#中的Invoke

在 C# 中&#xff0c;Invoke() 是一个用于调用方法的方法&#xff0c;它能够在运行时动态地调用一个方法。 Invoke() 方法的使用方式有两种&#xff1a; 通过 MethodInfo 对象调用&#xff1a; using System.Reflection;namespace ConsoleApp_Invoke {public class Program{…...

Hive终端命令行打印很多日志时,如何设置日志级别

示例&#xff1a;use test; 切换到test数据库时&#xff0c;输出很多日志信息不方便看结果&#xff0c;如下图。 解决方法&#xff1a; 退出hive命令行界面&#xff08;ctrlC&#xff09;执行“vi /usr/local/apache-hive-3.1.2-bin/conf/log4j.properties”命令&#xff0c;创…...

Android的PopupWindow(详细版)

经典好文推荐,通过阅读本文,您将收获以下知识点: 一、PopupWindow简介 二、PopupWindow 的使用方法 三、底部PopupWindow的实现 四、参考文献 一、PopupWindow简介 在学习PopupWindow之前,我们先了解一下PopupWindow的继承关系。 PopupWindow继承关系如下: java.lang.Obje…...

coze-loop应用指南:在数据分析、Web开发等场景下的优化技巧

coze-loop应用指南&#xff1a;在数据分析、Web开发等场景下的优化技巧 1. 工具介绍与核心功能 coze-loop是一款基于Ollama框架的AI代码优化工具&#xff0c;它将复杂的代码优化过程简化为三步操作&#xff1a;选择目标、粘贴代码、获取优化建议。这个工具特别适合需要快速提…...

人工智能应用- 走向未来:06.人与人工智能

智能时代的到来已是不可逆转的趋势。我们不得不承认一个现实&#xff1a;在某些领域&#xff0c;人工智能已经超越了普通人的能力&#xff0c;而且这一趋势正在加速。那么&#xff0c;人与人工智能的关系未来将如何演变&#xff1f;是竞争&#xff0c;还是共存&#xff1f;人工…...

Python高效实现:质因数分解的三种算法对比

1. 质因数分解&#xff1a;从数学概念到Python实现 质因数分解是数学中一个基础但重要的概念。简单来说&#xff0c;就是把一个正整数分解成若干个质数相乘的形式。比如数字28可以分解为227&#xff0c;这里的2和7都是质数&#xff0c;也就是28的质因数。这个概念在密码学、数据…...

路沿模板,乐山水泥路面模板,40公分路面钢模哪里有名

打路面模板&#xff1a;乐山水泥路面的优质之选在道路建设中&#xff0c;打路面模板起着至关重要的作用。它不仅关系到路面的成型质量&#xff0c;还影响着整个工程的效率和成本。乐山地区对于道路建设的需求不断增加&#xff0c;尤其是在水泥路面的铺设方面&#xff0c;40公分…...

Hunyuan-MT 7B一键部署教程:基于Git实现快速环境搭建

Hunyuan-MT 7B一键部署教程&#xff1a;基于Git实现快速环境搭建 想试试那个在国际翻译比赛里拿了30个第一的Hunyuan-MT-7B模型吗&#xff1f;你可能在网上看到过它的介绍&#xff0c;支持几十种语言&#xff0c;翻译效果据说很惊艳。但一看到“本地部署”、“环境配置”这些词…...

从攻到防:实战演练基于Wireshark与Snort的DoS攻击检测

1. 拒绝服务攻击初探&#xff1a;原理与危害剖析 想象一下周末去热门餐厅吃饭的场景。当所有座位都被占满&#xff0c;门口还不断涌入大量"假顾客"时&#xff0c;真正的食客就会被挡在门外——这就是拒绝服务攻击&#xff08;DoS&#xff09;的生动写照。作为网络安…...

Git子模块更新报错?手把手教你解决‘Unable to find origin/master revision‘问题

Git子模块更新报错深度解析&#xff1a;从原理到实战解决方案 1. 问题现象与核心原因分析 当你执行git submodule update --remote命令时&#xff0c;突然遇到fatal: Unable to find current origin/master revision in submodule path错误提示&#xff0c;这种场景在团队协作…...

RTK定位从入门到实践:如何利用千寻服务和Ntrip协议,让你的无人机定位精度达到厘米级?

RTK定位从入门到实践&#xff1a;如何利用千寻服务和Ntrip协议实现厘米级无人机定位 当无人机在农田上方悬停时&#xff0c;1米的定位误差可能导致农药喷洒完全错过目标作物&#xff1b;当测绘无人机进行地形扫描时&#xff0c;几厘米的高度误差可能使整个3D建模数据失效。这就…...

OpenRocket:革新性全流程火箭设计的开源技术突破实践

OpenRocket&#xff1a;革新性全流程火箭设计的开源技术突破实践 【免费下载链接】openrocket Model-rocketry aerodynamics and trajectory simulation software 项目地址: https://gitcode.com/GitHub_Trending/op/openrocket OpenRocket作为一款基于Java开发的开源火…...

LeetCode 11. Container With Most Water 题解

LeetCode 11. Container With Most Water 题解 题目描述 给你 n 个非负整数 a1&#xff0c;a2&#xff0c;...&#xff0c;an&#xff0c;每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线&#xff0c;垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条…...