【问题标题】:simultanious read/write on the same serial port在同一个串口上同时读/写
【发布时间】:2014-06-05 13:10:12
【问题描述】:

我正在构建一个应用程序,它通过接收传输、修改数据和回显更改的结果来截断串行通信线路。

传输的数据由高波特率的状态语句组成,数据量很大。

我创建了两个线程,一个读取语句并将指向每个新语句的指针推送到队列中,另一个将指针从队列中弹出,操作它们,将它们发送到串行端口并删除指针。

队列操作位于带有 CririticalSection 锁的外部函数中,因此可以正常工作。

为了确保队列不会很快溢出,我需要快速发送消息,而不是等待接收结束。

据我了解,串行端口可以同时接收和传输,但尝试这样做会导致访问限制出错。

另一种解决方案是将系统分成两个不同的端口,但我尽量避免这样做,因为硬件发生了变化,并且需要另一个 USB 和转换器。

我阅读了有关重叠结构的信息,但没有完全理解它们的用途,并且据我所知,它们管理 asinc 操作,而我的问题是并行操作。

对不起,我蹩脚的英语,任何帮助或解释都会有所帮助。

我将这个类用于串行通信,设置重叠以在打开 comport 时启用以允许等待事件超时:

http://www.codeproject.com/Articles/992/Serial-library-for-C

提前致谢。

罗马式。

澄清: 我没有打开端口两次,只在主程序中打开一次并将处理程序传递给两个线程(现在编写它可以最大化这种方法中的问题

更多细节:

错误来自 Cserial 库: “Cserial::read 完全重叠,没有结果。”在发送线程中注释 send back to serial 命令不会引发错误,队列已填满并正确显示–

我在一个没有互联网访问的机密系统上,所以我无法上传样本,用我的平板电脑写。在我得到第一个sentace之后,错误就出现了,它会在队列大小发生变化时立即触发第一个发送命令ss,然后接收线程因为接收失败而退出,所以队列停止填充并且没有任何发送。

可能是因为两者都使用相同的串行处理程序,但是在不锁定一个线程或另一个线程的情况下同时访问同一端口的替代方法是什么

忽略错误996,这是“读取重叠完成但没有结果”的错误ID,并且在检测到它时不退出线程,这使得两者都接收到传输的数据错误(丢失字节)

在最后一行,问了很多问题后:

如果这是两条单独的通信线路,为什么读取操作会被写入操作中断?我可以为同一端口上的每个任务使用两个处理程序吗?

usb 中的 D+/- 是发送/接收还是同时用于发送和接收?

【问题讨论】:

  • 您唯一可能做错的事情就是尝试多次打开端口。不支持,线程需要使用相同的 HANDLE。
  • 有趣的问题。您是通过 USB 转串口转换器还是串口访问串口?

标签: c++ serial-port


【解决方案1】:

":读取重叠完整无结果"

您是否防止读取被操作系统切换执行到写入线程而中断?您需要使用互斥锁或类似方法来防止这种情况发生。

真正的解决方案是切换到异步库,比如bosst::asio。

如果这是两条单独的通信线路,为什么读操作会被写操作中断?

如果您在两个线程中使用同步操作而不将它们相互锁定,则可能会发生这种情况。 (我猜你是如何安排你的软件的细节)

  • 您的应用收到来自端口的读取请求。
  • 您的应用请求操作系统启动读取线程。
  • 操作系统同意,您的读取线程完成读取。 -。您的应用会进行处理。
  • 您的应用要求操作系统启动写入线程。
  • 操作系统同意,您的写入线程开始写入。
  • 第二个读取请求到达端口。这不会中断任何事情,它只是等待。
  • 写入尚未完成,但操作系统确定写入线程有足够的时间。它决定将上下文切换到正在等待的读取线程。
  • 读取线程开始读取
  • 再次,操作系统确定正在运行的线程(读取)在 CPU 上有相当大的裂缝。它将上下文切换回写线程。这会使未完成的读取崩溃。请注意,这发生在您的软件中,而不是硬件或硬件驱动程序中。

这应该让您大致了解发生的问题类型,除非您阻止操作系统在彼此之上运行读取和写入。多线程与互斥锁(或等效)或异步事件驱动设计一起使用更好,这是一个意见问题。

【讨论】:

  • 错误来自 Cserial 库:Cserial::read 重叠完成而没有结果。在发送线程中将写回串行注释不会引发错误,因此它会影响读取和正确操作
  • 我在一个没有互联网接入的分类系统上,所以我无法上传样本,从我的平板电脑上写。在我得到第一个sentace之后出现错误,它触发了第一个send命令,然后接收线程因为receive失败而退出,所以队列停止填充并且没有任何发送。
  • 关键是要处于不断的中断状态,我需要同时读写,就好像它们是两个独立的端口一样。硬件(转换器)允许它。恐怕由于使用互斥锁,读取将不允许写入,一旦写入将中断读取并且字节将丢失。接收器是一个智能黑匣子,需要不断完美的反馈
  • 不知道该说什么来回应您的评论,除了重申您需要转而使用异步库,例如 boost::asio。同步读写的全部意义在于它们不能相互中断。问题出在软件上,而不是硬件上
  • 很难在没有互联网的情况下把它带到这里:(我试着在家里完成这个然后把它拿回来。非常感谢!!
【解决方案2】:

两个线程不能对单个端口/文件描述符进行操作。根据您使用的库,您应该尝试异步执行此操作,或者通过检查在不阻塞线程的情况下可以读取/写入多少字节。 (如果是 Linux 原始文件描述符,您应该查看 poll / select)

【讨论】:

  • 如果我创建两个不相互阻塞的串行端口并使用一个发送另一个接收?
  • 如果有两个不同的物理接口是可以的,但是你不能两次访问同一个物理端口。
  • 最后一行,使用c++可以同时进出同一个端口吗?我不能允许通过发送来拦截接收。所有收到的数据都必须回显。同样,添加另一个 pott 是一个简单的解决方案,我现在尽量避免只是因为我没有另一个转换器并且无法调试接收端。
  • "我没有其他转换器,无法调试接收端" 您可以使用空调制解调器模拟器 - 对于此类工作非常有用。 aggsoft.com/virtual-null-modem/download.htm
猜你喜欢
  • 1970-01-01
  • 2022-08-03
  • 2020-12-17
  • 1970-01-01
  • 2021-07-07
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多