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

linux input子系统深度剖析

input 就是输入的意思,因此 input 子系统就是管理输入的子系统,和 pinctrl gpio 子系统
一样,都是 Linux 内核针对某一类设备而创建的框架。比如按键输入、键盘、鼠标、触摸屏等
等这些都属于输入设备,不同的输入设备所代表的含义不同,按键和键盘就是代表按键信息,
鼠标和触摸屏代表坐标信息,因此在应用层的处理就不同,对于驱动编写者而言不需要去关心
应用层的事情,我们只需要按照要求上报这些输入事件即可。为此 input 子系统分为 input 驱动
层、 input 核心层、 input 事件处理层,最终给用户空间提供可访问的设备节点。
中左边就是最底层的具体设备,比如按键、 USB 键盘 / 鼠标等,中间部分属于Linux 内核空间,分为驱动层、核心层和事件层,最右边的就是用户空间,所有的输入设备以文件的形式供用户应用程序使用。可以看出 input 子系统用到了我们前面讲解的驱动分层模型,我们编写驱动程序的时候只需要关注中间的驱动层、核心层和事件层,这三个层的分工如下: 驱动层:输入设备的具体驱动程序,比如按键驱动程序,向内核层报告输入内容。
核心层:承上启下,为驱动层提供输入设备注册和操作接口。通知事件层对输入事件进行
处理。
事件层:主要和用户空间进行交互。
input 核心层会向 Linux 内核注册一个字符设备,大家找到 drivers/input/input.c 这个文件,
input.c 就是 input 输入子系统的核心层,此文件里面有如下所示代码:
1767 struct class input_class = {
1768 .name = "input",
1769 .devnode = input_devnode,
1770 };
......
2414 static int __init input_init(void)
2415 {
2416 int err;
2417
2418 err = class_register(&input_class);
2419 if (err) {
2420 pr_err("unable to register input_dev class\n");
2421 return err;
2422 }
2423
2424 err = input_proc_init();
2425 if (err)
2426 goto fail1;
2427
2428 err = register_chrdev_region(MKDEV(INPUT_MAJOR, 0),
2429 INPUT_MAX_CHAR_DEVICES, "input");
2430 if (err) {
2431 pr_err("unable to register char major %d", INPUT_MAJOR);
2432 goto fail2;
2433 }
2434
2435 return 0;
2436
2437 fail2: input_proc_exit();
2438 fail1: class_unregister(&input_class);
2439 return err;
2440 }
注册一个 input 类,这样系统启动以后就会在 /sys/class 目录下有一个 input 子目录。
注册一个字符设备,主设备号为 INPUT_MAJOR INPUT_MAJOR 定义在 include/uapi/linux/major.h 文件中,
#define INPUT_MAJOR 13
input 子系统的所有设备主设备号都为 13 ,我们在使用 input 子系统处理输入设备的时候就不需要去注册字符设备了,我们只需要向系统注册一个 input_device 即可。


1、注册 input_dev

