【发布时间】:2016-10-04 17:57:21
【问题描述】:
我正在编写一个简单的 Linux USB 字符驱动程序,允许从它创建的设备节点读取一个短字符串。
它工作正常,但我注意到使用cat 从设备节点读取和使用Files.readAllBytes 从Java 程序读取之间存在差异。
使用cat读取,在第一次调用file_operations.read函数时传入大小为131072的缓冲区,并复制5字节字符串:
kernel: [46863.186331] usbtherm: Device was opened
kernel: [46863.186407] usbtherm: buffer: 131072, read: 5, offset: 5
kernel: [46863.186444] usbtherm: done, returning 0
kernel: [46863.186481] usbtherm: Device was released
用Files.readAllBytes读取,第一次调用时传入一个大小为1的缓冲区,然后传入一个大小为8191的缓冲区并复制剩余的4个字节:
kernel: [51442.728879] usbtherm: Device was opened
kernel: [51442.729032] usbtherm: buffer: 1, read: 1, offset: 1
kernel: [51442.729102] usbtherm: buffer: 8191, read: 4, offset: 5
kernel: [51442.729140] usbtherm: done, returning 0
kernel: [51442.729158] usbtherm: Device was released
file_operations.read函数(包括调试printk的)是:
static ssize_t device_read(struct file *filp, char *buffer, size_t length,
loff_t *offset)
{
int err = 0;
size_t msg_len = 0;
size_t len_read = 0;
msg_len = strlen(message);
if (*offset >= msg_len)
{
printk(KERN_INFO "usbtherm: done, returning 0\n");
return 0;
}
len_read = msg_len - *offset;
if (len_read > length)
{
len_read = length;
}
err = copy_to_user(buffer, message + *offset, len_read);
if (err)
{
err = -EFAULT;
goto error;
}
*offset += len_read;
printk(KERN_INFO "usbtherm: buffer: %ld, read: %ld, offset: %lld\n",
length, len_read, *offset);
return len_read;
error:
return err;
}
两种情况下读取的字符串是相同的,所以我想没关系,我只是想知道为什么会有不同的行为?
【问题讨论】:
-
你能看到
size()为你的设备节点返回什么吗?