本节对“从globalmem学习linux字符设备驱动”中,关于file_operations的 read
函数进行学习。
函数的原型为:
-
ssize_t (*read) (struct file *filp, char __user *buffer, size_t count, loff_t *offp);
-
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)
-
static ssize_t globalmem_read(struct file *filp,char __user *buf,size_t size,loff_t *ppos)
-
{
-
unsigned long p = *ppos;//p在文件中的位置,范围[0,GLOBALMEM_SIZE-1]
-
unsigned int count = size; //读取的 字节数
-
int ret = 0;
-
struct globalmem_dev *dev = filp->private_data;
-
if(p >= GLOBALMEM_SIZE)// 超出 GLOBALMEM_SIZE大小,
-
return 0;
-
if(count > GLOBALMEM_SIZE - p)//读取的数据 超出范围
-
count = GLOBALMEM_SIZE - p;
-
if(copy_to_user(buf,(void *)(dev->mem+p),count))
-
{
-
ret = -EFAULT;//bad address
-
}
-
else
-
{
-
*ppos += count;//ppos在文件中的位置,重新设置
-
ret = count;
-
printk(KERN_INFO"read %u byte(s) form %lu\n",count,p);
-
}
-
return ret;
-
}
阅读(4478) | 评论(0) | 转发(0) |