dotnet/runtime

SerialPort ReadBufferSize cant set properly in Ubuntu

Open

#112 643 ouverte le 18 févr. 2025

Voir sur GitHub
 (1 commentaire) (0 réactions) (0 assignés)C# (5 445 forks)batch import
area-System.IO.Portshelp wanted

Métriques du dépôt

Stars
 (17 886 stars)
Métriques de merge PR
 (Merge moyen 12j 11h) (661 PRs mergées en 30 j)

Description

Describe the bug

Hello I am coding a program to control a device like "camera". It works like a call device how long to expose to light,and I wait for the time to check what came back.My code is using System.IO.Ports to do this job and wait for enough time the code properly works on Windows.

However,in Ubuntu even i set a long enough time the buffer (which I read) size never goes well. Whatever serialPort.ReadBufferSize I set still get a maxmimn 4095 length buffer.

And I check Ubuntu system settings about /dev/ttyACM0 has 1Mb cache. So I wondering if this is probrom is about the dotnet runtime.

To Reproduce

My code as follow: Main

using SerialPort serialPort = new(SelectedDevice, 115200, Parity.None, 8, StopBits.One);
serialPort.WriteBufferSize = 8192;
serialPort.ReadBufferSize = 8192;
serialPort.Open();
byte[] buffer = Sender.AcquireSpectra(ExposureTime, AverageTimes);
 int delay = (int)(ExposureTime * AverageTimes * 2);
var response = await SendNReadData(serialPort, buffer, delay, 4106);
if (response.Length == 4106)
 {
        var sp = Receiver.ReadSpectrum(response, 0);
        int[] ins = sp.m_nIntensity;
         SpectraPlotModel = SpectraPlot.OnUpdatedGraph(ins);
}

Serial

private static async Task<byte[]> SendNReadData(SerialPort serialPort, byte[] sendBuffer, int delay, int responseBufferLength)
        {
            serialPort.Write(sendBuffer, 0, sendBuffer.Length);
            int timeout = delay * 5;
            using var cancellationTokenSource = new CancellationTokenSource();
            cancellationTokenSource.CancelAfter(timeout);
            await Task.Delay(delay); //必须保留 在windows下会出现4k分包问题
            byte[] responseBuffer = new byte[responseBufferLength];
            var readTask = serialPort.BaseStream.ReadAsync(responseBuffer, 0, responseBuffer.Length, cancellationTokenSource.Token);
            var completedTask = await Task.WhenAny(readTask, Task.Delay(delay, cancellationTokenSource.Token));
            if (completedTask == readTask)
            {
                int bytesRead = await readTask;
                byte[] dataBuffer = new byte[bytesRead];
                Array.Copy(responseBuffer, dataBuffer, bytesRead);
                return dataBuffer;
            }
            else
            {
                return new byte[4];
            }
        }

Further technical details

SDK Version: 9.0.103 System.IO.Ports.dll 8.0.0.0

Guide contributeur