在使用 input 子系统的时候我们只需要注册一个 input 设备即可, input_dev 结构体表示 input
设备,此结构体定义在 include/linux/input.h 文件中,定义如下 ( 有省略 )
121 struct input_dev {
122 const char *name;
123 const char *phys;
124 const char *uniq;
125 struct input_id id;
126
127 unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
128
129 unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; /* 事件类型的位图 */
130 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; /* 按键值的位图 */
131 unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; /* 相对坐标的位图 */ 
132 unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; /* 绝对坐标的位图 */
133 unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)]; /* 杂项事件的位图 */
134 unsigned long ledbit[BITS_TO_LONGS(LED_CNT)]; /*LED 相关的位图 */
135 unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];/* sound 有关的位图 */
136 unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; /* 压力反馈的位图 */
137 unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; /*开关状态的位图 */
......
189 bool devres_managed;
190 };
evbit 表示输入事件类型,可选的事件类型定义在 include/uapi/linux/input.h 文件中,事件类型如下:
#define EV_SYN 0x00 /* 同步事件
*/
#define EV_KEY 0x01 /* 按键事件
*/
#define EV_REL 0x02 /* 相对坐标事件
*/
#define EV_ABS 0x03 /* 绝对坐标事件
*/
#define EV_MSC 0x04 /* 杂项 ( 其他 ) 事件 */
#define EV_SW 0x05 /* 开关事件
*/
#define EV_LED 0x11 /* LED
*/
#define EV_SND 0x12 /* sound( 声音 )
*/
#define EV_REP 0x14 /* 重复事件
*/
#define EV_FF 0x15 /* 压力事件
*/
#define EV_PWR 0x16 /* 电源事件
*/
#define EV_FF_STATUS 0x17 /* 压力状态事件
*/
比如本章我们要使用到按键,那么就需要注册 EV_KEY 事件,如果要使用连按功能的话
还需要注册 EV_REP 事件。
evbit keybit relbit 等等都是存放不同事件对应的值。比如我们本章要使用按键事件,因此要用到 keybit keybit 就是按键事件使用的位图,Linux 内核定义了很多按键值,这些按键值定义在 include/uapi/linux/input.h 文件中,按键值如下:
215 #define KEY_RESERVED 0
216 #define KEY_ESC 1
217 #define KEY_1 2
218 #define KEY_2 3
219 #define KEY_3 4
220 #define KEY_4 5
221 #define KEY_5 6
222 #define KEY_6 7
223 #define KEY_7 8
224 #define KEY_8 9
225 #define KEY_9 10
226 #define KEY_0 11
......
794 #define BTN_TRIGGER_HAPPY39 0x2e6
795 #define BTN_TRIGGER_HAPPY40 0x2e7
我们可以将开发板上的按键值设置为示例代码 58.1.2.4 中的任意一个,比如我们本章实验
会将 I.MX6U-ALPHA 开发板上的 KEY 按键值设置为 KEY_0 。在编写 input 设备驱动的时候我们需要先申请一个 input_dev 结构体变量,使用 input_allocate_device 函数来申请一个 input_dev。
struct input_dev *input_allocate_device(void)
void input_free_device(struct input_dev *dev)
int input_register_device(struct input_dev *dev)
void input_unregister_device(struct input_dev *dev)
①、使用 input_allocate_device 函数申请一个 input_dev
②、初始化 input_dev 的事件类型以及事件值。
③、使用 input_register_device 函数向 Linux 系统注册前面初始化好的 input_dev
④、卸载 input 驱动的时候需要先使用 input_unregister_device 函数注销掉注册的 input_dev
然后使用 input_free_device 函数释放掉前面申请的 input_dev input_dev
1 struct input_dev *inputdev; /* input 结构体变量 */
2 
3 /* 驱动入口函数 */
4 static int __init xxx_init(void)
5 {
6 ......
7 inputdev = input_allocate_device(); /* 申请 input_dev */
8 inputdev->name = "test_inputdev"; /* 设置 input_dev 名字 */
9 
10 /*********第一种设置事件和事件值的方法***********/
11 __set_bit(EV_KEY, inputdev->evbit); /* 设置产生按键事件 */
12 __set_bit(EV_REP, inputdev->evbit); /* 重复事件 */
13 __set_bit(KEY_0, inputdev->keybit); /*设置产生哪些按键值 */
14 /************************************************/
15 
16 /*********第二种设置事件和事件值的方法***********/
17 keyinputdev.inputdev->evbit[0] = BIT_MASK(EV_KEY) |
BIT_MASK(EV_REP);
18 keyinputdev.inputdev->keybit[BIT_WORD(KEY_0)] |=
BIT_MASK(KEY_0);
19 /************************************************/
20
21 /*********第三种设置事件和事件值的方法***********/
22 keyinputdev.inputdev->evbit[0] = BIT_MASK(EV_KEY) |
BIT_MASK(EV_REP);
23 input_set_capability(keyinputdev.inputdev, EV_KEY, KEY_0);
24 /************************************************/
25 
26 /* 注册 input_dev */
27 input_register_device(inputdev);
28 ......
29 return 0;
30 }
31
32 /* 驱动出口函数 */
33 static void __exit xxx_exit(void)
34 {
35 input_unregister_device(inputdev); /* 注销 input_dev */
36 input_free_device(inputdev); /* 删除 input_dev */
37 }
定义一个 input_dev 结构体指针变量。驱动入口函数,在此函数中完成 input_dev 的申请、设置、注册等工作。第 7 行调用 input_allocate_device 函数申请一个 input_dev。第 10~23 行都是设置 input 设备事件和按键值,这里用了三种方法来设置事件和按键值。第 27 行调用 input_register_device 函数向 Linux 内核注册 inputdev。驱动出口函数,第 35 行调用 input_unregister_device 函数注销前面注册的 input_dev,第 36 行调用 input_free_device 函数删除前面申请的 input_dev。
当我们向 Linux 内核注册好 input_dev 以后还不能高枕无忧的使用 input 设备, input 设备都
是具有输入功能的,但是具体是什么样的输入值 Linux 内核是不知道的,我们需要获取到具体
的输入值,或者说是输入事件,然后将输入事件上报给 Linux 内核。比如按键,我们需要在按
键中断处理函数,或者消抖定时器中断函数中将按键值上报给 Linux 内核,这样 Linux 内核才
能获取到正确的输入值。不同的事件,其上报事件的 API 函数不同,我们依次来看一下一些常
用的事件上报 API 函数。
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
dev :需要上报的 input_dev
type: 上报的事件类型,比如 EV_KEY
code 事件码,也就是我们注册的按键值,比如 KEY_0 KEY_1 等等。
value :事件值,比如 1 表示按键按下, 0 表示按键松开。
input_event 函数可以上报所有的事件类型和事件值, Linux 内核也提供了其他的针对具体
事件的上报函数,这些函数其实都用到了 input_event 函数。比如上报按键所使用的
input_report_key 函数,此函数内容如下:
static inline void input_report_key(struct input_dev *dev,
unsigned int code, int value)
{input_event(dev, EV_KEY, code, !!value);
}
input_report_key 函数的本质就是 input_event 函数,如果要上报按键事件的话还是建议大家使用 input_report_key 函数。
同样的还有一些其他的事件上报函数,这些函数如下所示:
void input_report_rel(struct input_dev *dev, unsigned int code, int value)
void input_report_abs(struct input_dev *dev, unsigned int code, int value)
void input_report_ff_status(struct input_dev *dev, unsigned int code, int value)
void input_report_switch(struct input_dev *dev, unsigned int code, int value)
void input_mt_sync(struct input_dev *dev)
按键的上报事件的参考代码如下
1 /* 用于按键消抖的定时器服务函数 */
2 void timer_function(unsigned long arg)
3 {
4 unsigned char value;
5 
6 value = gpio_get_value(keydesc->gpio); /* 读取 IO 值 */
7 if(value == 0){ /* 按下按键 */
8 /* 上报按键值 */
9 input_report_key(inputdev, KEY_0, 1); /* 最后一个参数 1,按下 */
10 input_sync(inputdev); /* 同步事件 */
11 } else { /* 按键松开 */
12 input_report_key(inputdev, KEY_0, 0); /* 最后一个参数 0,松开 */
13 input_sync(inputdev); /* 同步事件 */
14 } 
15 }
获取按键值,判断按键是否按下。如果按键值为 0 那么表示按键被按下了,如果按键按下的话就要使用input_report_key 函数向 Linux 系统上报按键值,比如向 Linux 系统通知 KEY_0 这个按键按下了。第 12~13 行,如果按键值为 1 的话就表示按键没有按下,是松开的。向 Linux 系统通知
KEY_0 这个按键没有按下或松开了。

