字符设备之read和write

原创 2013年12月02日 22:24:07

1.内核空间的read()和write():   

    read和write最大的意义是完成用户空间到内核空间的数据交互.其原型如下:

ssize_t read(struct file *filp,char __user *buff,size_t count,loff_t *offp);
ssize_t write(struct file *filp,const char __user *buff,size_t count,loff_t *offp);
    各参数的意义如下:

filp:文件指针,由open()产生;
buff:用户空间的指针;
count:请求传输的数量长度,以字节为单位;
offp:用户在文件中进行存取操作的偏移量.因此,我们可以通过指定这个参数并配合count参数读取某文件或buf的指定数据段;
   

    1-1.read()的返回值:

返回值为count则说明数据全部传输完成;
返回值为正(标志为len)但是比count小,表明实际传输了(count - len)字节,这时候需要重新读取数据;
返回值为0,则表示到了文件尾;
返回值为负表示出错.

    1-2.write()的返回值:

返回值为count,则说明完成了所请求的数目的字节数据长度;
返回值为正(标志为len)并小于count,则只传输了(count - len)个字节,这时候需要重新传输数据;
返回值为0,意味着什么也没写入;
返回值为负表示出错.

2.copy_to_user()和copy_from_user():

    read()和write()只是对应于用户空间的系统调用,并不产生实质的数据交互.并且这里注意一点,上述的指针参数buff对内核空间而言极有可能是无效的,不作任何处理地引用这个参数指针,有可能引发oops.因此,当用户空间和内核空间产生数据交互的时候,还需要借用内核提供的API来实现:copy_to_user()和copy_from_user().其原型如下:

unsigned long copy_to_user(void __user *to,const void *from,unsigned long count);
unsigned long copy_from_user(void *to,const void __user *from,unsigned long count);
    两个函数的第一个参数均为目标地址;第二个参数均为源地址;第三个参数为数据长度.

    这两个函数若无错误产生,则返回0.

    使用这两个内核API时,需要注意以下两点:

1).可能会引起睡眠;
2).返回值是还需要拷贝的内存数据长度.

    2-1.__copy_to_user()和__copy_from_user():

    在用户指针对内核的合法性有保障的情况下,可以使用__copy_to_user()和__copy_from_user()两个函数来取代上述的copy_to_user()和copy_from_user()两个函数.


3.readv()和writev():

    区别于read()和write()函数,这两个函数可以实现数据的批量传输而达到更高的效率.其原型如下:

ssize_t (*readv)(struct file *filp,const struct iovec *iov,unsigned long count,loff_t *ppos);
ssize_t (*writev)(struct file *filp,const struct iovec *iov,unsigned long count,loff_t *opps);
    这里的比较明著的参数是iov.其原型如下:

struct iovec
{
    void __user *iov_base;
    __kernel_size_t iov_len;
}
    iovec描述了一个数据块,此数据块的起始位置在iov_base,长度为iov_len.其中参数count表示要操作多少个这样的iovec.

   

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Linux 字符设备驱动开发基础(三)—— read()、write() 相关函数解析

我们在前面讲到了file_operations,其是一个函数指针的集合,用于存放我们定义的用于操作设备的函数的指针,如果我们不定义,它默认保留为NULL。其中有最重要的几个函数,分别是open()、r...

Linux字符设备驱动程序(二)---------实现open,read,write,llseek函数

1.open函数 我们从inode中获取scull_dev指针,并将其赋给filp->private_data,这样在其它文件函数中便可以知道当前正在操作的设备文件。 如果是只写方式打开文件,我们...

LDD3中scull字符设备源代码完全解析(二) open、read、write方法

在上一篇的最后我们提到了scull设备的内存结构,今天主要介绍源程序中的几个重要方法,会用到那张内存区图。   首先是open方法,其原型是int (*open)(struct inode *inod...

linux驱动开发之字符设备--内核和用户空间数据的交换(read write)

前边给出了字符设备的框架,内核和用户空间进行交流的时候,离不来数据的交换;内核实现read、wriet 、ioctl是常用的交互手段。

linux设备驱动归纳总结(三):2open.close.read.write

linux设备驱动归纳总结(三):2.字符型设备的操作open、close、read、write 一、文件操作结构体file_operations 继续上次没讲完的...

字符设备驱动

  • 2012-07-21 16:07
  • 14KB
  • 下载

linux文件设备与I/O:read/write函数与阻塞 Block

一,read 函数从打开的设备或文件中读取数据 #include        ssize_t read(int fd, void *buf, size_t count);     ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)