gpt4 book ai didi

c++ - 串行端口性能 - VB.NET 与 C++ & Boost

转载 作者:太空狗 更新时间:2023-10-29 20:34:21 27 4
gpt4 key购买 nike

我无法理解为什么我的应用程序需要这么长时间才能通过 Windows 10 上的串行端口与设备通信。我编写了两个小型测试应用程序来尝试查看是什么让它如此缓慢。这是它们的代码:

''VB.NET code    
Imports System.IO.Ports

Module Module1

Sub Main()
Dim port As New SerialPort("COM3", 921600, Parity.None, 8, 1)

port.Open()

port.DtrEnable = True
port.RtsEnable = True

Dim profiler As New Stopwatch

profiler.Start()

For i As Integer = 1 To 100
port.Write("1PA?" & vbCrLf)
port.ReadLine()
port.Write("TB" & vbCrLf)
port.ReadLine()
Next

profiler.Stop()

Console.WriteLine("Average: " & profiler.ElapsedMilliseconds / 100 & "ms")

Console.ReadKey()
End Sub

End Module

和:

//C++ code
#include <iostream>
#include <string>

#include "boost/asio/io_service.hpp"
#include "boost/asio/serial_port.hpp"
#include "boost/asio/read_until.hpp"
#include "boost/asio/write.hpp"
#include "boost/asio/streambuf.hpp"
#include "boost/asio/buffer.hpp"
#include "boost/thread.hpp"
#include "boost/ref.hpp"
#include "boost/lexical_cast.hpp"

using boost::asio::io_service;
using boost::asio::serial_port;
using boost::asio::streambuf;

size_t read_until(serial_port& port, streambuf& buf, const std::string& delim)
{
return boost::asio::read_until(port, buf, delim);
}

void complete(const boost::system::error_code& error, std::size_t bytes_transferred)
{
if (error)
std::cout << "Error\n";
}

int main()
{
std::cout << "Starting...\n";

io_service io;
serial_port port(io, "COM3");
streambuf buf(1000);

boost::posix_time::ptime t0 = boost::posix_time::microsec_clock::local_time();

port.set_option(boost::asio::serial_port_base::stop_bits(boost::asio::serial_port_base::stop_bits::one));
port.set_option(boost::asio::serial_port_base::parity());
port.set_option(boost::asio::serial_port_base::flow_control(boost::asio::serial_port::flow_control::hardware));
port.set_option(boost::asio::serial_port_base::baud_rate(921600));
port.set_option(boost::asio::serial_port_base::character_size(8));


for (int i = 0; i < 100; ++i)
{
boost::asio::write(port, boost::asio::buffer("1PA?\r\n", 6));

read_until(port, buf, "\r\n");
buf.consume(buf.size());

boost::asio::write(port, boost::asio::buffer("TB\r\n", 4));

read_until(port, buf, "\r\n");
buf.consume(buf.size());
}

boost::posix_time::ptime tE = boost::posix_time::microsec_clock::local_time();

std::cout << (tE-t0).total_milliseconds() << '\n';

std::cin.get();
}

问题是 VB.NET 代码报告每次循环迭代平均约 6 毫秒(即每个写/读对 3 毫秒),而 C++ 代码每次迭代花费超过 60 毫秒。

项目的其余部分是用 C++ 编写的,因此我需要改进该代码,不能简单地使用另一个。目前,我发现最快的方法是通过 TCP/IP 与将 TCP/IP 路由到串行端口的 VB.NET 应用程序进行通信。奇怪的是,尽管涉及额外的步骤,这比直接 C++ 实现快两倍多。

我是否遗漏了什么,也许是 C++ 实现中的设置?我已经尝试了所有流量控制选项、不同的缓冲区大小、...

最佳答案

您看到的写入/读取/写入/读取序列的 60 毫秒非常符合计划传输的典型默认值。这是 FTDI(非常流行的 USB 串行端口芯片组)的端口配置

enter image description here

如果串行端口初始化代码没有明确设置超时,您得到的是每 16 毫秒的预定传输。

如果您改为调用 SetCommTimeouts ,您可以安排 USB 设备在串行 RX 线上每次出现间隙时转发接收到的数据缓冲区。为此,设置 ReadIntervalTimeout到几个字节的传输时间。在 921 kbaud 下,每个字节需要 10-11 微秒,因此 ReadIntervalTimeout 的最低可能超时 1 毫秒对应于大约 92 字节的间隔。

但是,由于各种 USB 设备附带的驱动程序的实现质量不同,可能会遇到不具有字符间超时硬件支持的设备。在这种情况下,最好禁用 ReadIntervalTimeoutReadTotalTimeoutMultiplier,而只使用 ReadTotalTimeoutConstant

使用这些超时配置中的任何一个,通过 USB 的数据传输将更及时地发生,您的代码将取得进展。

但是,USB 延迟仍将在每次接收 3 毫秒的数量级(1 毫秒在 RX 线路忙时,1 毫秒空闲以触发超时,另外 1 毫秒等待下一个 USB 时隙)。为了比每 3 毫秒发送 1 条消息更好,您需要通过用一些滑动窗口方案替换停止和等待协议(protocol)来进行管道处理,以便多个消息在传输中。

关于c++ - 串行端口性能 - VB.NET 与 C++ & Boost,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48976397/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com