input_event 结构体

Linux 内核使用 input_event 这个结构体来表示所有的输入事件, input_envent 结构体定义在
include/uapi/linux/input.h 文件中,结构体内容如下:
24 struct input_event {
25 struct timeval time;
26 __u16 type;
27 __u16 code;
28 __s32 value;
29 };
我们依次来看一下 input_event 结构体中的各个成员变量:
time :时间,也就是此事件发生的时间,为 timeval 结构体类型, timeval 结构体定义如下:
1 typedef long __kernel_long_t;
2 typedef __kernel_long_t __kernel_time_t;
3 typedef __kernel_long_t __kernel_suseconds_t;
4
5 struct timeval {
6 __kernel_time_t tv_sec; /* 秒 */
7 __kernel_suseconds_t tv_usec; /* 微秒 */
8 };
  type: 事件类型,比如 EV_KEY ,表示此次事件为按键事件,此成员变量为 16 位。
  code:事件码,比如在 EV_KEY 事件中 code 就表示具体的按键码,如: KEY_0、KEY_1
  等等这些按键。此成员变量为 16 位。
value:值,比如 EV_KEY 事件中 value 就是按键值,表示按键有没有被按下,如果为 1 的
话说明按键按下,如果为 0 的话说明按键没有被按下或者按键松开了。
input_envent 这个结构体非常重要,因为所有的输入设备最终都是按照 input_event 结构体
呈现给用户的,用户应用程序可以通过 input_event 来获取到具体的输入事件或相关的值,比如
  按键值等。关于 input 子系统就讲解到这里,接下来我们就以开发板上的 KEY0 按键为例,讲
