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

驱动模块中的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)
1
执行write之后再read变成了hello hello,说明内核值被改变了(只是因为在write中给内核写入了hello hello)
2

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值