您的位置:首页 > 其它

驱动学习第一讲附(read,write的实现)

2016-08-19 16:18 274 查看
驱动模块中的read,write(纯知识点的代码编写,非正式驱动代码)

struct cdev hello_cdev;
dev_t hello_devno;  //dev_t  = unsigned int
int hello_major = 250; //Documentation/devices.txt
int hello_minor = 0;

#define KBUFSIZE 50
char kbuf[KBUFSIZE];  //表示内核下的buf数组

int hello_open(struct inode *pinode, struct file *pfile)
{
//简单的打印,表示open函数的成功引用
printk(KERN_INFO "hello open! \n");
return 0;
}

int hello_release(struct inode *pinode, struct file *pfile)
{
//便是模块的成功释放
printk(KERN_INFO "hello release! \n");
return 0;
}

//用户层read调用会访问到此函数
ssize_t  hello_read(struct file *pfile,
char __user *ubuf, size_t count, loff_t *ploff)
{
//如果写入的字节数大于内核中的内存字节数(目前给定的是50)则只取50
if (count > strlen(kbuf))
count = strlen(kbuf);
if (count < 0 )
return -EINVAL;
//将内核数据传递给应用 copy_to_user(to, from, size)
//返回值为0表示成功
if (copy_to_user(ubuf, kbuf, count)) {
printk(KERN_ERR "copy_to_user failed! \n");
return -EFAULT;
}
printk(KERN_INFO "KERNNEL: hello read! \n");
return count;

}

ssize_t  hello_write(struct file *pfile,
const char __user *ubuf, size_t count, loff_t *ploff)
{
if (count > sizeof (kbuf))
count = sizeof (kbuf);
if (count < 0 )
return -EINVAL;
if (copy_from_user(kbuf, ubuf, count)) {
printk(KERN_ERR "copy_to_user failed! \n");
return -EFAULT;
}
printk(KERN_INFO "KERNNEL:  kbuf = %s \n",
kbuf);
return count;

}
//用户调用
struct file_operations hello_ops = {
.owner = THIS_MODULE,
.open = hello_open,
.release = hello_release,
.read = hello_read,
.write = hello_write,
};
int hello_init(void)
{
//初始化字符设备流程
// 1. 组装设备号
// 2. 注册号
// 3. 初始化字符设备
// 4. 注册字符设备
int ret;
hello_devno = MKDEV(hello_major, hello_minor);//hello_major << 20 | hello_minor;
ret = register_chrdev_region(hello_devno, 1, "hello_char"); //cat /proc/devices hello_char

if (ret < 0) {
//诺上面注册号不成立则 动态分配字符设备
ret = alloc_chrdev_region(&hello_devno, 0, 1, "hello_char");
if (ret < 0) {
printk(KERN_ERR "register_chrdev_region failed! \n");
return ret;
}
}
//初始化字符设备对象
cdev_init(&hello_cdev, &hello_ops);
hello_cdev.owner = THIS_MODULE;

//将字符设备对象添加进内核
ret = cdev_add(&hello_cdev, hello_devno, 1);
if (ret < 0) {
unregister_chrdev_region(hello_devno, 1);
printk(KERN_ERR "cdev_add failed! \n");
return ret;
}
//给kbuf赋值
strncpy(kbuf, "kernel_data", sizeof ("kernel_data"));
printk(KERN_INFO "hello init! kbuf = %s  \n", kbuf);
return 0;
}

void hello_exit(void)
{
cdev_del(&hello_cdev);
unregister_chrdev_region(hello_devno, 1);
printk(KERN_INFO "hello exit! \n");
}
module_init(hello_init);   //加载模块后自动调用hello_init
module_exit(hello_exit);  //释放模块


通过内核打印的日志中我们看出内核被加载并打印内核初始值为“kernel_data”(上面代码中复制即kernel _data)



执行write之后再read变成了hello hello,说明内核值被改变了(只是因为在write中给内核写入了hello hello)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: