2024/6/16 驱动开发day3

_ioctl传递数组结构体

demo.c

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

#define CNAME "myled"
unsigned int major;

int myled_open(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}

long myled_ioctl(struct file *file, unsigned int cmd, unsigned long args)
{
    char kbuf[128] = {};
    image_t kimage;
    int ret;
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    //判断命令码
    switch(cmd)
    {
        case UACCESS_BUF:
            ret = copy_from_user(kbuf,(void*)args,GET_CMD_SIZE(UACCESS_BUF)); //用户空间数据拷贝到内核空间
            if(ret){
                printk("copy from user is buf error\n");
                return -EIO;
            }
            printk("kbuf = %s\n",kbuf); //打印内核空间中的kbuf内容
        break;
        case UACCESS_STRUCT:
            ret = copy_from_user(&kimage,(void*)args,GET_CMD_SIZE(UACCESS_STRUCT)); //用户空间数据拷贝到内核空间
            if(ret){
                printk("copy from user is struct error\n");
                return -EIO;
            }    
           printk("kernel height = %d width = %d\n",kimage.height,kimage.width); //打印内核空间结构体的值
           kimage.height += 10;
           kimage.width += 10;
           ret = copy_to_user((void*)args,&kimage,GET_CMD_SIZE(UACCESS_STRUCT));//内核空间数据,传递到用户空间
           if(ret){
                printk("copy to user is struct error\n");
                return -EIO;
            }           
        break;
    }
    return 0;
}
int myled_close(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}

//操作方法结构体
const struct file_operations fop = {
    .open = myled_open,
    .unlocked_ioctl = myled_ioctl,
    .release = myled_close,
};

//入口 insmod
static int __init demo_init(void)
{
    //注册字符设备驱动
    major = register_chrdev(0,CNAME,&fop);
    if(major < 0){
        printk("register chrdev is error\n");
        return -EIO;
    }
    printk("major = %d\n",major); //打印主设备号的值
    return 0; 
}

//出口 rmmod
static void __exit demo_exit(void)
{
    //注销字符设备驱动
    unregister_chrdev(major,CNAME);
}

module_init(demo_init);//指定入口函数地址
module_exit(demo_exit);//指定出口函数地址
MODULE_LICENSE("GPL");//许可证

demo.h

#ifndef __DEMO_H__
#define __DEMO_H__

char buf[128] = "";
typedef struct{
    int height;
    int width;
}image_t;

#define UACCESS_BUF _IOW('A',1,char [128]) //传递字符数组命令码
#define UACCESS_STRUCT _IOWR('A',1,image_t) //传递结构体命令码
#define GET_CMD_SIZE(cmd) (cmd >> 16 & 0x3fff) //获取命令码大小

#endif

test.c

#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 "demo.h"

int main(int argc,const char * argv[])
{
    int fd = -1;
    char buf[128] = "hello DC23121";
    image_t uimage;
    uimage.height = 100;
    uimage.width= 20;
    fd = open("/dev/myled",O_RDWR);//打开设备文件
    if(fd == -1){
        perror("open is error");
        exit(1);
    }
    ioctl(fd,UACCESS_BUF,buf);//传递数组
    ioctl(fd,UACCESS_STRUCT,&uimage);//传递结构体
    printf("user height = %d width = %d\n",uimage.height,uimage.width);
    close(fd);//关闭文件描述符
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值