Ubuntu下.NET串口接收异常:握手模式适配矛盾问题求助
.NET跨平台串口接收在Ubuntu下的XOnXOff握手适配问题
环境信息
- Ubuntu版本:Ubuntu 22.04.1 LTS
- 串口参数设置:
- 波特率:115200
- 停止位:1
- 奇偶校验:无
- RTS:True
- DTR:True
- 握手模式:XOnXOff / None(依实验调整)
测试结果
- Windows系统:串口收发字节功能完全正常
- Ubuntu系统:发送功能正常,但接收存在异常
Ubuntu接收异常详情
- 接收138字节帧(已在Windows验证发送正常):
- 握手模式设为None时,实际收到140字节,开头和中间各多出1个0x00;
- 切换为XOnXOff握手模式后,可正常接收138字节。
- 接收10字节帧:
- 保持XOnXOff握手模式时,实际仅收到9字节,缺失中间的0x11字节;
- 切换为None握手模式后,可正常接收10字节。
当前困境
Ubuntu系统下,XOnXOff握手仅适配大帧,关闭握手仅适配小帧,无法同时兼容两种帧的正常接收。但Ubuntu原生工具moserial在XOnXOff模式下可正常接收138字节和10字节帧,无缺失或冗余字节问题。
复现代码
public class RS232Service : IDisposable, IRS232Service { public event EventHandler<ReceivedSerialDataEventArgs>? DataReceived; public event EventHandler<FrameEventArgs>? DataSent; private SerialPort _comPort = new(); private readonly List<byte> _receivedDataBuffer = new(); public void Dispose() { _comPort.Dispose(); GC.SuppressFinalize(this); } public void Connect(SerialPort comPort) { _comPort = comPort; if (_comPort.IsOpen) return; _comPort.ReadTimeout = 1000; _comPort.DataReceived += OnComPortDataReceived; _comPort.Open(); } public void Disconnect() { if (_comPort.IsOpen) { _comPort.Close(); } _comPort.DataReceived -= OnComPortDataReceived; } private void OnComPortDataReceived(object sender, SerialDataReceivedEventArgs e) { ReceivedSerialDataEventArgs objReceivedSerialDataEventArgs = new ReceivedSerialDataEventArgs(); int dataLength = _comPort.BytesToRead; byte[] data = new byte[dataLength]; int nbrDataRead = _comPort.Read(data, 0, dataLength); if (nbrDataRead == 0) return; Console.WriteLine("Got data length: " + dataLength); _receivedDataBuffer.AddRange(data); int parsedbytes = 0; if (DataReceived != null) { objReceivedSerialDataEventArgs.ReceivedData = _receivedDataBuffer; DataReceived(this, objReceivedSerialDataEventArgs); parsedbytes = objReceivedSerialDataEventArgs.ReadLength; _receivedDataBuffer.RemoveRange(0, parsedbytes); } Console.WriteLine("removed length: " + parsedbytes); } public bool IsConnected() { return _comPort.IsOpen; } public void SendData(byte[] data, string dataDescription) { _comPort.Write(data, 0, data.Length); DataSent?.Invoke(this, new FrameEventArgs(data, dataDescription)); } }
注:该问题可在任意Ubuntu机器上用C#复现,多款C#串口工具均出现相同结果。
内容的提问来源于stack exchange,提问作者Ahmed Fawzy
相关产品推荐
相关产品推荐

