串口数据接收问题

xiaoyao18301 2010-07-13 10:14:22
大家好 现在我有一个问题 就是用串口接收传感器一个一个发送过来的数据 总计数据量是800,如何保证能完整正确的读取这800个数据呢,我通过设置c_cc[VTIME],c_cc[VMIN]两个控制字符 循环读取800次 可以满足要求 可是 这样效率太低了 不能满足系统要求 改用select机制 读取数据错误,不知道哪位可以指点一下 最好详细些 多谢
...全文
296 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaoyao18301 2010-07-19
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 wqkjj 的回复:]
如果是这种情况,完全怀疑有可能是tty层和硬件之间,是写丢或者写重数据了。LZ可以考虑一下
(1)硬件和tty是否支持缓存满,暂缓数据传送。如果都支持,不妨加入这个考虑。
(2)在硬件和tty之间是否可以保证数据已读走后再写,即一次读的事件中,不会发生两次硬件写的事件;
(3)在上面的假设下,加大tty的缓存,我觉得是很必要的。当然,它不一定是800个字符。
(4)在上面的假设下,单纯想在……
[/Quote]
非常感谢你的回复
我现在也在怀疑是自己的驱动的问题导致的 因为我的硬件上时没有缓冲的 所以在驱动中是一次中断中只能接受一个字符 然后提交给tty层 我曾经尝试修改tty层的缓冲区的大小 可是在重新编译的时候就报错了 好像是不允许修改(这个没有深究 下来可以自己看下) 可是目前 架构师一直认为是我应用机制的错误导致数据的读取错误 我目前使用两种机制 1、一次只读一个数据 读800次 这样读取单个串口数据是没有问题的 可是三个线程同时读取800个数据的时候 就会出现错误 2、将vmin设置大一些 譬如100 然后循环去读 。
还有不好意思 我上次写错了 不是10KB 1KB 而应该是10k 1k 是跟串口的读写速度有关系的(应为串口是FPGA仿真的) 当我们用10k的频率时 读取三路数据是错误的 如果降到1k 三路数据时可以同时接受的 我也就很诧异 到底是哪里的问题了 再次谢谢你的关注
wqkjj 2010-07-18
  • 打赏
  • 举报
回复
如果是这种情况,完全怀疑有可能是tty层和硬件之间,是写丢或者写重数据了。LZ可以考虑一下
(1)硬件和tty是否支持缓存满,暂缓数据传送。如果都支持,不妨加入这个考虑。
(2)在硬件和tty之间是否可以保证数据已读走后再写,即一次读的事件中,不会发生两次硬件写的事件;
(3)在上面的假设下,加大tty的缓存,我觉得是很必要的。当然,它不一定是800个字符。
(4)在上面的假设下,单纯想在应用层通过提高字符的读取频率来解决,可能不现实。这个只能减少缓存满几率,但不能根除。

10KB还是10Kb,难道就是串口的波特率?很久以前我玩的是9.6Kb的,系统只能支持这个速率的串口设备。如果在1KB下工作正常,而10K(不管是B还是b),使用缺省的系统行规程,出现LZ所说的问题,都是难免的。

所以不管怎样,感觉还是需要在tty驱动上作文章。
ForestDB 2010-07-18
  • 打赏
  • 举报
回复
帮顶。
xiaoyao18301 2010-07-18
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 forestdb 的回复:]

帮顶。
[/Quote]
谢谢帮顶 能给些建设性意见吗
xiaoyao18301 2010-07-17
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 wqkjj 的回复:]

还是不太明白LZ的问题是tty驱动方面还是应用层方面。不过我想,既然tty驱动是LZ你们自己写的,完全可以在驱动里面开辟一个800字节的缓存区啊,数据到齐后,再通知应用层读取不就OK了?
10K是什么频率?牵涉到发送到串口的数据发送速率。如果是,则怀疑串口缓存区满了导致写数据失败。印象中缺省tty的缓存仅有16个字节而已。
[/Quote]
你的提议不错 不过 我觉得有几个问题 首先 串口驱动是负责接收串口的数据 而不关心数据量的大小 还有串口是我们通过fpga自己仿真的 10k 1k 是跟串口的读写速率有关系的 现在的情况是 我们在1k的速度下接受三路800个数据是没有问题的 可是如果提升到10k 就出现丢数 或者读不全数据的问题了 我怀疑是驱动能力不足的问题 可是硬件工程师说在硬件上是能够响应的 郁闷中~~~
wqkjj 2010-07-14
  • 打赏
  • 举报
回复
还是不太明白LZ的问题是tty驱动方面还是应用层方面。不过我想,既然tty驱动是LZ你们自己写的,完全可以在驱动里面开辟一个800字节的缓存区啊,数据到齐后,再通知应用层读取不就OK了?
10K是什么频率?牵涉到发送到串口的数据发送速率。如果是,则怀疑串口缓存区满了导致写数据失败。印象中缺省tty的缓存仅有16个字节而已。
wqkjj 2010-07-14
  • 打赏
  • 举报
