从串行COM端口接收消息时,在我的输出上显示了一个大字符串00-00

本文关键字:显示 00-00 字符串 一个 输出 我的 COM 消息 | 更新日期: 2023-09-27 18:06:52

我有一个Atmel Atxmega128A1微控制器,它通过串行COM端口向PC (c#)应用程序发送消息。偶尔我开始接收一个看起来像这样的大字符串(PcIocBus是一个类):

"PcIocBus:无效消息RX:00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00"

在我的Visual Studio调试输出。

每次0出现,我们都会得到一个异常

System类型的第一次机会异常。ArgumentException发生在dll附加信息:偏移量和长度已超出数组或计数的边界大于元素的数量从索引到源集合的末尾

显示在"Port.Read…"行。

private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
     byte[] rxBuff = new byte[255];
     int bufferSize = Port.BytesToRead;
     try
     {
          Debug.WriteLine("Buffer Size: " + bufferSize);
          Port.Read(rxBuff, 0, Port.BytesToRead);
          foreach (byte newByte in rxBuff)
          {
               InBytes.Enqueue(newByte);
          }
     }
     catch (Exception)
     {
          Debug.WriteLine("PcIocBus: Invalid message RX: " + BitConverter.ToString(rxBuff)):
     }
}

有人知道为什么这会给我错误吗?我尝试将rxBuff数组设置为与缓冲区相同的大小,因为缓冲区(出于某种原因)有时会超过255,但我仍然得到0和异常。

从串行COM端口接收消息时,在我的输出上显示了一个大字符串00-00

   byte[] rxBuff = new byte[255];

255是一个完全随机的数字,与现实无关。这是C代码。BytesToRead当然可以大于255,您已经找到了爆炸!你可以从中得到。它也可以是0,你没有在你的代码中检查e.t eventtype。

   Port.Read(rxBuff, 0, Port.BytesToRead);

串口。BytesToRead不是一个稳定的数字,它在代码运行时增加,因为设备驱动程序继续从串行端口接收数据。这将使您的代码在修复第一个错误时崩溃,您将尝试将更多的字节读取到rxBuff,然后可能适合。您实际上有一个稳定的数字bufferSize,但是您没有使用它。在你修复了第一个bug后,使用rxBuff.Length是正确的方法。

   InBytes.Enqueue(newByte);

这是一种非常非常讨厌的细菌,很难诊断。Queue类是不是线程安全的。DataReceived运行在一个工作线程上,您编写的调用Dequeue()方法的代码运行在另一个线程上。当它们同时运行时会发生非常糟糕的事情,这将会发生。你的必须使用lock关键字来保证InBytes对象访问线程的安全。

   Debug.WriteLine("PcIocBus: Invalid message RX: " + BitConverter.ToString(rxBuff)):

你的异常处理程序严重损坏。它没有显示异常消息,没有显示实际接收到的内容(您忽略了Read()的返回值),它没有提供数据丢失是可恢复事故的希望。不会的。永远不要编写使程序以无法诊断的方式发生故障的try/catch代码。并且隐藏了编程错误。取消try/catch吧,它只会带来痛苦。为AppDomain.CurrentDomain.UnhandledException编写一个事件处理程序。

知道如何编写正确的SerialPort代码的程序员就像活着到达俄勒冈州的先驱一样。他们避开了背后的箭。