如何使用'猫'在下面的简单设备读取程序 [英] how to use 'cat' in following simple device read program

查看:197
本文介绍了如何使用'猫'在下面的简单设备读取程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 静态ssize_t供device_read(结构文件*的filp,字符* bufStoreData,为size_t bufCount,参数loff_t * curOffset)
{
    printk的(KERN_INFO从设备读);
    RET = copy_to_user(bufStoreData,virtual_device.data,bufCount);
    返回RET;
}


  1. 确实copy_to_user返回剩下来读取或读取的字节数?字节数


  2. 有什么用bufcount的,如果我使用cat


  3. 如果所有的数据都没有一次调用它如何能读取剩余数据读取?是应用程序再次发出系统调用这个责任或驱动程序自动工作?


我需要了解这一基本理念。


解决方案

copy_to_user()返回无法被复制到用户空间的字节数。如果整个缓冲区可能被复制,则返回0。

通常,如果!= 0,这意味着有某种存储器问题(书面方式过去合法存储器地址),因此,这些情况下应检测,并报告给用户。

 静态ssize_t供device_read(结构文件*的filp,字符* bufStoreData,
                            为size_t bufCount,参数loff_t * curOffset)
{
  为size_t bytes_to_copy;  printk的(KERN_INFO从设备读);  / *做的东西来获得设备数据到virtual_device.data。也
     更新virtual_device.datasize * /  bytes_to_copy =(virtual_device.datasize< = bufCount)?
                             virtual_device.datasize:bufCount;
  我不是用bufCount / *注意,但在一个假设的领域
     virtual_device,让我的设备有多少数据已经就绪
     为用户。我选择两者的低* /
  / *还记得,如果由用户请求的字节数是
     小于该设备已产生的字节数,则
     下一个读应该返回设备数据的其余部分,所以
     驾驶员应携带多少字节被复制的次数
     给用户和多少被留下。这不包括在本
     例。 * /  RET = copy_to_user(bufStoreData,virtual_device.data,bytes_to_copy);
  如果(RET!= 0)
    返回-EPERM; / *如果拷贝没有成功,举报* /
  返回bytes_to_copy;
}

当用户发出 RET =读(FD,缓冲,sizebuff); ,预计这些东西,应该作出相应的反应:


  • RET 等于 sizebuff 。这意味着,可以返回所有的用户请求的数据。闲来无事在这里做。


  • RET 是正的,但小于 sizebuff 。这意味着,在读给用户的某些数据,但不作为他要求一样多。用户进程必须重新发出系统调用来检索剩余数据,如果需要的话。喜欢的东西: RET =读(FD,缓冲区+ RET,sizebuff-RET);


  • RET 0。这意味着,设备没有更多的数据发送。这是 EOF 状态。用户过程中应关闭设备。


  • RET 为< 0。这是一个错误的条件。用户进程必须检查错误号,并采取措施appropiate


您的设备驱动程序将根据发生了什么事,当它被读取设备device_read返回一个适当的值。

在另一方面,像的过程预计将阅读每高达4096字节读电话。如果该设备比少发,将打印接收到的数据,并会要求更多。如果收到的信号(按Ctrl-C )后,或者如果<$ C $ 只会停止C>读调用返回不可恢复的错误(如 ENODEVICE ,应由如果这样的情况出现你的驱动程序生成),或者如果读数为0字节( EOF 状态)。


你好,世界返回给用户进程一个很傻的设备。它采用必须在 device_open 功能复位的一些全局数据。请注意,如果几个进程会在同一时间使用你的设备,这些全球性的数据必须被转化为实例数据(使用文件&GT;的private_data )。这device_read例子展示了如何处理设备的缓冲区和用户缓冲区,以及如何跟踪发送给用户的字节,所以设备永远不会发送更多的数据比它,从来没有超过用户请求发送更多的数据,当设备运行的数据,则返回0给用户。

  INT curindx = 0; / *应该是在调用device_open复位* /静态ssize_t供device_read(结构文件*的filp,字符* bufStoreData,
                            为size_t bufCount,参数loff_t * curOffset)
{
  为size_t bytes_to_copy;
  CHAR device_data [] =!您好,世界\\ n;
  为size_t remaindersize;  remaindersize = strlen的(device_data) - curindx;
  bytes_to_copy =(remaindersize&LT; = bufCount)?
                             remaindersize:bufCount;
  RET = copy_to_user(bufStoreData,device_data + curindx,bytes_to_copy);
  如果(RET!= 0)
    返回-EPERM; / *如果拷贝没有成功,举报* /
  curindx + = bytes_to_copy;
  返回bytes_to_copy;
}

