SerialPort ReadBufferSize cant set properly in Ubuntu
#112.643 aperta il 18 feb 2025
Metriche repository
- Star
- (17.886 star)
- Metriche merge PR
- (Merge medio 12g 11h) (661 PR mergiate in 30 g)
Descrizione
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