【发布时间】:2013-03-25 20:15:40
【问题描述】:
我正在尝试编写一个非常简单的 echo Linux 驱动程序。
驱动程序从命令行获取最多 250 个字符,并将其写入虚拟设备“mydev”。这再次从设备读回。前端和驱动代码贴在下面供参考。
问题是我能写但不能读。编译或分段错误没有错误。但是没有打印驱动程序读取的 printk 中的任何消息。我对正在发生的事情感到困惑。我可以在这里找到一些线索吗?
为了更清楚,我只是分享代码副本:
mydriver.c :
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
MODULE_LICENSE("GPL");
static int major;
static char kbuf[250];
static int dv_open(struct inode *inode, struct file *filp)
{
return 0;
}
static int dv_close(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t dv_read(struct file *filp, char __user *buf,
size_t sz, loff_t *fpos)
{
int r;
int L;
printk("READ:Entering\n");
L = strlen(kbuf);
r = copy_to_user(buf, kbuf, L);
printk("READ:Ends\n");
return L;
}
static ssize_t dv_write(struct file *filp, const char __user *buf,
size_t sz, loff_t *fpos)
{
int r, wr_sz;
printk("WRITE:Entering\n");
memset(kbuf,'\0', 250);
if ( sz <= 250 ) {
wr_sz = sz;
} else {
wr_sz = 250;
}
r = copy_from_user(kbuf, buf, wr_sz);
printk("WRITE:Rx buf = %s\n", kbuf);
return 0;
}
static struct file_operations dv_fops = {
.open = dv_open,
.release = dv_close,
.read = dv_read,
.write = dv_write,
.owner = THIS_MODULE,
};
int init_module(void)
{
major = register_chrdev(0, "dvdev", &dv_fops);
if ( major < 0 ) {
printk("Error in registering driver\n");
return -1;
}
else printk("Success. major = %d\n", major);
return 0;
}
void cleanup_module(void)
{
unregister_chrdev(major, "dvdev");
}
myuserapp.c
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
static char buf[250];
static char * wbuf;
int main(int argc, char **argv)
{
int fd;
int option;
int nbr = 0, len;
if ( argc != 2 ) {
printf("usage: front <devName>\n");
return -1;
}
fd = open("mydev", O_RDONLY | O_WRONLY);
if ( fd < 0 ) {
printf("Error opening file. %s does not exist\n", argv[1]);
return -2;
}
wbuf = argv[1];
len = strlen(wbuf);
nbr = write(fd, wbuf, len);
printf("USR: Buf written = %s, nbr = %d\n", wbuf ,nbr);
nbr = read(fd, buf, 250);
printf("USR RD: %s", buf);
close(fd);
return 0;
}
【问题讨论】:
-
您为什么以只读和只写方式打开文件?你的意思是读/写吗? (O_RDWR)
-
好吧,我被困在 Windows 计算机上,或者我会尝试一下,但可能就是这样。 RDWR == 2,但 (RD | WR) == (0 | 1) == 1 == 错误。所以我猜用“O_RDONLY | O_WRONLY”打开一个文件只打开它。
-
我猜 O_RDONLY 和 O_WRONLY 是单独的位,所以它会像 O_RDONLY | O_WRONLY = 10|01 = 11 。 Read 和 write 的位都设置了...
-
您是否创建了设备节点?您确实在内核日志中看到了
major设备ID 打印?顺便说一句,如果您有像open和close这样的存根,您可以在file_operations中将它们保留为NULL。如果您还没有制作设备节点,那么我可以看到您的症状。mknod mydev c <major> 0其中来自您的内核日志。你为什么用'C'标记这个?我不认为这是必要的。另见chapter 3 of ldd -
好吧,我意识到我对位的困惑。我将检查这一点,并将结果发布在所有信息上。感谢大家宝贵的时间
标签: c linux linux-kernel driver