字符设备应用之私有ioctl的使用

ops/2024/9/20 1:32:00/ 标签: wifi, linux, ioctl

ioctl和netlink是用于用户态程序和内核态模块交互的两种方法,这里主要讲解ioctl的使用方法;
-----再牛逼的梦想,也抵不住傻逼般的坚持! ----20240722 08:26

留一个思考问题,ioctl和netlink的优缺点分别是什么?

使用ioctlioctl的入参有个cmd,cmd的格式如下, 共两个字节,分别包含了type, number

/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */
/* --------|-type-|-number-|-direction-|-size--|--------------------*/
/* --------|-8bit-|--8bit--|----2bit---|-14bit-|--------------------*/#define SIOCGCHIPID 0x9160 /*get wifi chip id*/
#define SIOCGCHIPTEMP 0x9161 

cmd[31:30]—数据(args)的传输方向(读写) cmd[29:16]—数据(args)的大小
cmd[15:8]—>命令的类型,可以理解成命令的密钥,一般为ASCII码(0-255的一个字符,有部分字符已经被占用,每个字符的序号段可能部分被占用)
cmd[7:0] —>命令的序号,是一个8bits的数字(序号,0-255之间)

其实cmd本质是一个命令码,不按照上述的规则定义可以嘛?当然可以,只要上下都是你自己做的,发什么cmd做什么事情你自己清楚就好

接下来是干货,直接上Demo (需要自己根据自己的业务,做下微调)
用户态:

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>#define DEVICE_PATH "/dev/test_s_cdev"/*get wifi module chip id or other info*/
int get_dev_info(int cmd, char *buf) 
{int fd = -1;char info[32] = "";printf("open [%s]\n", DEVICE_PATH);fd = open(DEVICE_PATH, O_RDWR);if (fd < 0) {perror("Failed to open device--");return 1;}int ret = ioctl(fd, cmd, info);if (ret < 0) {printf("IOCTL failed\n");}else{printf("Got string: %s\n", info);memcpy(buf, info, strlen(info));}close(fd);return 0;
}

内核态:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/uaccess.h>#include "ipc_msg.h"#define DEVICE_NAME "test_s_cdev"
static char wifi_chip_id[32] = "";static struct cdev test_s_cdev;
static struct class *test_s_class;
static struct device *test_s_dev;extern struct ssv_hw *g_ssv_hw;
extern struct ssv_rftool_cfg rftool_cfg;extern int ssv_send_priv_msg_rf_cmd_wait_resp(struct ssv_rftool_softc *srfc, struct ssv_rf_tool_param *param);static int device_open(struct inode *inode, struct file *file)
{return 0;
}
static int device_write(struct inode *inode, struct file *file)
{return 0;
}
static int device_read(struct inode *inode, struct file *file)
{return 0;
}
static int device_release(struct inode *inode, struct file *file)
{return 0;
}
long test_s_set_chip_id(char *chip_id)
{if (copy_to_user(wifi_chip_id, chip_id, strlen(chip_id))){printk("[test_s] set chip id fail[%s]\n", chip_id);return -EFAULT;}printk("[test_s]set chip id success[%s]\n", wifi_chip_id);return strlen(wifi_chip_id);
}static void test_s_get_temp()
{struct ssv_rf_tool_param rf_tool_param = {0};rf_tool_param.rf_cmd = (u32)SSV6XXX_RFPHY_CMD_RF_TOOL_TEMPERATURE;rf_tool_param.wait_resp = 1;ssv_send_priv_msg_rf_cmd_wait_resp(g_ssv_hw->srfc, &rf_tool_param);printk("temperature = %d\n", rftool_cfg.temperature);
}static long test_s_private_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{// char *buffer = NULL;printk("[test_s]ssv recv ioctl[%04x]\n", cmd);if (cmd == SIOCGCHIPID) {#if 0buffer = kmalloc(strlen(wifi_chip_id) + 1, GFP_KERNEL);if (!buffer){return -ENOMEM;}strcpy(buffer, wifi_chip_id);#endifif (copy_to_user((void __user *)arg, wifi_chip_id, strlen(wifi_chip_id))) {// kfree(buffer);return -EFAULT;}// kfree(buffer);return 0;}else if (SIOCGCHIPTEMP == cmd){test_s_get_temp();if (copy_to_user((void __user *)arg, &rftool_cfg.temperature, sizeof(s8))) {return -EFAULT;}return 0;}return -EINVAL;
}static struct file_operations test_s_fops = {.owner = THIS_MODULE,.open = device_open,.read = device_read,.write = device_write,.release = device_release,.unlocked_ioctl = test_s_private_ioctl,
};int test_s_char_module_init(void)
{int ret = -1;/*设备节点初始化*/cdev_init(&test_s_cdev, &test_s_fops);/*动态申请主设备号*/ret = alloc_chrdev_region(&test_s_cdev.dev, 0, 1, DEVICE_NAME);if (0 != ret) {printk("[test_s]alloc_chrdev_region fail\n");return ret;}test_s_cdev.owner = THIS_MODULE;ret = cdev_add(&test_s_cdev, test_s_cdev.dev, 1);if (0 != ret) {printk("[test_s]cdev_add fail\n");return ret;}test_s_class = class_create(THIS_MODULE, DEVICE_NAME);if (IS_ERR(test_s_class)) {printk("[test_s]class_create fail\n");return PTR_ERR(test_s_class);}test_s_dev = device_create(test_s_class, NULL, test_s_cdev.dev, NULL, DEVICE_NAME);if (IS_ERR(test_s_dev)) {printk("[test_s]device_create fail\n");return PTR_ERR(test_s_dev);}printk("[test_s]device_create success\n");return 0;
}void test_s_char_module_exit(void)
{device_destroy(test_s_class, test_s_cdev.dev);class_destroy(test_s_class);unregister_chrdev_region(test_s_cdev.dev, 1);
}