解一下如何编写 input 驱动。        

相关文章:

linux input子系统深度剖析

input 就是输入的意思,因此 input 子系统就是管理输入的子系统,和 pinctrl 、 gpio 子系统 一样,都是 Linux 内核针对某一类设备而创建的框架。比如按键输入、键盘、鼠标、触摸屏等 等这些都属于输入设备,不同的输入设备…...

香蕉派 BPI-CM6 工业级核心板采用进迭时空K1 8核 RISC-V 芯片开发

BPI-CM6 产品介绍 香蕉派BPI-CM6是一款工业级RISC-V核心板,它采用SpacemiT K1 8核RISC-V芯片设计,CPU集成2.0 TOPs AI计算能力。8/16G DDR和8/16/32/128G eMMC。设计了板对板连接器,以增强稳定性,与树莓派CM4尺寸相同&#xff0c…...

9.4分漏洞!Next.js Middleware鉴权绕过漏洞安全风险通告

今日,亚信安全CERT监控到安全社区研究人员发布安全通告,Next.js 存在一个授权绕过漏洞,编号为 CVE-2025-29927。攻击者可能通过发送精心构造的 x-middleware-subrequest 请求头绕过中间件安全控制,从而在未授权的情况下访问受保护…...

【Unity3D实现UI轮播效果】

系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、效果展示👉二、实现步骤👉2-1、搭建UI👉2-2、代码实现👉2-3、代码挂载使用👉三、扩展实现👉壁纸分享👉总结👉前言 功能需求如图所示,点击下一个按钮,所有卡片向右滚动,其中最后一张需要变更…...

谈谈 Webpack 中的 Loader 和 Plugin,它们的区别是什么?

Webpack Loader与Plugin深度解析 作为前端工程化的核心工具,Webpack的Loader和Plugin机制是其强大扩展能力的基石。 理解它们的差异和适用场景,是构建高效打包体系的关键。 我们将从底层原理到实际应用,深入剖析两者的区别。 核心概念对比…...

C#单例模式