static ssize_t device_read (struct file* filp, char *bufStoreData, size_t bufCount, loff_t* curOffset)
{
    printk(KERN_INFO"reading from the device");
    ret = copy_to_user(bufStoreData,virtual_device.data,bufCount);
    return ret;
}

  1. does copy_to_user returns number of bytes remaining to read or number of bytes read?

  2. whats the use of bufcount if i am using cat

  3. if all the data is not read in single call how it can read the remaining data?Is this responsibility of application to issue system call again or the driver works automatically?

I need to understand this basic concept.

解决方案

copy_to_user() returns the number of bytes that couldn't be copied to user space. If the complete buffer could be copied, it returns 0.

Normally, if !=0, means that there was some sort of memory problem (writting past a legal memory address), so these situations should be detected and reported to the user.

static ssize_t device_read (struct file* filp, char *bufStoreData, 
                            size_t bufCount, loff_t* curOffset)
{
  size_t bytes_to_copy;

  printk(KERN_INFO"reading from the device");

  /* do stuff to get device data into virtual_device.data . Also
     update virtual_device.datasize */

  bytes_to_copy = (virtual_device.datasize <= bufCount)? 
                             virtual_device.datasize : bufCount;
  /* note that I'm not using bufCount, but an hypothetical field in 
     virtual_device that gives me how much data the device has ready 
     for the user. I choose the lower of both */
  /* Also recall that if the number of bytes requested by the user is
     less than the number of bytes the device has generated, then the
     next read should return the remainder of the device data, so the
     driver should carry the count of how many bytes have been copied
     to the user and how many are left. This is not covered in this
     example. */

  ret = copy_to_user(bufStoreData,virtual_device.data, bytes_to_copy);
  if (ret != 0)
    return -EPERM; /* if copy was not successful, report it */
  return bytes_to_copy;
}

When the user issues ret = read (fd, buffer, sizebuff); it expects one of these things and should react accordingly:

  • ret is equal to sizebuff. That means that read could return all the data the user requested. Nothing else to do here.

  • ret is positive, but less than sizebuff. That means that the read gave the user some data, but not as much as he requested. The user process must re-issue the read syscall to retrieve the remaining data, if needed. Something like: ret = read (fd, buffer+ret, sizebuff-ret);

  • ret is 0. This means that the device has no more data to send. It's the EOF condition. User process should close the device.

  • ret is < 0. This is an error condition. User process must check errno and take appropiate measures.

Your device driver will have to return an appropiate value in device_read according to what happened to the device when it was read.

On the other hand, a process like cat expects to read as much as 4096 bytes per read call. If the device sends less than that, it will print the received data and will ask for more. cat will only stop if it receives a signal (Ctrl-C for example), or if a read call returns an unrecoverable error (such as ENODEVICE, which should be generated by your driver if such condition arises), or if reads 0 bytes (EOF condition).


A rather silly device that returns "Hello, world" to the user process. It employs some global data that must be reset in device_open function. Note that if several processes are going to use your device at the same time, these global data must be turned into instance data (using file->private_data). This device_read example shows how to deal with device buffers and user buffers, and how to keep track of bytes sent to the user, so the device never sends more data than it has, never sends more data than the user requests, and when the device runs out of data, it returns 0 to the user.

int curindx = 0; /* should be reset upon calling device_open */

static ssize_t device_read (struct file* filp, char *bufStoreData, 
                            size_t bufCount, loff_t* curOffset)
{
  size_t bytes_to_copy;
  char device_data[]="Hello, world!\n";
  size_t remaindersize;

  remaindersize = strlen(device_data) - curindx;
  bytes_to_copy = (remaindersize <= bufCount)? 
                             remaindersize : bufCount;
  ret = copy_to_user(bufStoreData,device_data+curindx, bytes_to_copy);
  if (ret != 0)
    return -EPERM; /* if copy was not successful, report it */
  curindx += bytes_to_copy;
  return bytes_to_copy;
}

这篇关于如何使用'猫'在下面的简单设备读取程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