/// 串口 /// /// /// FRAME:
// ADDRESS: FLIGHT_CONTROL 0XC8 // LENGTH: CONTAIN TYPE,PALOAD,CRC // TYPE: LINK STATE 0X14 // CHANNEL 0X16 // CRC: CRC8_DVB_S2 1BYTE using System; using System.Collections.Concurrent; using System.Linq; using System.Threading; namespace LoraGamepad.Util; public class SerialPipeIn: IAsyncPipe { private const int TpyeAndCrcLength = 2; private const int HeaderAndLenLength = 2; private const int FrameCrcLength = 1; protected override void Process(ConcurrentQueue queue) { if (!queue.TryPeek(out var first)) { SpinWait.SpinUntil(() => false, 1); // 队列无数据 return; } if (0xC8 != first) { // 未匹配到包头,扔掉继续 queue.TryDequeue(out _); return; } if (queue.Count < 10) { // 数据长度过低 return; } var packLength = queue.ElementAt(1); if (queue.Count < packLength + HeaderAndLenLength) { return; } var pack = queue.Take(packLength + HeaderAndLenLength).ToArray(); var crc = pack[packLength + HeaderAndLenLength - FrameCrcLength]; if (crc != CrcUtil.CRC8_Calculate(pack.Skip(HeaderAndLenLength).SkipLast(FrameCrcLength).ToArray())) { // crc校验失败,砍头 queue.TryDequeue(out _); return; } // 队列消除整包数据 for (var i = 0; i < packLength + HeaderAndLenLength; i++) { queue.TryDequeue(out _); } // 输出数据,砍头砍尾 // Console.WriteLine(BitConverter.ToString(pack)); OnOut(pack.Skip(HeaderAndLenLength).SkipLast(FrameCrcLength).ToArray()); } }