http://www.ppmy.cn/ops/97068.html

相关文章

C# 不一样的洗牌算法---Simd指令

洗牌算法&#xff0c;以随机打乱数组中元素的位置 测试数据创建 int[] _data; Random rng new Random(); protected override void CreateData() {_data new int[_size];for (int i 0; i < _data.Length; i){_data[i] i;} } 普通打乱数组元素位置 protected overrid…

oracle中创建视图,将一个表中多条数据整合成一条

要求&#xff1a;根据coil_id和passnum检索出多组数据&#xff0c;根据coil_id和passnum求M2-M16的平均值保留三位小数&#xff0c;并写入到新的视图中 创建视图 FEEDBACK_L1 CREATE VIEW FEEDBACK_L1 AS SELECT COIL_ID, PASSNUM, ROUND(AVG(M2),3) AS avg_M2, ROUND(AVG(M3),…

ESP32智能设备:蓝牙音箱、AI语音助手、环境监测与调节以及智能控制,基于BLE与MQTT技术(代码详解)

本文将介绍如何实现一个功能丰富的ESP32项目&#xff0c;集成蓝牙音箱、AI语音助手、智能设备控制器、环境监测与调节等功能。通过本项目&#xff0c;您将学习到硬件设计、嵌入式编程、蓝牙技术、音频处理、人工智能与语音识别、物联网平台、数据分析及用户界面构建等技术。 一…

建设项目跟踪与展示系统

这是在翻旧文件时翻到的16年写的一个项目 建设项目跟踪与展示系统 建设方案 一、系统建设目的及意义 建设工程项目进度控制的最终目的是确保建设项目按预定的时间完成。能否在预定的时间内交付使用&#xff0c;直接影响到投资效益。为解决施工组织过程中存在问题&#xff0c;…

企业财务自动化:RPA机器人的优势与挑战

随着数字化浪潮的推进&#xff0c;企业财务自动化已成为企业提升效率和降低成本的关键策略。在这一背景下&#xff0c;RPA以其独特的优势&#xff0c;正逐渐成为企业财务自动化的重要工具&#xff0c;然而&#xff0c;RPA在实际应用中也面临着一些挑战。本文金智维将围绕RPA机器…

快速排序的改进(超详细!!!)

改进前的快速排序 代码实现&#xff1a; //快速排序 void quick(int arr[],int start,int end){int i start;int j end;int mid arr[start];int tmp;while(i < j){//从头往后找,比基准小就继续while(arr[i] < mid){i;}//循环结束,i的位置大于等于基准元素//从后往前…

【企业高性能web服务器】

目录 一、Nginx 介绍1、 Nginx 功能介绍2、基础特性3、Nginx 模块介绍 二、Nginx 编译安装1、编写systemd服务 三、平滑升级和回滚1、平滑升级的流程2、升级2、回滚 四、 Nginx 核心配置详解1、实现 nginx 的高并发配置2、Nginx 账户认证功能3、nginx作为下载服务器配置 五、re…

vue3--定时任务cron表达式组件比较

## 背景&#xff1a; 之前使用vue2开发项目时&#xff0c;使用了cron组件&#xff0c;比较了两种组件的使用效果。现在需要把原有的vue2项目升级为vue3&#xff0c;需要对应的cron组件。 方案一&#xff0c;vue3-cron-plus 具体实现&#xff1a; 安装插件 npm install vue3-…

SEO之网站结构优化(十二-绝对路径和相对路径)

