驱动——ioctl数组及结构体传递

news2024/11/24 16:02:48

 1、ioctl函数是用户程序来控制设备的函数

int ioctl(int fd, unsigned long request, ...);

函数功能:设备控制

参数:

@fd:文件描述符

@request:请求码

@...:可变参数 需要传递地址

返回值:成功返回0,失败返回-1,并且置位错误码

2、内核层与ioctl对应的接口函数:

long (*unlocked_ioctl) (struct file *file, unsigned int cmd, unsigned long arg)

3、代码实现:ioctl传递字符数组与结构体

1>对数组和结构体命令码进行封装:

#ifndef __LED_H__
#define __LED_H__

typedef struct{
    int width;
    int high;
}image_t;

#define UACCESS_BUF _IOW('a',1,char[128])
#define UACCESS_STRUCT _IOWR('b',0,image_t)

#endif

 2>在long mydev_ioctl (struct file *file, unsigned int cmd, unsigned long arg)接口函数内,使用copy_from_user接收用户空间拷贝过来的信息,并进行打印,再使用copy_to_user函数将修改后的结构体信息拷贝到用户空间

#include<linux/init.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/uaccess.h>
#include<linux/io.h>
#include"./led.h"
#include<linux/device.h>

#define GNAME "mydev"
int major;
char kbuf[128]={0};
struct class *cls=NULL;
struct device *dev=NULL;