单例模式 (Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化对个对象,一个最好的办法就是,让类自身负责保护它的唯一实例。这个类可以保证没…...

Oracle 数据库通过exp/imp工具迁移指定数据表

项目需求:从prod数据库迁移和复制2个表(BANK_STATE,HBS)的数据到uat数据库环境。 数据库版本:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 迁移工具:客户端exp/imp工具 -- 执行命令 从Prod数据库导出数据exp us…...

MongoDB 与 Elasticsearch 使用场景区别及示例

一、核心定位差异 ‌MongoDB‌ ‌定位‌:通用型文档数据库,侧重数据的存储、事务管理及结构化查询,支持 ACID 事务‌。‌典型场景‌: 动态数据结构存储(如用户信息、商品详情)‌。需事务支持的场景&#xf…...

PyTorch生成式人工智能实战:从零打造创意引擎

PyTorch生成式人工智能实战:从零打造创意引擎 0. 前言1. 生成式人工智能1.1 生成式人工智能简介1.2 生成式人工智能技术 2. Python 与 PyTorch2.1 Python 编程语言2.2 PyTorch 深度学习库 3. 生成对抗网络3.1 生成对抗网络概述3.2 生成对抗网络应用 4. Transformer4…...

蓝桥杯高频考点——二分(含C++源码)

二分 基本框架整数查找(序列二分的模版题 建议先做)满分代码及思路solution 子串简写满分代码及思路solution 1(暴力 模拟双指针70分)solution 2(二分 AC) 管道满分代码及思路样例解释与思路分析solution 最…...

VUE3项目VITE打包优化

VUE3项目VITE打包优化 代码加密依赖配置效果对比图 自动导入依赖配置 代码压缩依赖配置效果对比图 图片压缩依赖配置效果对比图 字体压缩总结与实践运用效果 代码加密 依赖 npm install -D vite-plugin-bundle-obfuscator配置 import vitePluginBundleObfuscator from "…...

IP 分片重组与 TCP 会话重组

1. IP 分片重组(IP Fragmentation & Reassembly) (1)分片原因 当 IP 数据包长度超过 MTU(Maximum Transmission Unit)(如以太网默认 1500 字节)时,路由器或发送端会…...

《Python实战进阶》No34:卷积神经网络(CNN)图像分类实战

第34集:卷积神经网络(CNN)图像分类实战 摘要 卷积神经网络(CNN)是计算机视觉领域的核心技术,特别擅长处理图像分类任务。本集将深入讲解 CNN 的核心组件(卷积层、池化层、全连接层)…...

【Django】教程-1-安装+创建项目+目录结构介绍

欢迎关注我!后续会更新django教程。一周2-3更,欢迎跟进,本周会更新第一个Demo的单独一个模块的增删改查【Django】教程-4-一个增删改查的Demo【Django】教程-2-前端-目录结构介绍【Django】教程-3-数据库相关介绍 1.项目创建 1.1 安装 Djan…...

力扣DAY29 | 热100 | 删除链表的倒数第N个结点

前言 中等 √ 链表心得:考虑好边界情况。 题目 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2,3,4,5], n 2 输出:[1,2,3,5]示例 2: 输入&#…...

渗透测试过-关于学习Token、JWT、Cookie等验证授权方式的总结

关于学习Token、JWT、Cookie等验证授权方式的总结 目录 一、为什么Cookie无法防止CSRF攻击,而Token可以? 二、为什么无论采用Cookie-session的方式,还是Token(JWT)的方式,在一个浏览器里,同一个…...

C#从入门到精通(3)

目录 第九章 窗体 (1)From窗体 (2)MDI窗体 (3)继承窗体 第十章 控件 (1)控件常用操作 (2)Label控件 (3)Button控件 &…...

greenhill编译出现:3201原因错误

ecom800: 21Mar25 16:26:45.609351: No licenses available for ecom800 Reason: ecom800 (3201): The License Manager cannot be contacted. 解决方式:重新加载lincese驱动。 检查是否安装正确: 检查驱动是否正确识别: 以上检查都正常&#xff0c…...

Docker 快速入门指南

Docker 快速入门指南 1. Docker 常用指令 Docker 是一个轻量级的容器化平台&#xff0c;可以帮助开发者快速构建、测试和部署应用程序。以下是一些常用的 Docker 命令。 1.1 镜像管理 # 搜索镜像 docker search <image_name># 拉取镜像 docker pull <image_name>…...

RISC-V AIA学习2---IMSIC

我在学习文档这章时&#xff0c;对技术术语不太理解&#xff0c;所以用比较恰当的比喻来让自己更好的理解。 比较通俗的理解&#xff1a; 将 RISC-V 系统比作一个工厂&#xff1a; hart → 工厂的一条独立生产线IMSIC → 每条生产线配备的「订单接收员」MSI 中断 → 客户通过…...

