简体   繁体   English

如何在以下简单的设备读取程序中使用“cat”

[英]how to use 'cat' in following simple device read program

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? copy_to_user 是否返回剩余要读取的字节数或读取的字节数?

  2. whats the use of bufcount if i am using cat如果我使用 cat,那么 bufcount 有什么用?

  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. copy_to_user()返回无法复制到用户空间的字节数。 If the complete buffer could be copied, it returns 0.如果可以复制完整的缓冲区,则返回 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.通常,如果 !=0,则表示存在某种内存问题(写入超过合法内存地址),因此应检测这些情况并将其报告给用户。

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);当用户发出ret = read (fd, buffer, sizebuff); it expects one of these things and should react accordingly:它期待这些事情之一,并应作出相应的反应:

  • ret is equal to sizebuff . ret等于sizebuff That means that read could return all the data the user requested.这意味着read可以返回用户请求的所有数据。 Nothing else to do here.这里没有其他可做的。

  • ret is positive, but less than sizebuff . ret是正数,但小于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.如果需要,用户进程必须重新发出read系统调用以检索剩余数据。 Something like: ret = read (fd, buffer+ret, sizebuff-ret);类似于: ret = read (fd, buffer+ret, sizebuff-ret);

  • ret is 0. This means that the device has no more data to send. ret为 0。这意味着设备没有更多数据要发送。 It's the EOF condition.这是EOF条件。 User process should close the device.用户进程应该关闭设备。

  • ret is < 0. This is an error condition. ret < 0。这是一个错误条件。 User process must check errno and take appropiate measures.用户进程必须检查errno并采取适当的措施。

Your device driver will have to return an appropiate value in device_read according to what happened to the device when it was read.您的设备驱动程序必须根据读取设备时发生的情况在 device_read 中返回适当的值。

On the other hand, a process like cat expects to read as much as 4096 bytes per read call.另一方面,像cat这样的进程期望每次read调用读取多达 4096 个字节。 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). cat只会在收到信号(例如Ctrl-C ),或者read调用返回不可恢复的错误(例如ENODEVICE ,如果出现这种情况时应该由您的驱动程序生成),或者读取 0 个字节( EOF条件)。


A rather silly device that returns "Hello, world" to the user process.一个相当愚蠢的设备,它向用户进程返回"Hello, world" It employs some global data that must be reset in device_open function.它使用了一些必须在device_open函数中重置的全局数据。 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 ).请注意,如果多个进程要同时使用您的设备,则必须将这些全局数据转换为实例数据(使用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.这个 device_read 示例显示了如何处理设备缓冲区和用户缓冲区,以及如何跟踪发送给用户的字节,因此设备永远不会发送比它拥有的更多的数据,永远不会发送比用户请求更多的数据,以及当设备数据用完,它返回 0 给用户。

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;
}

1) does copy_to_user returns number of bytes remaining to read or number of bytes read? 1) copy_to_user 返回剩余要读取的字节数还是读取的字节数?

copy_to_user returns a number of bytes that could not be copied. copy_to_user 返回无法复制的字节数。

2) whats the use of bufcount if i am using cat 2) 如果我使用的是 cat,那么 bufcount 的用途是什么

bufCount is a number of bytes user can read. bufCount 是用户可以读取的字节数。 In other words, it's a buffer size of user space application.换句话说,它是用户空间应用程序的缓冲区大小。 I guess cat uses multiple of PAGE_SIZE for buffer size, actually you can check it yourself by adding printk to your device_read() function:我猜 cat 使用 PAGE_SIZE 的倍数作为缓冲区大小,实际上您可以通过将 printk 添加到您的 device_read() 函数来自行检查:

print(KERN_INFO "bufCount=%ld\n", bufCount);

3) if all the data is not read in single call how it can read the remaining data? 3)如果没有在单个调用中读取所有数据,它如何读取剩余数据? Is this responsibility of application to issue system call again or the driver works automatically?应用程序有责任再次发出系统调用还是驱动程序自动工作?

User space programs use read() system call to read data from files (including block and character devices) which returns 0 only if the end of file is reached.用户空间程序使用 read() 系统调用从文件(包括块设备和字符设备)读取数据,只有在到达文件末尾时才返回 0。 That's how they know when to stop.这就是他们知道何时停止的方式。 So, yes, it's responsibility of user-space program to read remaining data (if it needs to).所以,是的,读取剩余数据是用户空间程序的责任(如果需要)。

ssize_t ret;
...
while ((ret = read(fd, buf, bufsize)) > 0) {...};
if (ret < 0)
   error();

On the other hand, the responsibility of device driver is to correctly maintain offsets inside its internal structures and return values that make sense.另一方面,设备驱动程序的职责是在其内部结构中正确维护偏移量并返回有意义的值。

P/S: I'd recommend you to read a book "Linux device drivers" which is freely available in internet ( http://lwn.net/Kernel/LDD3/ ) and touches these topics in details. P/S:我建议您阅读 Internet ( http://lwn.net/Kernel/LDD3/ ) 上免费提供的“Linux 设备驱动程序”一书,并详细介绍了这些主题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM