免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5187 | 回复: 6
打印 上一主题 下一主题

tty_insert_flip_string以及read BUG [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-17 10:51 |只看该作者 |倒序浏览
20可用积分
9260的板子,从串口DMA读取80个字节,然后通过tty驱动的tty_insert_flip_string,把数据插入到tty_buffer。
然后在用户层通过read操作读取数据。大多时候能成功读取80个字节。
但是有的时候出现read读出的数据少了2个字节,而且位置固定。假如把80个字节分成前后相等的2段,那么丢失的字节一般是在第15个字节处

read应该是读出tty_buffer这个环形缓冲区,但是怎么丢失的数据呢?
请问这是否是个BUG?什么地方干扰了正常的读入?
int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars,
                                size_t size)
{
        int copied = 0;
        do {
                int space = tty_buffer_request_room(tty, size - copied);
                struct tty_buffer *tb = tty->buf.tail;
                /* If there is no space then tb may be NULL */
                if(unlikely(space == 0))
                        break;
                memcpy(tb->char_buf_ptr + tb->used, chars, space);
                memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
                tb->used += space;
                copied += space;
                chars += space;
                /* There is a small chance that we need to split the data over
                   several buffers. If this is the case we must loop */
        } while (unlikely(size > copied));
        return copied;

最佳答案

查看完整内容

请问一下,将数据插入到tty_buffer之后,tty_buffer的数据是完整的吧?也就是说数据丢失是发生在tty_buffer到应用层这一步吗?

论坛徽章:
0
2 [报告]
发表于 2009-02-17 10:51 |只看该作者

回复 #1 againyuan 的帖子

请问一下,将数据插入到tty_buffer之后,tty_buffer的数据是完整的吧?也就是说数据丢失是发生在tty_buffer到应用层这一步吗?

论坛徽章:
0
3 [报告]
发表于 2009-02-17 13:42 |只看该作者
应该是,因为我跟踪了一下read_chan函数。read_chan是用于向read操作提供数据的。
我打印了一下read_chan的参数nr,还有返回值retval,发现丢失数据的时候是retval=78,nr=2
不丢失数据的时候retval=80,nr=0

论坛徽章:
0
4 [报告]
发表于 2009-02-17 15:19 |只看该作者
等待高手回答!

论坛徽章:
0
5 [报告]
发表于 2009-02-17 16:06 |只看该作者
疑惑
在底层获得数据然后送入tty中,是插入到tty结构中struct tty_bufhead buf;
但是在用户层read是读取tty结构中char *read_buf;
这2个变量有什么关系呢?
tty结构中的read_cnt有时候是80,有时候是78.

论坛徽章:
0
6 [报告]
发表于 2009-02-17 16:21 |只看该作者
数据最终会通过tty-> receive_buf()将数据放入read_buf.
在这段代码中,有几个很有意思的处理。在进入工作队列的时候,首先会置TTY_FLUSHING标志.如果有进程在读read_buf的时候,如果此标志被置位,就会设置TTY_FLUSHPENDING标志,并进行睡眠。在数据处理完成之后,判断是否有TTY_FLUSHPENDING标志。如果有,则将读进程唤醒.并清除TTY_FLUSHPENDING和TTY_FLUSHING
想一想。为什么会这么处理呢?为什么这里需要两个缓存区,一个buf.一个read_buf。为什么要这样麻烦呢?
首先,对于缓存区的数目问题:我们在后面会看到。对接收数据还有一系列的预处理过程,这些过程是比较费时的。不宜在中断中进行费时的操作。所以需要选用软中断机制。这就需要将数据先放置一个buf.再由软中断进行预处理之后,再将它放入到read_buf.这就是两个缓存区的原因.
另外:在存数据到read_buf的时候。会有进程从read_buf中读数据。这样就会造成一个竞争。注意到在软中断情况下是不可睡眠的。我们只能选用自旋锁一类的机制。而这种机制是禁止中断和抢占的。这又违背了软中断机制的初衷。怎么办呢?这就是这样标志的作用了。在设计中,我们必须首先得要保证软中断处理机制的快速完成。所以一进入软中断,就置了一个标志。如果有进程来读数据了,也就是说竞争条件发生了,先将读进程置睡眠。不管怎样,先让软中断处理完之后再说。软中断的工作over这后,再唤醒读进程。
我们之前讲的一系统加锁机制是在两者同样平等的情况。而原子置位与判断置位一般是为了保证一方的工作先完成

论坛徽章:
0
7 [报告]
发表于 2009-02-18 13:25 |只看该作者
找到原因软件流控的问题,通过n_tty_set_termios,设置的n_tty_receive_buf中的tty->real_raw。
tty->real_raw置为1,表示非规范模式
高层加入options.c_iflag &= ~(IXON | IXOFF | IXANY);就可以了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP