簡體   English   中英

串口性能 - VB.NET與C ++和Boost

[英]Serial port performance - VB.NET vs C++ & Boost

我無法理解為什么我的應用程序需要很長時間才能通過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代碼每循環迭代平均報告約6ms(即每個寫/讀對3ms),而C ++代碼每次迭代占用超過60ms。

項目的其余部分是用C ++編寫的,所以我需要改進代碼,不能簡單地使用另一個代碼。 目前,我發現最快的方法是通過TCP / IP與將TCP / IP路由到串行端口的VB.NET應用程序進行通信。 奇怪的是,盡管涉及額外的步驟,這仍然是直接C ++實現的兩倍多。

有什么我想念的,也許是C ++實現中的一個設置? 我已經嘗試過所有流量控制選項,不同的緩沖區大小,......

您在寫入/讀取/寫入/讀取序列中看到的60 ms與預定傳輸的典型默認值非常相似。 這是FTDI的端口配置(非常流行的USB串口芯片組)

在此輸入圖像描述

如果串行端口初始化代碼沒有明確設置超時,那么你得到的是每16ms的預定傳輸。

如果您改為調用SetCommTimeouts ,則可以安排USB設備每次在串行RX線上有間隙時轉發接收的數據緩沖區。 為此,將ReadIntervalTimeout設置為傳輸時間僅幾個字節。 在921 kbaud,每個字節需要10-11微秒,因此ReadIntervalTimeout的最小可能超時1毫秒對應於大約92字節的間隙。

但是,由於各種USB設備附帶的驅動程序的實現質量不同,因此可能會遇到沒有硬件支持來進行字符間超時的設備。 在這種情況下,最好禁用ReadIntervalTimeoutReadTotalTimeoutMultiplier ,並使用ReadTotalTimeoutConstant

使用這些超時配置中的任何一種,USB上的數據傳輸將更加及時,您的代碼將取得進展。

但是,USB延遲仍將是每次接收3毫秒的數量級(當RX線路忙時為1毫秒,1毫秒空閑以觸發超時,另外1毫秒等待下一個USB時隙)。 為了比每3毫秒更好的消息,你需要通過一些滑動窗口方案替換stop-and-wait協議來管道,以便多個消息在飛行中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM