Chinaunix

标题: 继续请教 [打印本页]

作者: yyykkk1229    时间: 2008-08-18 12:00
标题: 继续请教
unsigned char kbuf[1024]="hello world!\n";


static ssize_t read_test(struct file *file,char *outbuf,size_t count,loff_t *f_pos)
{
        //int left;

        printk(KERN_ALERT "read1\n");

        int bytes_read=0;
        
        if(verify_area(VERIFY_WRITE,outbuf,count)==-EFAULT)
        return -EFAULT;
                Message_Ptr=kbuf;
                while(count && *Message_Ptr)
                {
                        if(put_user(*(Message_Ptr),outbuf))
                                        return -EINVAL;
                                Message_Ptr++;
                                outbuf++;
                                count--;
                                bytes_read++;
                }
                return bytes_read;
}
老师在我的测试程序中加了一段程序
        memset(outbuf, 0x32, sizeof(outbuf));
        n = read(testdev,outbuf,4096);
        printf("read len=%d\n", n);
        printf("read: %s\n",outbuf);
说这是在初始读取的outbuf的数值
输出为read len=12
read: hello world!
222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222....
我定义的outbuf是4096个字节,输出的字符串应该是4096个字节
      memset(outbuf, 0, sizeof(outbuf));
        n = read(testdev,outbuf,4096);
        printf("read len=%d\n", n);
        printf("%s\n",outbuf);
我这样输入的就是正常的hello world!
这是什么原因啊~
作者: dreamice    时间: 2008-08-18 12:20
标题: 回复 #1 yyykkk1229 的帖子
我给你注解一下吧:
老师在我的测试程序中加了一段程序
        memset(outbuf, 0x32, sizeof(outbuf)); /*  把outbuf初始化为字符‘2’ */
        n = read(testdev,outbuf,4096); /* 这里读出来的是hello world, 但是4096的outbuf其余部分全部为字符‘2’填充, 所以下面的结果不言而喻 */
        printf("read len=%d\n", n);
        printf("read: %s\n",outbuf); /* 问题出在这里,一个基本概念:%s输出是什么格式?答曰:字符串;字符串以什么结尾? 答曰:‘\0’or 0   你这样输出为什么会有问题? --输出的格式是字符串,而outbuf确实是字符串么?*/
说这是在初始读取的outbuf的数值
输出为read len=12
read: hello world!
222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222....
我定义的outbuf是4096个字节,输出的字符串应该是4096个字节
      memset(outbuf, 0, sizeof(outbuf));
        n = read(testdev,outbuf,4096);
        printf("read len=%d\n", n);
        printf("%s\n",outbuf); /* 这里为什么能对,看上面的注解吧 */
我这样输入的就是正常的hello world!
这是什么原因啊~

[ 本帖最后由 dreamice 于 2008-8-18 12:21 编辑 ]
作者: yyykkk1229    时间: 2008-08-18 12:36
我明白了,那请问该怎么修改read那个函数在'\0'的时候就返回,不输入后面加载的字符
作者: dreamice    时间: 2008-08-18 12:39
标题: 回复 #3 yyykkk1229 的帖子
老师在我的测试程序中加了一段程序
     memset(outbuf, 0x32, sizeof(outbuf));
        n = read(testdev,outbuf,4096);
        outbuf[n] = '\0';
        printf("read len=%d\n", n);
        printf("read: %s\n",outbuf);


遇到问题自己多思考一下吧。这是个很基础的问题。
作者: dreamice    时间: 2008-08-18 12:42
标题: 回复 #4 dreamice 的帖子
这个地方,对是否读取错误也没有做检查。写程序思维要严谨一些。
作者: yyykkk1229    时间: 2008-08-18 12:52
谢谢楼上的,我的意思是如何修改read这个函数,在read里面进行返回'\0',这应该算是一个优化问题吧,在测试程序中进行修改,在原程序中还是需要读取4000多了字符,只是在测试中屏蔽掉了,,系统依然运行了...
作者: dreamice    时间: 2008-08-18 13:28
标题: 回复 #6 yyykkk1229 的帖子
你仔细分析一下这个程序的执行,或者你可以看一下read函数的manual 手册,read在什么时候返回?阻塞与非阻塞是怎么实现的?自己分析搞明白这些理解就深刻了。我建议你再仔细研读一下LDD,同时,要搞驱动程序,没有一定的应用程序功底,也是不行的。
作者: yyykkk1229    时间: 2008-08-18 13:29
我感觉应该在read里面,用count计算字符串的长度,当出现'\0'时跳出while循环,但是不知道该如何写这个过程
作者: yyykkk1229    时间: 2008-08-18 13:30
标题: 回复 #7 dreamice 的帖子
OK...谢谢...
作者: dreamice    时间: 2008-08-18 13:38
原帖由 yyykkk1229 于 2008-8-18 12:52 发表
谢谢楼上的,我的意思是如何修改read这个函数,在read里面进行返回'\0',这应该算是一个优化问题吧,在测试程序中进行修改,在原程序中还是需要读取4000多了字符,只是在测试中屏蔽掉了,,系统依然运行了...


写驱动程序,首先要弄明白机制与策略这两个概念及思想。可以说,你这样的想法先不说他正确与否,这是一个策略问题,不应该是驱动程序应该去关心的,这样就犯了一个写驱动程序的错误;另外,你请求读4096字节,难道read真的会返回这么多数据?要知道outbuf是你用户空间的东东,而读取的数据是内核空间的,先看看系统调用read的实现吧,看read manual的帮助。
作者: yyykkk1229    时间: 2008-08-19 10:38
问题解决了,我发现自己只是一味的追求功能的实现,很多原理性的问题理解的并不透彻,谢谢楼上的指导
作者: dreamice    时间: 2008-08-19 10:50
标题: 回复 #11 yyykkk1229 的帖子
把基本问题搞明白,我也是从你这样的心态过来的。基础知识,原理性的东西,一定要弄扎实,一些经典的书要认真的看看。
作者: yyykkk1229    时间: 2008-08-19 10:59
标题: 回复 #12 dreamice 的帖子
推荐一些书籍看看吧,谢谢,我知道有一本是<LINUX设备驱动>,我看的第三版的,但我用的还是2.4的内核,还有很多地方不理解...
作者: dreamice    时间: 2008-08-19 11:09
标题: 回复 #13 yyykkk1229 的帖子
应用程序:《UNIX环境高级编程》
驱动:《LINUX设备驱动》第二版是2.4的,第三版是讲2.6的
内核:《深入理解linux内核》、《LINUX内核情景分析》
作者: MagicBSD    时间: 2008-11-07 10:56
用户态的开发还是应该熟悉一下,不然驱动开发的学习曲线你就不能接受
作者: eveson    时间: 2008-11-07 12:57
这版主真称职啊。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2