/// <summary> /// 将数据加包,包首增加应用标志,包尾增加奇偶校验 /// </summary> /// <param name="baseMessage"></param> /// <param name="cycle"></param> /// <returns></returns> public byte[] EnPackage(BaseMessage baseMessage, int cycle) { if (baseMessage.Data == null) { LogHelper.GetLogger<FrameProtocol>().Error("通信层待编码数据为空,丢弃。"); return null; } byte[] temp = BaseMessageToBytes(baseMessage); byte[] data = new byte[baseMessage.Data.Length + 10 + 9]; data[0] = AppMarkHead;//frame head byte[] cyclebytes = new byte[4]; cyclebytes = BitConverter.GetBytes(cycle); //cyclebytes.CopyTo(data, 1);//周期号 Array.Copy(cyclebytes, 0, data, 1, 4); data[5] = 1;//分包总数 data[6] = 1;//序列号 Array.Copy(temp, 0, data, 7, temp.Length); //计算奇偶校验和,最后2位不参与奇偶校验 byte oddCheck = data[0]; for (int i = 1; i < data.Length - 2; i++) { oddCheck ^= data[i]; } data[data.Length - 2] = oddCheck;//奇偶校验位 data[data.Length - 1] = AppMarkTail;//frame tail return data; }
public void Append(BaseMessage msg,string board,string testInfo) { try { lock (lockFile) { if (sw != null) { sw.WriteLine("{0},{1},{2}", Util.FormateDateTime3(DateTime.Now), board,testInfo); } } } catch (Exception ee) { LogHelper.GetLogger<ErrorCodeMsgFile>().Error(ee.Message); LogHelper.GetLogger<ErrorCodeMsgFile>().Error(ee.StackTrace); } }
//没有消息的时候,界面会周期性发送0xFF消息 public void AppendLog(BaseMessage msg) { if (TestStatus == TestStatus.THRESHOLD) { if (!IsHeartMsg(msg)) return; //检查握手消息是否收到 CheckShakeHands(msg); } //判断心跳并且生成心跳超时 if (TestStatus == TestStatus.RUNNING) { List<Board> boards = GetTimeoutBoard(runTimeoutDic, runTimeout); foreach (Board b in boards) { HeartTimeoutMsg heartTimeoutMsg = HeartTimeoutMsg.CreateNewMsg(b); if (rxMsgQueue != null) rxMsgQueue.Push(heartTimeoutMsg); //下一次再进行超时判断 runTimeoutDic[b] = DateTime.Now; } //心跳消息、错误码消息都算是心跳,更新收到上次心跳的时间 Board board = GetBoard(msg); if (!board.Name.Contains("未知板卡")) { runTimeoutDic[board] = DateTime.Now; } } if (TestStatus == TestStatus.RUNNING && IsStopTestMsg(msg)) { CheckStop(msg); } //只在测试过程中记录日志,并且不记录心跳数据 if (TestStatus == TestStatus.RUNNING && errorCodeMsgFile != null && !IsHeartMsg(msg)) { Board b = GetBoard(msg); if (BoardErrorStatus(msg))//有错误板卡,触发板卡状态错误事件 { if (b.IsPassed) { b.IsPassed = false; GenBoardStatusChangeEvent(b); } } errorCodeMsgFile.Append(msg, b.Name, GetTestInfo(msg)); } }
//是否是握手消息 private bool IsShakeHandMsg(BaseMessage baseMessage) { return baseMessage is ShakeHandMsg; }
//是否是心跳或者空闲消息或者握手消息 private bool IsHeartMsg(BaseMessage msg) { return (msg is HeartMsg || msg is IdleMsg || msg is ShakeHandMsg || msg is StopTestMsg); }
//是否是停止测试消息 public bool IsStopTestMsg(BaseMessage msg) { return msg is StopTestMsg; }
//获取消息中的字符串 public string GetTestInfo(BaseMessage msg) { string message = ""; if (msg.Data.Length > 5) { int strLength = msg.Data.Length - EqIDLength; byte[] temp = new byte[strLength]; Array.Copy(msg.Data, EqIDLength, temp, 0, strLength); //message = ByteHelper.Byte2String(temp); message = Encoding.Default.GetString(temp); } return message; }
//根据消息的Equip获取板卡 public Board GetBoard(BaseMessage msg) { byte[] temp = new byte[5]; Array.Copy(msg.Data, 0, temp, 0, 5); //byte[] equipID = msg.Data; uint uID = BitConverter.ToUInt32(temp, 0); if (IDBoardDic.ContainsKey(uID)) { return IDBoardDic[uID]; } Board b = new Board(); b = new Board(); b.Name = "未知板卡"; return b; }
//检查是否收到停止消息 public void CheckStop(BaseMessage msg) { byte[] data = msg.Data; uint uData = BitConverter.ToUInt32(data, 0); bool temp = true; if (IDBoardDic.ContainsKey(uData)) IDStopDic[uData] = true; foreach (var kv in IDStopDic) { temp &= kv.Value; } if (temp) { TestStatus = TestStatus.EXPECTED_FINNISH; GenTestStatusChangeEvent(TestStatus.RUNNING, TestStatus); return; } }
//检查是否都收到握手消息 public void CheckShakeHands(BaseMessage msg) { if (IsShakeHandMsg(msg)) { byte[] data = msg.Data; uint uData = BitConverter.ToUInt32(data, 0); bool temp = true; if (IDBoardDic.ContainsKey(uData)) IDStatusDic[uData] = true; foreach (var kv in IDStatusDic) { temp &= kv.Value; } if (temp) { TestStatus = TestStatus.HANDS_OK; GenTestStatusChangeEvent(TestStatus.THRESHOLD, TestStatus.HANDS_OK); return; } }//如果超时了,还有板卡没有收到消息,进入异常结束 else if (DateTime.Now.Ticks - preTestTime.Ticks > (uint)preTimeout * 10000000) { List<Board> boards = new List<Board>(); foreach (var kv in IDStatusDic) { if (kv.Value == false) boards.Add(IDBoardDic[kv.Key]); } //执行异常结束工作 GenTimeoutEvent(boards, TestStatus.THRESHOLD); FinishHandsNotOK(); } }
//根据消息中错误状态获取板卡是否通过,0x01:通过,0x02:失败 public bool BoardErrorStatus(BaseMessage msg) { bool result = true; switch (msg.ErrorStatus) { case 0x01: result = false; break; case 0x02: result = true; break; } return result; }
/// <summary> /// 将应用消息转换为byte[] /// </summary> /// <param name="baseMessage"></param> /// <returns></returns> private byte[] BaseMessageToBytes(BaseMessage baseMessage) { byte[] temp = new byte[baseMessage.Data.Length + 10]; temp[0] = baseMessage.ProtocolVersion; byte[] cycles = new byte[4]; cycles = BitConverter.GetBytes(baseMessage.CycleNo); cycles.CopyTo(temp, 1); temp[5] = baseMessage.Type; temp[6] = baseMessage.SubType; temp[7] = baseMessage.ErrorStatus; BitConverter.GetBytes(baseMessage.DataLen).CopyTo(temp, 8); baseMessage.Data.CopyTo(temp, 10); Array.Copy(baseMessage.Data, 0, temp, 10, baseMessage.Data.Length); return temp; }
private void UpdateGridData(BaseMessage msg) { Board board = testedRacks.GetBoard(msg); string logStr = testedRacks.GetTestInfo(msg); if(board.Name.Contains("STBY")) { int index = this.logList.Rows.Add();//添加一行 this.logList.Rows[index].Cells[0].Value = DateTime.Now.ToString("HH:mm:ss:fff");//第一列是时间 this.logList.Rows[index].Cells[1].Value = board.Name;//第二列是板卡 this.logList.Rows[index].Cells[2].Value = logStr;//第三列是状态 if (testedRacks.BoardErrorStatus(msg)) { this.logList.Rows[index].DefaultCellStyle.ForeColor = System.Drawing.Color.Red; } else { this.logList.Rows[index].DefaultCellStyle.ForeColor = System.Drawing.Color.Green; } } else { if (testedRacks.BoardErrorStatus(msg)) { int index = this.logList.Rows.Add();//添加一行 this.logList.Rows[index].Cells[0].Value = DateTime.Now.ToString("HH:mm:ss:fff");//第一列是时间 this.logList.Rows[index].Cells[1].Value = board.Name;//第二列是板卡 this.logList.Rows[index].Cells[2].Value = logStr;//第三列是状态 this.logList.Rows[index].DefaultCellStyle.ForeColor = System.Drawing.Color.Red; } } }