int mydev_open(struct inode *inode, struct file *file)
{
    //printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}
long mydev_ioctl(struct file *file,unsigned int cmd,unsigned long arg)
{
    int ret;
    image_t image;
    switch(cmd)
    {
        case UACCESS_BUF:
        ret = copy_from_user(kbuf,(void*)arg,sizeof(char)*128);
        if(ret)
        {
            printk("copy from user char error\n");
            return -EIO;
        }
        printk("kbuf=%s\n",kbuf);
        break;

        case UACCESS_STRUCT:
        ret = copy_from_user(&image,(void*)arg,sizeof(image_t));
        if(ret)
        {
            printk("copy from user image_t error\n");
            return -EIO;
        }
        printk("image_t.width=%d  image_t.high=%d\n",image.width,image.high);
        image.width+=10;
        image.high+=10;
        ret = copy_to_user((void*)arg,&image,sizeof(image_t));
        if(ret)
        {
            printk("copy to user image_t error\n");
            return -EIO;
        }
        break;
    }
    return 0;
}
int mydev_close(struct inode *inode, struct file *file)
{
    //printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}
struct file_operations fops={
    .open=mydev_open,
    .unlocked_ioctl=mydev_ioctl,
    .release=mydev_close,
};

static int __init mydev_init(void)
{
    major=register_chrdev(0,GNAME,&fops);
    if(major<0)
    {
        printk("register file\n");
        return major;
    }
    printk("major=%d\n",major);
    cls = class_create(THIS_MODULE,GNAME);
    if(IS_ERR(cls))
    {
        return PTR_ERR(cls);
    }
    
    dev = device_create(cls,NULL,MKDEV(major,0),NULL,GNAME);
    if(IS_ERR(dev))
    {
        return PTR_ERR(dev);
    }
    return 0;
}

static void __exit mydev_exit(void)
{
    device_destroy(cls,MKDEV(major,0));
    class_destroy(cls);
    unregister_chrdev(major,GNAME);
}

module_init(mydev_init);
module_exit(mydev_exit);

MODULE_LICENSE("GPL");

 3>编写用户程序,通过ioctl函数传递信息给内核空间,从而达到想要的操作结果,并进行打印

#include <stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<sys/ioctl.h>
#include"led.h"
char buf[128] = "问灵十三年";

int main(int argc, const char *argv[])
{
    int fd = -1;
    int i=0;
    int witch;
    image_t image={20,1024};
    fd = open("/dev/mydev",O_RDWR);
    if(-1 == fd)
    {
        perror("open is error");
        exit(1);
    }
    ioctl(fd,UACCESS_BUF,buf);
    ioctl(fd,UACCESS_STRUCT,&image);
    printf("image_t.width=%d  image_t.high=%d\n",image.width,image.high);
    close(fd);
	
	return 0;
}

 4>通过dmesg查看内核层的打印信息,结果如下所示,应用层传递的数组信息以及结构体信息成功传递到内核层

5>执行应用层程序,终端打印结构体信息+10后的信息

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/14148.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ARXIV2207】LightViT: Towards Light-Weight Convolution-Free Vision Transformers

【ARXIV2207】LightViT: Towards Light-Weight Convolution-Free Vision Transformers 论文地址&#xff1a;https://arxiv.org/abs/2207.05557 代码地址&#xff1a;https://github.com/hunto/LightViT 1、研究动机 作者认为&#xff0c;在ViT中混合 convolution&#xff0c;…

高校部署房产管理系统前要认真做好那些基础工作?

高校部署数图互通房产管理系统的目的是为了在学校产权范围的基础上&#xff0c;确保开发工作的合理性、房产资源调配的科学性&#xff0c;强化房产资源的使用&#xff0c;切实将学校房产作用功能发挥出来。 一、在部署房产管理系统前期基础性工作包括&#xff1a; 1、摸清家底…

【C语言】-程序环境和预处理指令

文章目录前言1、翻译环境2、执行环境前言 1、翻译环境 我们的代码运行出来&#xff0c;变为我们人眼可以看到的结果的这个过程会经过两个过程。 一、程序的翻译环境&#xff1a;在这个环境中&#xff0c;源代码会变成可以执行的机器指令。这个过程就是把我们人能看懂的语言转换…

操作系统4小时速成:内存管理,程序执行过程,扩充内存,连续分配,非连续分配,虚拟内存,页面替换算法

操作系统4小时速成&#xff1a;内存管理&#xff0c;程序执行过程&#xff0c;扩充内存&#xff0c;连续分配&#xff0c;非连续分配&#xff0c;虚拟内存&#xff0c;页面替换算法 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&…

艾美捷C1q天然蛋白的应用和化学性质说明

C1q是构成C1的一个重要成分&#xff0c;由小肠、结肠上皮细胞、血液中单核细胞、腹膜巨噬细胞、上皮细胞、肝脏、脾脏等合成。活化后能启发补体经典激活途径。 C1q蛋白家族由众多含C1q结构域的蛋白组成, 从细菌到高等哺乳动物中都有分布。这类蛋白由一条信号肽、胶原样区(Colla…

Java BIO基本介绍

Java BIO基本介绍Java BIO基本介绍工作原理BIO传统通讯实现总结BIO实现多发和多收结果&#xff1a;Java BIO基本介绍 &#x1f4dc;Java BIO就是传统的java io 编程&#xff0c;其相关的类和接口在java.io&#x1f4dc;Blo(blockingl/O):同步阻塞&#xff0c;服务器实现模式为…

Java本地搭建宝塔部署实战springboot仓库管理系统源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 本期给大家带来一套Java开发的springboot仓库管理系统源码。 技术架构 技术框架&#xff1a;jdk8 jQuery MySQL5.7 mybatisplus layui shiro运行环境&#xff1a;jdk8 IntelliJ IDEA maven3 宝塔面板 本…

云计算HCIA学习笔记-云计算基础概念

第1章 云计算基础概念 1.1 云计算课程安排说明 &#xff08;IA-虚拟化-FC / IP-Linux OpenStack 桌面云/IE-备份容灾迁移&#xff09; 1.2 为什么云计算IA讲虚拟化&#xff1f; 提前告知学员&#xff0c;为什么IA课程要重点讲解虚拟化&#xff1f;云计算基于OpenStack&…

c++多线程(一)线程管理

来源&#xff1a;微信公众号「编程学习基地」 文章目录1.启动线程2.等待线程完成2.1特殊情况下的等待2.2使用RAII等待线程完成2.3后台运行线程2.4量产线程&#xff0c;等待结束2.传递参数3.转移线程所有权4.运行时决定线程数量2.5 识别线程1.启动线程 当把函数对象传入到线程…

G1D15-fraud-APT-汇报-基础模型与LR相关内容总结-KG-cs224w colab1-ctf rce41-44

一、fraud 跑了一个lr模型&#xff0c;从正则&#xff0c;一直看到了极大似然和最大后验估计emmm。一路跑偏&#xff0c;已经0954了。先把实验结果抄一抄 本来想把模型都跑完&#xff0c;没想到看R补充了大量的基本知识&#xff08;L1\L2正则、先验概率 今天先来看fraud 看的…

Hive——详细总结Hive中各大查询语法

✅作者简介&#xff1a;最近接触到大数据方向的程序员&#xff0c;刚入行的小白一枚 &#x1f34a;作者博客主页&#xff1a;皮皮皮皮皮皮皮卡乒的博客 &#x1f34b;当前专栏&#xff1a;Hive学习进阶之旅 &#x1f352;研究方向&#xff1a;大数据方向&#xff0c;数据汇聚&a…

单隐层神经网络在Matlab上实现及其简单应用

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

Kafka 认证三:添加 Kerberos 认证详细流程

背景 上一章节介绍了 Kerberos 服务端和客户端的部署过程&#xff0c;本章节继续介绍 Kafka 添加 Kerberos 认证的部署流程&#xff0c;及 Java API 操作的注意事项。 sasl.kerberos.service.name 配置的含义 Kafka 添加 Kerberos 部署的核心是 Kafka 服务端的 Principal 配…

基于gensim实现word2vec模型(附案例实战)

目录 什么是word2vec&#xff1f; Word2Vec的原理 gensim实现word2vec模型&#xff08;实战&#xff09; 什么是word2vec&#xff1f; Word2Vec是google在2013年推出的一个NLP工具&#xff0c;它的特点是能够将单词转化为向量来表示&#xff0c;这样词与词之间就可以定量的…

20+个很棒的 Python 脚本的集合(迷你项目)

&#x1f482; 个人网站:【海拥】【摸鱼小游戏】【神级源码资源网站】&#x1f91f; 风趣幽默的前端学习课程&#xff1a;&#x1f449;28个案例趣学前端&#x1f485; 想寻找共同学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】&#x1f4ac; 免费且实用的 前…

【软件分析第17讲-学习笔记】程序综合 Program Synthesis

文章目录前言正文程序综合枚举法CEGIS&#xff1a;基于反例的优化约束求解法启发式搜索法统计法基于组件的程序综合 Component-Based Synthesis小结参考文献前言 创作开始时间&#xff1a; 如题&#xff0c;学习一下程序综合 Program Synthesis的相关知识。参考&#xff1a;熊…

AUTOSAR-Fee模块

(73条消息) AUTOSAR-Fee模块_一ye残雪的博客-CSDN博客_fee 配置 0 前言 Fee模块全称Flash EEPROM Emulation Module&#xff0c;属于ECU抽象层 Fee模块本身是脱离硬件的&#xff0c;但是Fee模块可能会引用的Fls模块定制API&#xff0c;所以只能算半抽象 本文中&#xff0c;由于…

数据库高级 III

数据库高级 III 二叉排序树在极端情况下存在的问题 二叉排序树在极端情况下会产生失衡二叉树 失衡二叉树其实是不希望存在的&#xff0c;因为它失去了二叉排序树的查询优势&#xff0c;现在这种失衡二叉树的查询效率和单向链表一样&#xff0c;此时它就是单向链表 数据结构…

14.4、SpringWebFlux-1

14.4、SpringWebFlux-1 14.4.1、前置知识 SpringMVC&#xff0c;SpringBoot&#xff0c;Maven&#xff0c;Java8 新特性 14.4.2、基本介绍 官方文档 Web on Reactive Stack (spring.io) 是 Spring5 添加新的模块&#xff0c;用于 web 开发的&#xff0c;功能 SpringMVC 类…

网络热传App鉴定 |「得物」疑私删用户视频?从技术角度还原事件始末

声明&#xff1a;本文更注重于原理知识的普及&#xff0c;因此文中不会有大量实际代码的展示&#xff0c;如果想从代码层面上了解「应用存储分区」的内容&#xff0c;欢迎阅读我两年前写过的技术文章《Android 10 应用分区存储适配实践》 近日&#xff0c;有网友爆料&#xff0…