鼠标驱动框架:模拟键盘按键
/* 参考: drivers\hid\usbhid\usbmouse.c */
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb.h>
#include <linux/input.h>
#include <linux/hid.h>struct usb_mouse_as_key_desc {struct usb_device *dev;struct usb_interface *intf;const struct usb_device_id *id;int pipe, maxp;int bInterval;void *data_buffer;dma_addr_t data_dma;struct urb *urb;
};/* 1. 构造usb_driver * 1.1 id_table : 能支持哪些设备* 1.2 probe : 记录某些信息, 分配/设置/注册input_dev, 也许也可以在probe里面做"分配/填充/提交URB"*/static struct usb_device_id usb_mouse_as_key_id_table [] = {{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,USB_INTERFACE_PROTOCOL_MOUSE), .driver_info = (kernel_ulong_t)"it is a mouse", },/*.driver_info = (kernel_ulong_t)"it is a mouse" 可以增加一些probe需要的驱动信息,probe里面会自动得到这些信息*/{ } /* Terminating entry */
};static void usb_mouse_as_key_irq(struct urb *urb)
{struct input_dev *dev = urb->context;struct usb_mouse_as_key_desc *desc = input_get_drvdata(dev);signed char *data = desc->data_buffer;int status;//printk("%s %s %d, urb->status = %d\n", __FILE__, __FUNCTION__, __LINE__, urb->status);switch (urb->status) {case 0: /* success */break;case -ECONNRESET: /* unlink */case -ENOENT:case -ESHUTDOWN:return;/* -EPIPE: should clear the halt */default: /* error */goto resubmit; /*如果错误,重新提交*/}// printk("data[0] = 0x%x\n", data[1]);input_report_key(dev, KEY_L, data[1] & 0x01); /*查看鼠标数据格式可知data[1]代表 按键状态 见 07_使用libusb读取鼠标数据.md*/input_report_key(dev, KEY_S, data[1] & 0x02);input_report_key(dev, KEY_ENTER, data[1] & 0x04);input_sync(dev);
resubmit:status = usb_submit_urb (urb, GFP_ATOMIC);//printk("%s %s %d, status = %d\n", __FILE__, __FUNCTION__, __LINE__, status);
}static int usb_mouse_as_key_open(struct input_dev *dev)
{struct urb *urb;struct usb_mouse_as_key_desc *desc = input_get_drvdata(dev); /*获取我们之前存入的驱动信息*/int err;urb= desc->urb;printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);err = usb_submit_urb (urb, GFP_KERNEL);printk("%s %s %d, err = %d\n", __FILE__, __FUNCTION__, __LINE__, err);return err;
}static void usb_mouse_as_key_close(struct input_dev *dev)
{struct usb_mouse_as_key_desc *desc = input_get_drvdata(dev); /*获取我们之前存入的驱动信息*//* 取消/释放 URB */usb_kill_urb(desc->urb);usb_free_urb(desc->urb);
}static int usb_mouse_as_key_probe(struct usb_interface *intf, const struct usb_device_id *id)
{struct usb_device *dev = interface_to_usbdev(intf);struct input_dev *input_dev;struct usb_mouse_as_key_desc *desc;int error;struct usb_host_interface *interface;struct usb_endpoint_descriptor *endpoint;int pipe, maxp;printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);/* 1. 记录设备信息: intf *//*判断是不是真正的鼠标*/interface = intf->cur_altsetting;if (interface->desc.bNumEndpoints != 1)return -ENODEV;endpoint = &interface->endpoint[0].desc;if (!usb_endpoint_is_int_in(endpoint)) /*如果不是输入端口,说明不是真正的鼠标设备*/return -ENODEV;pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); /*管道一次性能够传输的数据*/desc = kmalloc(sizeof(struct usb_mouse_as_key_desc), GFP_KERNEL);desc->dev = dev;desc->intf = intf;desc->id = id;desc->pipe = pipe;desc->maxp = maxp;desc->bInterval = endpoint->bInterval;desc->data_buffer = usb_alloc_coherent(dev, maxp, GFP_ATOMIC, &desc->data_dma); /*分配dma*///printk("%s %s %d, desc->data_buffer = 0x%x\n", __FILE__, __FUNCTION__, __LINE__, desc->data_buffer);/* 2. 分配/设置/注册input_dev * 2.1 能产生哪类事件* 2.2 能产生这类事件里哪些些事件: L/S/ENTER ,可见 input 框架* 2.3 设置函数, 比如open* 2.4 在open函数里: 分配/填充/提交 URB* 2.5 URB的回调函数: 解析数据, 上报input_event*/input_dev = devm_input_allocate_device(&intf->dev); /*里面自带free ,一般带前缀的allocate,里面都自带free*/input_set_drvdata(input_dev, desc); /*存入一些我们想要的驱动描述信息*//* set 1: which type event ? */ __set_bit(EV_KEY, input_dev->evbit);/* set 2: which event ? */ __set_bit(KEY_L, input_dev->keybit);__set_bit(KEY_S, input_dev->keybit);__set_bit(KEY_ENTER, input_dev->keybit);/* set 3: open */input_dev->open = usb_mouse_as_key_open;input_dev->close = usb_mouse_as_key_close;/* 分配/填充 URB */desc->urb = usb_alloc_urb(0, GFP_KERNEL);usb_fill_int_urb(desc->urb,desc->dev,desc->pipe,desc->data_buffer,(desc->maxp > 8 ? 8 : desc->maxp),usb_mouse_as_key_irq,dev, /*context参数会传入回调函数*/desc->bInterval);/**如果URB使用DMA Buffer,需要如下的设置**/desc->urb->transfer_dma = desc->data_dma; desc->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;error = input_register_device(input_dev);usb_set_intfdata(intf, input_dev);return 0;
}static void usb_mouse_as_key_disconnect(struct usb_interface *intf)
{struct input_dev *input_dev = usb_get_intfdata (intf);struct usb_mouse_as_key_desc *desc = input_get_drvdata(input_dev);usb_free_coherent(desc->dev, desc->maxp, desc->data_buffer, desc->data_dma);kfree(desc);input_unregister_device(input_dev);usb_set_intfdata(intf, NULL);
}static struct usb_driver usb_mouse_as_key_driver = {.name = "usbmouse_as_key",.probe = usb_mouse_as_key_probe,.disconnect = usb_mouse_as_key_disconnect,.id_table = usb_mouse_as_key_id_table,
};/* 入口函数 / 出口函数 */
// module_usb_driver(usb_mouse_as_key_driver);可以使用这个宏一键完成入口函数 / 出口函数 等同于196:208行代码
static int __init usb_mouse_as_key__init(void)
{printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);return usb_register(&usb_mouse_as_key_driver);
}static void __exit usb_mouse_as_key__init_exit(void)
{ usb_deregister(&usb_mouse_as_key_driver);
}module_init(usb_mouse_as_key__init);
module_exit(usb_mouse_as_key__init_exit);/* 2. 注册usb_driver */MODULE_LICENSE("GPL");
装载该驱动时,首先要卸载原本内核自带的驱动程序
# 把USB鼠标查到开发板上
# 先看看原来有哪些设备节点
ls /dev/input/event*
# 安装驱动程序
insmod usbmouse_as_key.ko
# 再看看新得到了哪个设备节点
ls /dev/input/event*
# 执行命令, 假设event4是新节点
hexdump /dev/input/event4
# 点击鼠标按键即可观察输出信息
# 第2种测试方法: 执行以下命令,按鼠标左键、右键,再按中键就有输出"ls"
cat /dev/tty0
# 第3种测试方法: 执行以下命令(注意"<"号前后没有空格),就可以使用鼠标按键在控制台输入字符
exec 0</dev/tty0
打印内核input信息:
hexdump /dev/input/event* /*具体对应 event几 要自己判断*/
相关文章:
鼠标驱动框架:模拟键盘按键
/* 参考: drivers\hid\usbhid\usbmouse.c */ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> #include <linux/input.h> #include <linux/hid.h>st…...