回复
LZ的前提是要等所有的数据到达,这个前提想提高效率似乎不是LZ的应用可以控制的。
wqkjj 2010-07-14
  • 打赏
  • 举报
回复
整个数据传递过程:传感器-->串口硬件-->串口驱动-->LZ的应用
不确定LZ在使用什么串口驱动,感觉VTIME应该是驱动每次读轮询时间 VMIN:是每次读缓存中最少字符数。
从上面数据传递过程看,效率主要在从传感器到串口驱动之间的速度问题。至于从串口驱动到应用之间,由于串口驱动应该带有数据缓存,因此LZ应用以单个字符去读一次,还是以800个字符,差别不大。有些OS对串口具有缓存限制,比如256字节,这种情况下,只需要保证数据在缓存满之前被读走就可以了(满了没读走会导致缓存等待)。
LZ的前提是要等所有的数据到达,这个似乎不是LZ的应用可以控制的。如果,需要提高系统的灵敏度,即传感器一传输数据,则系统有相应的反映,则上面的两个控制参数是有效的。
如果LZ使用的OS对串口缓存存在限制,则不妨将缓存改大些(遍免缓存满时写等待),则可能提高一些效率。
liujiaji 2010-07-14
  • 打赏
  • 举报
回复
1.do while循环
2.一个字节一个字节的读

xiaoyao18301 2010-07-14
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 icansaymyabc 的回复:]

呵呵,串口设备速率非常的低,和现代CPU速率远远不匹配,你就算用什么再笨的算法来读取都不可能影响你的程序效率的。因为在等待串口设备发送 1 bit 数据的时间里,cpu都可以执行上万条指令了。
你就算找到什么再聪明的读取数据的方法都不可能缩短程序执行时间,你总得等串口把数据传完吧?

如果你不想在等待串口传输的漫长时间里什么事都不能做,你就开一个线程来专门接收数据,这样你的主线程可以做它喜……
[/Quote]

非常感谢
我现在就是在三个线程中读取三路串口的数据 可是现在发现 数据读取是有错误的 怀疑是驱动能力不够 导致数据的读取错误 想请教另外一个问题 如果串口接收一次发过来的500个数据和接受发送500次 每次发送一个数据 之间有区别嘛 我自己感觉是没有区别的
xiaoyao18301 2010-07-14
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 higto 的回复:]

整一个校验位,要么删除了,要么做错误标记
[/Quote]
是这样的 800个数据一定要完整的无误的接收 如果有一个数据出错 那么这800个数据也就没有价值了 所以必须保证正确地 完整地接受到800个数据
higto 2010-07-14
  • 打赏
  • 举报
回复
整一个校验位,要么删除了,要么做错误标记
xiaoyao18301 2010-07-14
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 wqkjj 的回复:]

整个数据传递过程:传感器-->串口硬件-->串口驱动-->LZ的应用
不确定LZ在使用什么串口驱动,感觉VTIME应该是驱动每次读轮询时间 VMIN:是每次读缓存中最少字符数。
从上面数据传递过程看,效率主要在从传感器到串口驱动之间的速度问题。至于从串口驱动到应用之间,由于串口驱动应该带有数据缓存,因此LZ应用以单个字符去读一次,还是以800个字符,差别不大。有些OS对串口具有缓存限制,比如……
[/Quote]
你说的太好了 我现在用的串口驱动是我在linux 下自己写的驱动模块 因为原有的只能支持三个 我们在硬件上自己做了6个串口 串口驱动也是我们自己来写的 硬件上是不带缓冲的 所以硬件上接收到一个字符 我就在中断中 将第一个字符提交到tty层 由于传感器那边是一个一个数据传输过来 如果我用select机制的话 出现的结果时 数据都是0 读取数据错误 现在还没有搞清到底是驱动的问题 还是硬件不满足 总之当频率从10k降到1k后 应用层 驱动层不变的情况下 数据可以正确接收 可是需要的时间太长
xiaoyao18301 2010-07-14
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 liujiaji 的回复:]

1.do while循环
2.一个字节一个字节的读
[/Quote]
呵呵 聪明 我现在就是这么做的 可是这样相当耗时间 而且 现在看来 我linux这边的驱动不能满足硬件传感器的速度
xiaoyao18301 2010-07-13
  • 打赏
  • 举报
回复
如何保证阻塞读取完整的800个数据啊 用什么机制呢 谢谢了啊
icansaymyabc 2010-07-13
  • 打赏
  • 举报
回复
呵呵,串口设备速率非常的低,和现代CPU速率远远不匹配,你就算用什么再笨的算法来读取都不可能影响你的程序效率的。因为在等待串口设备发送 1 bit 数据的时间里,cpu都可以执行上万条指令了。
你就算找到什么再聪明的读取数据的方法都不可能缩短程序执行时间,你总得等串口把数据传完吧?

如果你不想在等待串口传输的漫长时间里什么事都不能做,你就开一个线程来专门接收数据,这样你的主线程可以做它喜欢做的事,子线程收完数据之后通知主线程提取数据就行了。

70,020

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