C#基础学习(五)函数中的ref和out

1. 引言&#xff1a;为什么需要ref和out&#xff1f; ​问题背景&#xff1a;函数参数默认按值传递&#xff0c;值类型在函数内修改不影响外部变量&#xff1b;引用类型重新赋值时外部对象不变。​核心作用&#xff1a;允许函数内部修改外部变量的值&#xff0c;实现“双向传参…...

【每日算法】Day 9-1:贪心算法精讲——区间调度与最优选择(C++实现)

掌握高效决策的核心思想&#xff01;今日深入解析贪心算法的底层逻辑&#xff0c;聚焦区间调度与最优选择两大高频场景&#xff0c;结合大厂真题与严谨证明&#xff0c;彻底掌握“局部最优即全局最优”的算法哲学。 一、贪心算法核心思想 贪心算法&#xff08;Greedy Algorit…...

Netty源码—8.编解码原理二

大纲 1.读数据入口 2.拆包原理 3.ByteToMessageDecoder解码步骤 4.解码器抽象的解码过程总结 5.Netty里常见的开箱即用的解码器 6.writeAndFlush()方法的大体步骤 7.MessageToByteEncoder的编码步骤 8.unsafe.write()写队列 9.unsafe.flush()刷新写队列 10.如何把对象…...

【踩坑系列】使用httpclient调用第三方接口返回javax.net.ssl.SSLHandshakeException异常

1. 踩坑经历 最近做了个需求&#xff0c;需要调用第三方接口获取数据&#xff0c;在联调时一直失败&#xff0c;代码抛出javax.net.ssl.SSLHandshakeException异常&#xff0c; 具体错误信息如下所示&#xff1a; javax.net.ssl.SSLHandshakeException: sun.security.validat…...

双目云台摄像头全方位监控方案

双目云台摄像头是一种具有两个镜头的摄像头设备&#xff0c;通常配备云台功能&#xff0c;能够实现水平和垂直方向的旋转&#xff0c;从而提供全方位的监控视角&#xff1a; 一、工作原理与特点 工作原理 &#xff1a;双目云台摄像头利用仿生学原理&#xff0c;通过两个标定后的…...

测谎仪策略思路

来源:【东吴金工 金工专题】“高频价量相关性拥抱CTA”系列研究&#xff08;四&#xff09;&#xff1a;CPV因子期货版3.0—CPV测谎机 原创 高子剑 量化邻距离 2024年09月20日 14:37 该报告主要介绍了“高频价量相关性拥抱CTA”系列研究中CPV因子期货版的相关内容&#xff0c;…...

2025年移动端开发性能优化实践与趋势分析

启动速度优化 本质&#xff1a;缩短首次可见帧渲染时间。 方法&#xff1a; iOS&#xff1a;利用Core ML本地模型轻量化部署&#xff0c;减少云端等待。Android&#xff1a;强制启用SplashScreen API&#xff0c;通过setKeepOnScreenCondition控制动画时长。冷启动需将耗时操…...

VScode-i18n-ally-Vue

参考这篇文章&#xff0c;做Vue项目的国际化配置&#xff0c;本篇文章主要解释&#xff0c;下载了i18n之后&#xff0c;该如何对Vscode进行配置 https://juejin.cn/post/7271964525998309428 i18n Ally全局配置项 Vscode中安装i18n Ally插件&#xff0c;并设置其配置项&#…...

vue vue3 走马灯Carousel

背景&#xff1a; 在项目中需要展示多张图片&#xff0c;但在页面上只有一张图片的有限位置&#xff0c;此时考虑使用轮播图实现多张图片的展示。element组件官网有走马灯Carousel的组件详细介绍。 实现效果&#xff1a; 官网链接&#xff1a;点击跳转 核心代码&#xff1a; …...

Android设计模式之Builder模式

