驱动学习第一讲附(read,write的实现)
2016-08-19 16:18
274 查看
驱动模块中的read,write(纯知识点的代码编写,非正式驱动代码)
通过内核打印的日志中我们看出内核被加载并打印内核初始值为“kernel_data”(上面代码中复制即kernel _data)
执行write之后再read变成了hello hello,说明内核值被改变了(只是因为在write中给内核写入了hello hello)
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)
相关文章推荐
- Android Studio 使用 插件 Butterknife
- C语言基本教程 第9课: 自定义数据结构
- IPPBX-性能测试
- 数组去重的四种方法
- 字符编码
- 除去ScrollVIew拉到尽头时再拉的阴影效果和个别机型的阻尼效果
- linux和qt 字符串和数字转换篇
- VirtualBox: Resize a Fedora, CentOS, or Windows Dynamic Guest Virtual Disk (VDI) in VirtualBox
- 关于phonegap的cookie
- Git--将本地代码提交到服务器分支上
- STL中的排序函数(模板)
- dubbo+zookeeper集群
- android 根据设置的日期获取星期几
- java内部类
- 使用 thinkphp 3.2.3 连接 mongodb 数据库
- dNet命令行编译命令CSC使用详细图解
- leetcode_c++:Integer to English Words(273)
- 计算一棵完全二叉树上节点的数目
- Monkey测试环境搭建
- Win7下安装配置gVim