LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1001|回复: 3

一个简单字符设备驱动的问题

[复制链接]
发表于 2007-10-15 21:07:34 | 显示全部楼层 |阅读模式
最近写了一个简单的字符设备驱动, 发现一个很奇怪的问题。
其中的write方法如下:
//全局数据变量
char kbuf[1024];
static int kcount;

ssize_t testdev_write(struct file* file, char* buf, size_t count, loff_t* ppos)
{
        ssize_t retval = 0;

        printk(KERN_NOTICE"test_write is called1, *ppos = %d, kcount = %d\n", *ppos, kcount); /*kcount输出有问题*/

        if (*ppos >= 1024)
        {
                printk(KERN_ALERT"*ppos exceed the length of buf.\n");
                retval = -EFAULT;
                goto error;
        }
       
        if (*ppos + count >= 1024)
        {
                printk(KERN_ALERT"count changed from %d to %d.\n", count, 1024 - *ppos - 1);
                count = 1024 - 1 - *ppos;
        }

        if (copy_from_user(kbuf + kcount, buf, count))
        {
                retval = -EFAULT;
                goto error;
        }

        printk(KERN_NOTICE"string, kbuf: %s\n", kbuf);

        printk(KERN_NOTICE"string,kcount = %d,  kbuf+kcount: %s\n", kcount, kbuf+kcount); /*kcount输出正确*/

        *ppos += count;
        kcount = *ppos;

        printk("kcount = %d\n", kcount);
       
        return count;

error:
        return retval;
}


用户空间的程序代码片段如下:
int fd = open("/dev/testdev/1", O_RDWR);
char* pbuf = "Hello World!\n";
char buf[20];
int num;

extern int errno;

num = write(fd, pbuf, strlen(pbuf));
printf("num = %d\n", num);
if (num != 13)
{
        printf("failed to write pbuf1, errno = %d\n", errno);
        return -1;
}

num = write(fd, "mike\n", 5);
if (num != 5)
{
        printf("failed to write pbuf2, errno = %d\n", errno);
        return -1;
}

在用户空间的程序中,连续调用了两次write,两次write都执行成功了。但驱动中的testdev_write执行有点奇怪。第一次调用testdev_write时很正常,第二次调用testdev_write时,下面这句代码输出的有问题:
printk(KERN_NOTICE"test_write is called1, *ppos = %d, kcount = %d\n", *ppos, kcount);
其中*ppos输出为13,正确,但kcount输出还是为0,就不正确了,kcount应该也是13才对。

但是随后这句代码输出又是正确的:
printk(KERN_NOTICE"string,kcount = %d,  kbuf+kcount: %s\n", kcount, kbuf+kcount);
这次kcount输出的就是13了,两次输出之间,我并没有修改kcount的值,为什么第一次输出不正确,而第二次输出就正确呢?而且内存也能正确从用户空间拷贝到内核空间。
发表于 2007-10-16 06:17:22 | 显示全部楼层
之前在某个论坛上也有人有类似的帖子,当时看了一下 ,问题是由于printk 造成的。
你打印kcount 是用的%d, 而它是unsigned int  型,用%u 打印应该就不会出现类似的问题。

你编译时应该有warning吧,用%u warning 就没有了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-10-16 09:11:14 | 显示全部楼层
刚试了一下, 与%d, %u没有关系。
static unsigned int kcount;
static int kcount;两种定义方法也试过了。
回复 支持 反对

使用道具 举报

发表于 2007-10-16 12:19:27 | 显示全部楼层
if (*ppos + count >= 1024)
{
printk(KERN_ALERT"count changed from %d to %d.\n", count, 1024 - *ppos - 1);
count = 1024 - 1 - *ppos;
}

我是新手,请见谅。
我发现你还是有修改的。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表