一、定义&#xff1a;将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 二、核心思想&#xff1a; 分离构造与表示&#xff1a;将对象的构建过程&#xff08;如参数组合、校验逻辑&#xff09;与对象本身分离。 链式调用&#xff1a;通…...

【时时三省】(C语言基础)关系运算符和关系表达式

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 在if语句中对关系表达式disc > 0进行判断。其中的“>”是一个比较符&#xff0c;用来对两个数值进行比较。在C语言中&#xff0c;比较符&#xff08;或称比较运算符&#xff09;称为关…...

运算放大器(二)运算放大器的选型与应用

1.运算放大器的工艺决定Vos和Ib 2.TI放大器的命名规律 3.TI精密放大器家族 4.精密运放的选型指南 5.高共模抑制比放大器 6.TI其他的精密放大器 7.选型时需考虑的问题 8.TI精密运放选型实例 先确定供电电压 9.确定放大器的步骤 参考&#xff1a; 注&#xff1a;本文出自对b…...

vulhub靶场jangow-01-1.0.1

启动靶机时点shift停在这个界面 点e进入编辑页面&#xff0c;把ro改成rw signie init/bin/bash Ctrlx保存&#xff0c;ip a查看网卡信息 vim /etc/network/interfaces 把enp0s17改为ens33&#xff0c;保存退出 重启靶机&#xff0c;nmap扫ip ip为192.168.93.179 nmap扫端口 扫…...

android 一步完成 aab 安装到手机

家人们谁懂&#xff01;在 Android 系统安装 aab 应用超麻烦。满心期待快速体验&#xff0c;却发现 aab 无法直装&#xff0c;得先转为 apks 格式&#xff0c;这过程复杂易错。好不容易转好&#xff0c;还得安装 apks&#xff0c;一番折腾&#xff0c;时间与耐心全耗尽。别愁&a…...

mysqlworkbench导入.sql文件

1、MySQL Workbench 新建数据库 或者 在左侧导航栏的 ​Schemas 区域右键选择 ​Create Schema...输入数据库名称&#xff08;例如 mydatabase&#xff09;&#xff0c;点击 ​Apply确认创建&#xff0c;点击 ​Finish 2、选择目标数据库 在左侧导航栏的 ​Schemas 列表中&a…...

pyqt 信号与槽

PySide6 信号与槽机制详解 引言 PySide6 是 Qt for Python 的官方绑定库&#xff0c;为 Python 提供了强大的 GUI 开发能力。其中&#xff0c;信号与槽&#xff08;Signals and Slots&#xff09; 机制是 Qt 事件处理系统的核心&#xff0c;它允许对象之间进行松耦合的通信&a…...

深入探索C++:从基础到实践

目录 引言 一、C 基础语法与特性 &#xff08;一&#xff09;命名空间&#xff08;Namespace&#xff09; 单独使用 嵌套使用 调用形式 &#xff08;二&#xff09;输入输出流&#xff08;I/O Streams&#xff09; &#xff08;三&#xff09;变量作用域 二、C 的…...

从零开始完成冒泡排序(0基础)——C语言版

文章目录 前言一、冒泡排序的基本思想二、冒泡排序的执行过程&#xff08;一&#xff09;第一轮排序&#xff08;二&#xff09;第二轮排序&#xff08;三&#xff09;第三轮排序&#xff08;四&#xff09;第四轮排序 三、冒泡排序的代码实现&#xff08;C语言&#xff09;&am…...

Echars插入的柱状图条形图,鼠标放在图上显示坐标值

只需要将axiosPointer改为cross axisPointer.type支持类型及作用&#xff1a; line&#xff1a;默认直线型指向线shadow&#xff1a;显示坐标轴方向的阴影区域cross&#xff1a;交叉线&#xff08;横向纵向双线&#xff09;none&#xff1a;不显示指向器inside&#xff1a;结合…...

机械臂如何稳稳上桌?Mujoco场景修改实操

