【发布时间】:2017-11-13 16:21:56
【问题描述】:
我为 Linux 编写了一个简单的字符设备驱动程序。
这是一个简单的消息存储/检索系统,消息存储在内核空间中。
我应该可以这样做:
echo "message 1" > /dev/mydevice
然后用
检索消息cat /dev/mydevice
消息存储在队列中。
当我尝试检索硬编码用于测试的消息(消息是“hello”)时,我得到以下命令行输出:
cat /dev/mydevice
hellocat: /dev/mydevice: Resource temporarily unavailable
所以我按预期收到了 hello 消息,但显然我做的不是很正确。
这是处理设备读取的函数。
static ssize_t device_read(struct file *filp, char *buffer,
size_t length, loff_t * offset) {
unsigned long result;
int message_size;
struct message_list* message = pop_message(&global_message_list);
if (!message) return -EAGAIN;
message_size = message -> message_length;
result = copy_to_user(buffer, message -> message, message_size);
printk(KERN_ALERT "res: %lu, msg_size: %d, len: %d\n", result, message_size, length);
if (result == 0) return message_size;
else return message_size - result;
}
【问题讨论】:
-
我认为
cat一直在尝试读取,直到到达 EOF(read返回 0)。在这种情况下,一旦您没有消息,您会立即转到EAGAIN。尝试在队列中的"hello"之后硬编码一条空消息,看看是否有效? (如果这是实际问题,那可能不是最好的解决方案,但它更容易测试;一方面,很难以这种方式以线程安全的方式将一条消息准确地返回给每个读者。) -
在没有更多消息时返回 EAGAIN 是我的作业要求的一部分。鉴于我需要为 EOF 返回 0,我对如何克服这个问题感到有些困惑。
-
@DanielH 也是,这是否意味着 cat 会多次调用我的读取函数?我认为读取传统上返回读取的字节数。
-
如果将队列硬编码为
"hello",然后是"",那么第一次读取将得到hello,第二次将得到一个长度为0的空字符串,表示EOF,而第三个将获得 EAGAIN。 -
是的,
read返回读取的字节数。但这可能不是整个文件,原因有两个: 1. 很明显,如果传入read的缓冲区小于可供读取的字节数,那么您没有全部内容,需要调用@ 987654334@ 再次获得休息。 2. 您reading 的文件可能是管道、TTY 或其他无法同时提供所有数据的设备;在这种情况下,read将返回任何可用的数据,而下一个将阻塞,直到有更多数据为止。
标签: c linux linux-device-driver chardev