1.用户空间-->内核空间(写)
#include<linux/uaccess.h>
int copy_from_user(void *to,const void __user volatile*from,unsigned long n)
函数功能:将用户空间数据拷贝到内核空间
参数:
to:内核空间首地址
from:用户空间首地址
n:拷贝大小
返回值:成功返回0
失败返回拷贝的字节数
2.内核空间-->用户空间(读)
int copy_to_user(void __user volatile *to,const void *from,unsigned long n)
函数功能:将内核空间数据拷贝到用户空间
参数:
to:用户空间首地址
from:内核空间首地址
n:拷贝大小
返回值:成功返回0
失败返回拷贝的字节数
驱动代码:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#define CNAME "myled"
unsigned int major;
char kbuf[128] = {};
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 *loff)
{
int ret;
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
//如果用户空间想要读的数据大小,大于内核空间,更正大小
if(size > sizeof(kbuf))
{
size = sizeof(kbuf);
}
//将内核空间数据,拷贝到用户空间
ret = copy_to_user(ubuf,kbuf,size);
if(ret)
{
printk("copy to user is error\n");
return -EIO;
}
return size;
}
ssize_t myled_write(struct file *file,const char __user *ubuf,size_t size,loff_t *loff)
{
int ret;
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
//如果用户空间想要写的数据大小,大于内核空间,更正大小
if(size > sizeof(kbuf))
{
size = sizeof(kbuf);
}
//将用户空间的数据,拷贝到内核空间
ret = copy_from_user(kbuf,ubuf,size);
if(ret)
{
printk("copy from user is error\n");
return -EIO;
}
printk("kbuf = %s\n",kbuf);//打印用户空间传递到内核空间的数据
return size;
}
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,
.write = myled_write,
.read = myled_read,
.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");//许可证
应用层代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc,const char * argv[])
{
int fd = -1;
char buf[128] = "hello world";
fd = open("/dev/myled",O_RDWR);//打开设备文件
if(fd == -1)
{
perror("open is error");
exit(1);
}
write(fd,buf,sizeof(buf));//写入数据
memset(buf,0,sizeof(buf));//清零
read(fd,buf,sizeof(buf));//读取数据
printf("user buf = %s\n",buf);
close(fd);//关闭文件描述符
return 0;
}