typedef struct{
int width;
int high;
}image_t;
用户空间: width = 10 high = 200
要求:将用户空间数据传递给内核空间,在内核空间进行打印,打印之后需要每个变量+10,在传递给用户空间,在用户空间打印增加后的值
头文件
#ifndef __LED_H__
#define __LED_H__
typedef struct {
int width;
int high;
}image_t;
#define UACCESS_BUF _IOW('a',1,char[128])
#endif
内核文件
#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 CNAME "myled"
int major;
char kbuf[128]={0};
image_t arg;
int myled_open(struct inode *inode, struct file * file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
ssize_t myled_read(struct file *file, char __user * ubuf, size_t size, loff_t *loft)
{
int ret;
ret = copy_to_user(ubuf,&arg,sizeof(arg));
if(ret)
{
printk("copy to user is error\n");
return -EIO;
}
printk("%d\n",arg.high);
printk("%d\n",arg.width);
return size;
}
ssize_t myled_write(struct file *file, const char __user *ubuf, size_t size, loff_t *loft)
{
return size;
}
int myled_close(struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
long myled_ioctrl (struct file * file, unsigned int cmd , unsigned long args)
{
int ret;
//1.判断cmd switch(cmd)
ret = copy_from_user(&arg,(void *)args,sizeof(arg));
if(ret)
{
printk("copy from user is error\n");
return -EIO;
}
printk("%d\n",arg.high);
printk("%d\n",arg.width);
arg.high += 10;
arg.width += 10;
return 0;
}
const struct file_operations fops = {
.open = myled_open,
.read = myled_read,
.write = myled_write,
.release = myled_close,
.unlocked_ioctl = myled_ioctrl,
};
static int __init mycdev_init(void)
{
//1.注册字符设备驱动
major = register_chrdev(0,CNAME,&fops);
if(major < 0)
{
printk("register chrdev ids error\n");
}
printk("major=%d\n",major);
return 0;
}
static void __exit mycdev_exit(void)
{
//1.注销字符设备驱动
unregister_chrdev(major,CNAME);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
用户层文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include "led.h"
#include <sys/ioctl.h>
int main(int argc,const char * argv[])
{
int fd = -1;
fd = open("/dev/myled",O_RDWR);
if(fd == -1)
{
perror("open is error\n");
return -1;
}
image_t arg;
arg.high = 10;
arg.width = 200;
ioctl(fd,UACCESS_BUF,&arg);
memset(&arg,0,sizeof(arg));
/*接收*/
read(fd,&arg,sizeof(arg));
printf("%d\n",arg.high);
printf("%d\n",arg.width);
close(fd);
return 0;
}
结果
ubuntu@ubuntu:09_ioctrl_struct$ sudo ./a.out
20
210
ubuntu@ubuntu:09_ioctrl_struct$ dmesg
[37818.756541] major=241
[37830.948660] /home/ubuntu/HQYJ/DC22101/day2/09_ioctrl_struct/mycdev.c:myled_open:16
[37830.948662] 10
[37830.948662] 200
[37830.948663] 20
[37830.948663] 210
[37830.951134] /home/ubuntu/HQYJ/DC22101/day2/09_ioctrl_struct/mycdev.c:myled_close:39
ubuntu@ubuntu:09_ioctrl_struct$