Linux下ioctl的应用
文章目录
- 1、ioctl简介
- 2、示例程序编写
- 2.1、应用程序编写
- 2.2、驱动程序编写
- 3、ioctl命令的构成
- 4、测试
1、ioctl简介
ioctl(input/output control)是Linux中的一个系统调用,主要用于设备驱动程序与用户空间应用程序之间进行设备特定的输入/输出操作。它提供了一种通用的机制,允许用户空间的应用程序通过文件描述符与设备进行交互,以执行标准文件操作(如读取、写入、打开和关闭)之外的特殊操作。
2、示例程序编写
本次示例程序包括应用程序和驱动程序。
2.1、应用程序编写
应用程序中,将用户输入的数据通过ioctl()传入到驱动程序,并通过ioctl()读取出来。
/* ioc_test.c */#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>// 定义设备类型和 ioctl 命令
#define IOC_MAGIC 'M'
#define MY_IOCTL_GET_PARAM _IOR(IOC_MAGIC, 0, int)
#define MY_IOCTL_SET_PARAM _IOW(IOC_MAGIC, 1, int)int main()
{int fd;int param;int getparam;/* 1、打开设备节点 */fd = open("/dev/ioc", O_RDWR);if (fd < 0) {perror("open");return -1;}/* 2、获取用户输入 */ fprintf(stdout, "entry the number : ");scanf("%d", ¶m);/* 3、写入参数 */if (ioctl(fd, MY_IOCTL_SET_PARAM, ¶m) < 0) {perror("ioctl");close(fd);return -1;}/* 4、读出参数 */if (ioctl(fd, MY_IOCTL_GET_PARAM, &getparam) < 0) {perror("ioctl");close(fd);return -1;}fprintf(stdout, "getparam = %d\n", getparam);// 关闭文件close(fd);return 0;
}
2.2、驱动程序编写
重点主要有如下两个部分:
1、file_operations中指定ioctl操作函数:
static struct file_operations ioc_drv = {.owner = THIS_MODULE,.open = ioc_drv_open,.read = ioc_drv_read,.write = ioc_drv_write,.release = ioc_drv_close,.unlocked_ioctl = my_device_ioctl,
};
2、填充ioctl函数:
#define IOC_MAGIC 'M'
#define MY_IOCTL_GET_PARAM _IOR(IOC_MAGIC, 0, int)
#define MY_IOCTL_SET_PARAM _IOW(IOC_MAGIC, 1, int)static long my_device_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{static int param = 0;switch (cmd) {/* 设置参数命令 */case MY_IOCTL_SET_PARAM:printk(KERN_INFO "MY_IOCTL_SET_PARAM\n");if (copy_from_user(¶m, (int __user *)arg, sizeof(param))) {return -EFAULT;}printk(KERN_INFO "my_device: set param to %d\n", param);break;/* 读取参数命令 */case MY_IOCTL_GET_PARAM:printk(KERN_INFO "MY_IOCTL_GET_PARAM\n");if (copy_to_user((int __user *)arg, ¶m, sizeof(param))) {return -EFAULT;}printk(KERN_INFO "my_device: get param %d\n", param);break;default:return -EINVAL; }return 0;
}
3、完整的驱动程序如下:
/* ioc_drv.c */#include <linux/module.h>#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>static int major = 0;
static struct class *ioc_class;#define IOC_MAGIC 'M'
#define MY_IOCTL_GET_PARAM _IOR(IOC_MAGIC, 0, int)
#define MY_IOCTL_SET_PARAM _IOW(IOC_MAGIC, 1, int)static long my_device_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{static int param = 0;switch (cmd) {case MY_IOCTL_SET_PARAM:printk(KERN_INFO "MY_IOCTL_SET_PARAM\n");if (copy_from_user(¶m, (int __user *)arg, sizeof(param))) {return -EFAULT;}printk(KERN_INFO "my_device: set param to %d\n", param);break;case MY_IOCTL_GET_PARAM:printk(KERN_INFO "MY_IOCTL_GET_PARAM\n");if (copy_to_user((int __user *)arg, ¶m, sizeof(param))) {return -EFAULT;}printk(KERN_INFO "my_device: get param %d\n", param);break;default:return -EINVAL; }return 0;
}static ssize_t ioc_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}static ssize_t ioc_drv_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}static int ioc_drv_open (struct inode *node, struct file *file)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}static int ioc_drv_close (struct inode *node, struct file *file)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}static struct file_operations ioc_drv = {.owner = THIS_MODULE,.open = ioc_drv_open,.read = ioc_drv_read,.write = ioc_drv_write,.release = ioc_drv_close,.unlocked_ioctl = my_device_ioctl,
};static int __init ioc_init(void)
{int err;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);major = register_chrdev(0, "ioc", &ioc_drv);ioc_class = class_create(THIS_MODULE, "ioc_class");err = PTR_ERR(ioc_class);if (IS_ERR(ioc_class)) {printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major, "ioc");return -1;}device_create(ioc_class, NULL, MKDEV(major, 0), NULL, "ioc"); /* /dev/ioc */return 0;
}static void __exit ioc_exit(void)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);device_destroy(ioc_class, MKDEV(major, 0));class_destroy(ioc_class);unregister_chrdev(major, "ioc");
}module_init(ioc_init);
module_exit(ioc_exit);MODULE_LICENSE("GPL");
3、ioctl命令的构成
一个完整的ioctl命令码通常包含以下几个字段:
- 设备类型(通常是8位):用于标识设备或设备驱动程序的类型。这使得系统能够区分不同的设备或设备组。
- 序列号(也是8位):在同一设备类型下,用于区分不同的ioctl命令。每个命令都有一个唯一的序列号,以确保命令的唯一性。
- 方向位(2位):指示数据传输的方向。这可以是读操作、写操作或读写操作。方向位帮助设备驱动程序了解用户空间程序期望执行的操作类型。
- 数据大小(8~14位):指定用户空间与内核空间之间传输的数据的大小。这确保了数据在传输过程中的完整性和一致性。
在Linux内核中,为了简化ioctl命令的创建过程,提供了一些宏定义。可以看到在上面的应用程序和驱动程序中,都使用了宏来创建ioctl命令:
#define IOC_MAGIC 'M'
#define MY_IOCTL_GET_PARAM _IOR(IOC_MAGIC, 0, int)
#define MY_IOCTL_SET_PARAM _IOW(IOC_MAGIC, 1, int)
可用的宏有如下:
// _IO宏用于创建不带数据传输的ioctl命令
// type是设备类型,通常是一个字符常量,用于区分不同的设备或设备驱动程序
// nr是命令序号,用于在同一设备类型下区分不同的命令
#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)// _IOR宏用于创建从设备读取数据的ioctl命令
// type和nr的含义与_IO宏相同
// size是数据类型大小
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))// _IOW宏用于创建向设备写入数据的ioctl命令
// 其他参数的含义与_IOR宏相同
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))// _IOWR宏用于创建既读取又写入数据的ioctl命令
// 其他参数的含义与_IOR和_IOW宏相同
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
4、测试
1、编译驱动程序,加载驱动程序。
2、编译应用程序,运行应用程序。

相关文章:
Linux下ioctl的应用
文章目录 1、ioctl简介2、示例程序编写2.1、应用程序编写2.2、驱动程序编写 3、ioctl命令的构成4、测试 1、ioctl简介 ioctl(input/output control)是Linux中的一个系统调用,主要用于设备驱动程序与用户空间应用程序之间进行设备特定的输入/…...
如何通过 prometheus-operator 实现服务发现
在之前的章节中,我们讲解了如何编写一个自定义的 Exporter,以便将指标暴露给 Prometheus 进行抓取。现在,我们将进一步扩展这个内容,介绍如何使用 prometheus-operator 在 Kubernetes 集群中自动发现并监控这些暴露的指标。 部署应用 在 Kubernetes 集群中部署我们的自定…...
认识HTML的标签结构
一、HTML的基本概念 1.什么是HTML? ①HTML是描述网页的一种标记语言,也被称为超文本标记语言【并不是一种编程语言】 ②HTML包含了HTML标签和文本内容 ③HTML文档也称为web页面 2.HTML的标签 HTML的标签通常成对出现,HTML文档由标签和受…...
MySQL 之INDEX 索引(Index Index of MySQL)
MySQL 之INDEX 索引 1.4 INDEX 索引 1.4.1 索引介绍 索引:是排序的快速查找的特殊数据结构,定义作为查找条件的字段上,又称为键 key,索引通过存储引擎实现。 优点 大大加快数据的检索速度; 创建唯一性索引,保证数…...
基于flask+vue的租房信息可视化系统
✔️本项目利用 python 网络爬虫抓取某租房网站的租房信息,完成数据清洗和结构化,存储到数据库中,搭建web系统对各个市区的租金、房源信息进行展示,根据各种条件对租金进行预测。 1、数据概览 将爬取到的数据进行展示ÿ…...
开源Web主机控制面板ISPConfig配置DNS
ISPConfig 是一个开源的 Web 主机控制面板,特别适合用于构建虚拟主机环境。 它拥有强大的 DNS 管理功能,可以: 管理 DNS 区域 (主区域、辅助区域)。支持多种记录类型。DNSSEC 支持。远程 DNS 服务器管理。 ISPConfig 优点在于专为主机服务设…...
【Python项目】信息安全领域中语义搜索引擎系统
【Python项目】信息安全领域中语义搜索引擎系统 技术简介:采用Python技术、MYSQL数据库等实现。 系统简介:系统主要是围绕着语义搜索展开的,要将输入的文字在爬取数据时能够通过深层次的内涵理解,来更好的查找到与之相关的精准信息…...
网站搭建基本流程
需求分析: 实现网站搭建的过程:首先进行网站的需求性分析 网站可分为前台系统和后台系统,由不同的功能拆分为不同的模块 如下是一个电商网站可以拆分出的模块: 在编写代码前,我们要先对网站进行架构,通过…...
mysql 存储空间增大解决方案
一:查询数据库中表占比比较多的表 SELECT table_name AS "Tables", round(((data_length index_length) / 1024 / 1024), 2) AS "Size (MB)" FROM information_schema.tables WHERE table_schema "自己的数据库名"; …...
深入解析队列与广度优先搜索(BFS)的算法思想:原理、实现与应用
目录 1. 队列的基本概念 2. 广度优先搜索(BFS)的基本概念 3. 队列在BFS中的作用 4. BFS的实现细节 5. C实现BFS 6. BFS的应用场景 7. 复杂度分析 8. 总结 1. 队列的基本概念 队列(Queue)是一种先进先出(FIFO, …...
Swap to Gather-----
C - 烟销日出不见人 问题陈述 给定一个长度为 NN 的字符串 SS,由 0 和 1 组成。保证 SS 至少包含一个 1。 您可以执行以下操作任意次数(可能为零): 选择一个整数 ii (1≤i≤N−11≤i≤N−1),并交换 SS 的第 ii 个和…...
使用DeepSeek+本地知识库,尝试从0到1搭建高度定制化工作流(自动化篇)
7.5. 配图生成 目的:由于小红书发布文章要求图文格式,因此在生成文案的基础上,我们还需要生成图文搭配文案进行发布。 原实现思路: 起初我打算使用deepseek的文生图模型Janus进行本地部署生成,参考博客:De…...
Python 函数式编程全攻略:从理论到实战的深度解析
本文深入剖析 Python 函数式编程,详细讲解其概念、核心特性(迭代器、生成器等)、内置函数及相关模块(itertools、functools ),结合丰富示例与直观图表,助力读者全面掌握函数式编程技巧ÿ…...
Ollama 在 LangChain 中的使用
文章目录 一、langChain 介绍二、环境安装1.依赖库安装2.下载模型 三、基本使用示例1.使用 ChatPromptTemplate 进行对话2.流式输出3.工具调用4.多模态模型调用 四、进阶使用1.使用 ConversationChain 进行对话2.自定义提示模板3.构建一个简单的 RAG 问答系统 五、遇到问题与解…...
使用apt-rdepends制作软件离线deb安装包
使用apt-rdepends制作软件离线deb安装包 除基础软件外,还要获取软件依赖包。 依赖包工具安装 apt-get install apt-rdependsapt-rdepends工具使用 使用apt-rdepends工具,递归方式分析软件依赖,下载软件包本体,和依赖包。制作时…...
根据POD名称生成 三部曲:get、describe、log、exec
#!/bin/bash# 定义颜色变量 RED\033[0;31m GREEN\033[0;32m YELLOW\033[0;33m NC\033[0m # No Color# 检查是否传入 Pod 名称作为参数 if [ -z "$1" ]; then# 如果没有传参,则提示用户输入 Pod 名称echo -e "${YELLOW}Please enter the Pod name:${…...
SQL sever数据导入导出实验
1.创建数据库TCP-H (1)右键“数据库”,点击“新建数据库”即可 (2)用sql语言创建,此处以创建数据库DB_test为例,代码如下: use master;go--检查在当前服务器系统中的所有数据里面…...
python环境的yolov11.rknn物体检测
1.首先是我手里生成的一个yolo11的.rknn模型: 2.比对一下yolov5的模型: 2.1 yolov5模型的后期处理: outputs rknn.inference(inputs[img2], data_format[nhwc])np.save(./onnx_yolov5_0.npy, outputs[0])np.save(./onnx_yolov5_1.npy, outpu…...
I2C、SPI、UART
I2C:串口通信,同步,半双工,双线(数据线SDA时钟线SCL),最大距离1米到几米 SPI(串行外设接口):串口通信,同步,全双工,四线&…...
如何监控和优化 MySQL 中的慢 SQL
如何监控和优化 MySQL 中的慢 SQL 前言一、什么是慢 SQL?二、如何监控慢 SQL?1. 启用慢查询日志启用方法:日志内容: 2. 使用 mysqldumpslow 分析日志 三、如何分析慢 SQL?1. 使用 EXPLAIN 分析执行计划使用方法&#x…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