ES6之Promise的链式调用
✨ 专栏介绍 在现代Web开发中,JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性,还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言,JavaScript具有广泛的应用场景&#x…...

HTML----JavaScript操作对象BOM对象
文章目录 目录 文章目录 本章要求 一.BOM模型概述 二.BOM核心:window对象 常用属性 常用方法: confirm() 案例 open ()close()案例 setTimeout( ) 案例 setInterval( ) 案例 document对象 练习 本章要求 了解BOM模型掌握BOM模型实际应用 一.BOM模型…...
隆道数智大会回顾|第13期《如何构建绿色产业供应链新生态》(完)
本期演讲嘉宾: 史文月 采购与供应链专家 邢庆峰 品类管理和质量管理专家 刘婷婷 中兴通讯供应链规划总监 张燕华 正大生物CIO 吴树贵 隆道公司总裁 本期演讲主题: 如何构建绿色产业供应链新生态 本期内容要点: 1.供应链管理的核心问…...

粒子群优化pso结合bp神经网络优化对csv文件预测matlab(3)
1.csv数据为密西西比数据集,获取数据集可以管我要,数据集内容形式如下图: 2.代码 这里参考的是b站的一位博主。 数据集导入教程在我的另一篇文章bp写过,需要的话可以去看一下 psobp.m close all clc%读取数据 inputX; outputY;…...

软性演员-评论家算法 SAC
软性演员-评论家算法 SAC 软性演员-评论家算法 SAC优势原理软性选择模型结构目标函数重参数化熵正则化代码实现 软性演员-评论家算法 SAC 优势原理 DDPG 的问题在于,训练不稳定、收敛差、依赖超参数、不适应复杂环境。 软性演员-评论家算法 SAC,更稳定…...