初创企业搭建网站的朋友看1号文章&#xff1b;想学习云计算&#xff0c;怎么入门看2号文章谢谢支持&#xff1a; 1、我给不会敲代码又想搭建网站的人建议 2、“新手上云”能够为你开启探索云世界的第一步 博客&#xff1a;阿幸SEO~探索搜索排名之道 绝对路径指的是包含城名的完…

奇异递归Template有啥奇的?

如果一个模版看起来很头痛&#xff0c;那么大概率这种模版是用来炫技&#xff0c;没啥用的&#xff0c;但是CRTP这个模版&#xff0c;虽然看起来头大&#xff0c;但是却经常被端上桌~ 奇异递归模板模式&#xff08;Curiously Recurring Template Pattern, CRTP&#xff09;是一…

数字人的形象克隆与语音克隆是伪需求

形象克隆与语音克隆技术&#xff0c;在当前的环境上已经可以成熟的实现&#xff0c;但真的解决了痛点问题吗&#xff1f; 普通人或者一般的公司克隆自己内部人的形象有必要吗&#xff1f;对外界而言&#xff0c;克隆的形象与虚拟的形象并无二致&#xff0c;本身并没有什么知名…

【区块链+商贸零售】消费券 2.0 应用方案 | FISCO BCOS应用案例

方案基于FISCO BCOS区块链技术与中间件平台WeBASE&#xff0c;实现新一代消费券安全精准高效发放&#xff0c;实现消费激励&#xff0c; 促进消费循环。同时&#xff0c;方案将用户消费数据上链&#xff0c;实现账本记录与管理&#xff0c;同时加密机制保证了数据安全性。

【Axure视频教程】中继器表格——设置文字颜色

今天教大家在Axure制作将控制中继器内部控制文字颜色的原型模板&#xff0c;效果包括&#xff1a; 1、用中继器表格的数据来控制文字的颜色&#xff0c;例如60分以下红色文字&#xff0c;90分以上绿色文字双击分值的格子2 2、可以填写或修改分值&#xff0c;修改后根据新值自…

当SOA遇到DDD

本文讨论软件设计中的决策&#xff0c;特别是关于将较大的系统拆分为多个可独立部署的服务端点。不会特别讨论【服务端点设计】&#xff0c;但我想探讨一下为创建多个服务应用程序进行构思的阶段。 面对复杂问题&#xff0c;通常试图理解复杂性的各部分。将问题拆解为更易于理…

C#使用Modbus TCP通讯PLC,实现读写寄存器

一、创建一个Moudbus类&#xff0c;引入NModbus和Modbus这两个包 #region ModbusTCPpublic class NmodbusTcpHelper{// 静态成员变量&#xff0c;用于存储TcpClient实例private static TcpClient tcpClient null;// 静态成员变量&#xff0c;用于存储ModbusIpMaster实例privat…

一个手机到手机之间通话经过了哪些设备

来源&#xff1a;https://www.bilibili.com/video/BV1ic411F7mM/?spm_id_from333.880.my_history.page.click&vd_source6c5d3cd50fc7fa8732bdfb760a055839 一个手机通话需要经过下面三个网络 类别接入网&#xff08;Access Network&#xff09;承载网&#xff08;Transp…

C语言面试题(持续更新)

1.static/const C语言的关键字 static 修饰 局部变量时 延长了局部变量的生命周期 直到程序结束 作用域取决于定义它的函数 static 修饰 全局变量时 只允许全局变量在定义它的源文件中使用 其他文件不能对其进行调用 static 修饰 函数是 也只允许函数在定义它的源文件中使用…

软件开发者的首选:最佳Bug测试工具Top 10

本篇文章介绍了以下软件bug测试管理工具&#xff1a;PingCode、Worktile、Test360、禅道、码云Gitee、优云测试、Jira、GitHub、Axosoft、Bugzilla。 在开发过程中&#xff0c;Bug的管理往往是最让人头疼的问题之一。小问题积累起来不仅会拖延项目进度&#xff0c;还可能影响到…

【vue】编辑器段落对应材料同步滚动交互

场景需求 编辑器段落对应显示材料编辑器滚动时&#xff0c;材料同步滚动编辑器段落无数据时&#xff0c;材料不显示 实现方法 编辑器与材料组件左右布局获取编辑器高度&#xff0c;材料高度与编辑器高度一致禁用材料组件的滚动事件获取编辑器段落距离顶部的位置&#xff0c;…

三高 vue

高性能是指系统或应用程序在单位时间内能够处理更多的工作量或请求。 高可用性是指系统或服务能够在面对故障或异常情况时保持持续可用和正常运行的能力。 高扩展性是指系统或应用程序能够在面对不断增长的负载时保持性能和吞吐量的能力。 nginx主备keepalived实现nginx服务的高…