gpt4 book ai didi

c - 如何在以下简单的设备读取程序中使用 'cat'

转载 作者:太空宇宙 更新时间:2023-11-04 11:59:22 25 4
gpt4 key购买 nike

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

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

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

我需要了解这个基本概念。

最佳答案

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

通常,如果 !=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;
}

当用户发出 ret = read (fd, buffer, sizebuff); 时,它期望这些事情之一并且应该做出相应的 react :

  • ret 等于 sizebuff。这意味着 read 可以返回用户请求的所有数据。这里没有其他事可做。

  • ret 为正,但小于 sizebuff。这意味着读取给了用户一些数据,但没有他要求的那么多。如果需要,用户进程必须重新发出 read 系统调用以检索剩余数据。类似于:ret = read (fd, buffer+ret, sizebuff-ret);

  • ret 为 0。这意味着设备没有更多数据要发送。这是 EOF 条件。用户进程应该关闭设备。

  • ret 是 < 0。这是一个错误条件。用户进程必须检查errno并采取适当的措施。

您的设备驱动程序必须根据读取设备时发生的情况在 device_read 中返回一个适当的值。

另一方面,像 cat 这样的进程期望每次 read 调用读取多达 4096 字节。如果设备发送的少于该值,它将打印接收到的数据并要求更多。 cat 只有在收到信号(例如 Ctrl-C)或 read 调用返回不可恢复的错误(例如ENODEVICE,如果出现这种情况,应该由您的驱动程序生成),或者读取 0 字节(EOF 条件)。


一个向用户进程返回“Hello, world” 的相当愚蠢的设备。它使用一些必须在 device_open 函数中重置的全局数据。请注意,如果多个进程要同时使用您的设备,则必须将这些全局数据转换为实例数据(使用 file->private_data)。这个 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;
}

关于c - 如何在以下简单的设备读取程序中使用 'cat',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53098082/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com