Nginx多域名部署多站点
目录 1.修改配置文件nginx.conf 2. 修改hosts文件 1.修改配置文件nginx.conf 在配置文件的 server_name 处修改成自己需要的域名,然后保存退出 j 查看语法是否错误,然后重启nginx nginx -t # 查看语法是否正确 systemctl restart nginx # 重启nginx …...
Java的常规面试题
Java的面试题主要涉及Java基础知识、并发编程、集合原理、JVM原理、I/O与网络编程、设计模式、互联网常用框架等多个领域[6]。一些常见的面试问题包括: 1. 面向对象的特征:继承、封装和多态性。 2. 访问修饰符public、private、protected以及默认时的区别…...

大数据技术发展史
文章目录 Google论文HadoopHive大数据生态 Google论文 今天我们常说的大数据技术,其实起源于Google在2004年前后发表的三篇论文,也就是我们经常听到的“三驾马车”,分别是分布式文件系统GFS、大数据分布式计算框架MapReduce和NoSQL数据库系统…...

linux常见基础指令
入门常见基础指令 ls、stat、 pwd 、cd、tree、 whoami、 touch、 mkdir、 rm 、 man、 cp、mv、cat、tac、echo、>、 >>、 < 、more、 less、 head、 tail、date、 cal、 find、 which、alias、whereis、grep、zip与unzip、 tar、bc、uname、xargs... 热键Tab、…...
“人家赚那么多”系列01:如何练习?练什么?
01 如何练习?练习什么? 今年计划重点围绕「在不骗自己的前提下,如何才能把事儿彻底做好,并做得有声有色?」为主题来写点儿东西,聊聊我是怎么做的,如何通过一些有效的方法来不断优化自己的。 想把…...
【Android】使用android studio查看内置数据库信息
要使用Android Studio查看内置数据库信息,可以按照以下步骤进行操作: 打开Android Studio并打开你的项目。 在左侧的Project窗口中,找到并展开你的app模块。 找到并展开"app" > "src" > "main"文件夹。…...

PHP开发日志 ━━ 基于PHP和JS的AES相互加密解密方法详解(CryptoJS) 适合CryptoJS4.0和PHP8.0
最近客户在做安全等保,需要后台登录密码采用加密方式,原来用个base64变形一下就算了,现在不行,一定要加密加key加盐~~ 前端使用Cypto-JS加密,传输给后端使用PHP解密,当然,前端虽然有key有盐&…...

2021-01-03 excel实现列递增,行保持不变
需求:excel文档数据操作的时候发现自动递增只能实现列不变行号递增 我这里里需要的是列递增行不变 解决方式:通过一些函数的组合使用 INDIRECT("驻场明细!"&CHAR(ROW()62)&ROW(驻场明细!A$28)) INDIRECT()函数的使用: INDI…...
[Python]两个杯子取水问题
利用两个杯子巧取三升水: 今天的这个趣味数学小游戏是利用两个没有刻度的水杯,巧妙地取出三升水来。 题目的条件是:一个总容量为6升的杯子和一个总容量为5升的杯子,同时面前有无限容量的水供你使用。不借助其它任何的容器…...
C++汇编语言学习计划
前几天买了某游戏的外挂,感觉外挂在我计算机上进行了不少操作,我想一探究竟,可是只有exe,没办法,翻译成汇编我也看不懂,索性来简单学习下。访问Chatgpt4,给了如下学习计划。 要从零开始学习C生成…...

微信服务号升级订阅号条件
服务号和订阅号有什么区别?服务号转为订阅号有哪些作用?首先我们要看一下服务号和订阅号的主要区别。1、服务号推送的消息没有折叠,消息出现在聊天列表中,会像收到消息一样有提醒。而订阅号推送的消息是折叠的,“订阅号…...

SpringBoot整合mybatis多数据源
废话不多说先上结果 对应数据库 首先导入所需的mybatis、mysql和lombok依赖 <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version></dependen…...

垃圾收集器与内存分配策略
内存分配和回收原则 对象优先在Eden区分配 大对象直接进入老年代 长期存活的对象进入老年代 什么是内存泄漏 不再使用的对象在系统中未被回收,内存泄漏的积累可能会导致内存溢出 自动垃圾回收与手动垃圾回收 自动垃圾回收:由虚拟机来自动回收对象…...
Python计算三角形的面积
Python 计算三角形的面积 以下实例为通过用户输入三角形三边长度,并计算三角形的面积: # 三角形第一边长 a 3 # 三角形第二边长 b 4 c float( input("输入三角形第三边长: ") ) # 计算半周长 s (a b c) / 2 # 计算…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...
0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化
是不是受够了安装了oracle database之后sqlplus的简陋,无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话,配置.bahs_profile后也能解决上下翻页这些,但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可,…...