Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4247681
  • 博文数量: 1148
  • 博客积分: 25453
  • 博客等级: 上将
  • 技术积分: 11949
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-06 21:14
文章分类

全部博文(1148)

文章存档

2012年(15)

2011年(1078)

2010年(58)

分类: LINUX

2011-12-18 20:27:19

本文的copyright归yuweixian4230@163.com 所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
作者:yuweixian4230@163.com
博客:
yuweixian4230.blog.chinaunix.net  

本节对“从globalmem学习linux字符设备驱动”中,关于file_operations的 read
函数进行学习。

函数的原型为:
  1. ssize_t (*read) (struct file *filp, char __user *buffer, size_t count, loff_t *offp);
  1. ssize_t (*write) (struct file *filp, const char __user *buffer, size_t count , loff_t *offtp);

*filp:文件指针
*buffer:指向用户空间的缓冲区,存放新读入数据的空缓冲区
count:请求传输的数据长度
offp;指向一个“long offset type(长偏移类型)"对象的指针,这个对象指明用户在文件中进行存取操作的位置[0,max_length]。
offp对应struct file中的f_ops参数

将内核空间数据 复制到 用户空间,读出数据到用户空间
read
unsigned long copy_to_user(void __user *to,const void *from,unsigned long count);

将从用户空间user复制数据到内核空间
write
unsigned long copy_from_user(void *to,const void __user *from,unsigned long count)


  1. static ssize_t globalmem_read(struct file *filp,char __user *buf,size_t size,loff_t *ppos)
  2. {
  3.     unsigned long p = *ppos;//p在文件中的位置,范围[0,GLOBALMEM_SIZE-1]
  4.     unsigned int count = size; //读取的 字节数 
  5.     int ret = 0;
  6.     struct globalmem_dev *dev = filp->private_data;
  7.     if(>= GLOBALMEM_SIZE)// 超出 GLOBALMEM_SIZE大小,
  8.         return 0;
  9.     if(count > GLOBALMEM_SIZE - p)//读取的数据 超出范围
  10.         count = GLOBALMEM_SIZE - p;
  11.     if(copy_to_user(buf,(void *)(dev->mem+p),count))
  12.     {
  13.         ret = -EFAULT;//bad address
  14.     }
  15.     else
  16.     {
  17.         *ppos += count;//ppos在文件中的位置,重新设置
  18.         ret = count;
  19.         printk(KERN_INFO"read %u byte(s) form %lu\n",count,p);
  20.     }
  21.     return ret;
  22. }


阅读(4397) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~