视频讲解&#xff1a; 机械臂如何稳稳上桌&#xff1f;Mujoco场景修改实操 前面《常见机械臂模型不用找&#xff01;Mujoco这儿都有&#xff01;》中介绍的mujoco-menagerie中机械臂大多都是base_link放在地上的&#xff0c;这些场景往往和真实的场景对应不上&#xff0c;比如机…...

金融级密码管理器——抗内存扫描的密钥保险箱

目录 金融级密码管理器 —— 抗内存扫描的密钥保险箱一、模块概述与设计背景二、技术原理与设计目标2.1 关键安全原理2.2 设计目标三、系统架构设计3.1 系统架构图(Mermaid示意图)四、关键技术与安全策略4.1 密钥分割与加密存储4.2 动态内存随机化技术4.3 内存扫描检测与自动…...

如何查看 SQL Server 的兼容性级别

在 SQL Server 中&#xff0c;兼容性级别是一个非常重要的设置&#xff0c;它决定了数据库在特定版本的 SQL Server 中运行时所使用的行为和功能。不同版本的 SQL Server 可能会在 SQL 查询优化、索引、语法、错误处理等方面有差异&#xff0c;因此&#xff0c;设置正确的兼容性…...

AI for CFD入门指南(传承版)

AI for CFD入门指南 前言适用对象核心目标基础准备传承机制 AI for CFDLibtorch的介绍与使用方法PytorchAutogluon MakefileVscodeOpenFOAMParaviewGambit 前言 适用对象 新加入课题组的硕士/博士研究生对AICFD交叉领域感兴趣的本科生实习生需要快速上手组内研究工具的合作研…...

人工智能与网络安全

目录 1、人工智能的安全和安全的人工智能各有什么含义&#xff0c;如何解决 2、当人工智能技术应用于某一安全领域&#xff0c;会对该领域的攻守双方带来哪些机遇与挑战 3、ChatGPT原理 、ChatGPT的缺陷 ChatGPT的缺陷 4、人工智能与算力&#xff0c;风险挑战 应对 5、人…...

GPIO输出实验,控制LED灯

1.实验工具&#xff1a;FSMP1A开发板 核心板&#xff1a; 拓展板&#xff1a; 2.实验要求&#xff1a;编写汇编程序&#xff0c;实现三盏灯流水 程序代码&#xff1a; .text .global _start _start: 将RCC_MP_AHB4ENSET寄存器第4位设置为1&#xff0c;使能GPIO外设时钟 …...

小区团购管理设计与实现(代码+数据库+LW)

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装小区团购管理软件来发挥其高效地信息处理的作用&#xff0…...

How to use pgbench to test performance for PostgreSQL?

pgbench 是一个用于测试 PostgreSQL 数据库性能的基准测试工具。通过模拟多个客户端并发执行 SQL 查询&#xff0c;它可以帮助你评估数据库的性能。以下是使用 pgbench 的基本步骤&#xff1a; 安装 pgbench pgbench 是 PostgreSQL 的一部分&#xff0c;因此在安装 PostgreSQ…...

dbeaver连接mongodb 插入日期变成了字符串

dbeaver插入mongodb数据 日期默认使用ISODate处理&#xff0c;但是插入数据以后实际上是ISODate(2025-03-03T03:25:19.640Z)字符串 INSERT INTO xxx.aaa (_id, chatId, buddyId, pId, lastChatId, inspiration, createTime, modelType, version, selectedInspiration, _class)…...

wgcloud怎么实现服务器或者主机的远程关机、重启操作吗

可以&#xff0c;WGCLOUD的指令下发模块可以实现远程关机和重启 使用指令下发模块&#xff0c;重启主机&#xff0c;远程关机&#xff0c;重启agent程序- WGCLOUD...

PrimeTime生成.lib竟暗藏PG添加Bug

在primeTime里生成lib&#xff0c;如何能带上相关的pg信息&#xff1f; 这是一位群友的发问&#xff0c;就这个问题总结了下可能的原因和解决步骤&#xff1a; 概念 PrimeTime是Synopsys的静态时序分析工具&#xff0c;通常用于在设计的各个阶段进行时序验证。 1&#xff09…...