初始化上传
This commit is contained in:
251
常用工具集/Utility/SerialDebug/CSendParam.cs
Normal file
251
常用工具集/Utility/SerialDebug/CSendParam.cs
Normal file
@@ -0,0 +1,251 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SerialDebug
|
||||
{
|
||||
public class CSendParam
|
||||
{
|
||||
private SendParamFormat _Format;
|
||||
private SendParamMode _Mode;
|
||||
private int _DelayTime;
|
||||
private readonly string _Data;
|
||||
private readonly byte[] _DataBytes = null;
|
||||
|
||||
public CSendParam(SendParamFormat format, SendParamMode mode, int delayTime, byte[] data, int startIndex, int count)
|
||||
{
|
||||
_Format = format;
|
||||
_Mode = mode;
|
||||
_DelayTime = delayTime;
|
||||
_Data = string.Empty;
|
||||
if (data != null)
|
||||
{
|
||||
_DataBytes = new byte[count];
|
||||
Array.Copy(data, startIndex, _DataBytes, 0, count);
|
||||
|
||||
if (Format == SendParamFormat.Hex)
|
||||
{
|
||||
_Data = BitConverter.ToString(_DataBytes).Replace('-', ' ').TrimEnd(new char[] { ' ' });
|
||||
}
|
||||
else
|
||||
{
|
||||
_Data = System.Text.ASCIIEncoding.Default.GetString(_DataBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CSendParam(SendParamFormat format, SendParamMode mode, int delayTime, string data, bool trans = true)
|
||||
{
|
||||
_Format = format;
|
||||
_Mode = mode;
|
||||
_DelayTime = delayTime;
|
||||
_Data = data;
|
||||
|
||||
switch (_Format)
|
||||
{
|
||||
case SendParamFormat.ASCII:
|
||||
{
|
||||
byte[] bytes = System.Text.ASCIIEncoding.Default.GetBytes(_Data);
|
||||
if (trans)
|
||||
{
|
||||
|
||||
List<byte> list = new List<byte>();
|
||||
for (int i = 0; i < bytes.Length; i++)
|
||||
{
|
||||
if (bytes[i] == (byte)'\\')
|
||||
{
|
||||
if ((i + 1) >= bytes.Length)
|
||||
{
|
||||
list.Add(bytes[i]);
|
||||
continue;
|
||||
}
|
||||
//\r
|
||||
//<2F><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>r
|
||||
if (bytes[i + 1] == (byte)'r' || bytes[i + 1] == (byte)'R')
|
||||
{
|
||||
list.Add(0x0D);
|
||||
i++;//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||||
}
|
||||
// \n
|
||||
else if (bytes[i + 1] == (byte)'n' || bytes[i + 1] == (byte)'N')
|
||||
{
|
||||
list.Add(0x0A);
|
||||
i++;//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||||
}
|
||||
//\t 09
|
||||
else if (bytes[i + 1] == (byte)'t' || bytes[i + 1] == (byte)'T')
|
||||
{
|
||||
list.Add(0x09);
|
||||
i++;//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||||
}
|
||||
//\v 0B
|
||||
else if (bytes[i + 1] == (byte)'v' || bytes[i + 1] == (byte)'V')
|
||||
{
|
||||
list.Add(0x0B);
|
||||
i++;//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||||
}
|
||||
else if (bytes[i + 1] == (byte)'a' || bytes[i + 1] == (byte)'A')
|
||||
{
|
||||
list.Add(0x07);
|
||||
i++;//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||||
}
|
||||
else if (bytes[i + 1] == (byte)'b' || bytes[i + 1] == (byte)'B')
|
||||
{
|
||||
list.Add(0x08);
|
||||
i++;//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||||
}
|
||||
else if (bytes[i + 1] == (byte)'f' || bytes[i + 1] == (byte)'F')
|
||||
{
|
||||
list.Add(0x0C);
|
||||
i++;//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(bytes[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(bytes[i]);
|
||||
}
|
||||
}
|
||||
_DataBytes = list.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
_DataBytes = bytes;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SendParamFormat.Hex:
|
||||
|
||||
string inputText = Regex.Replace(_Data, @"[0-9A-Fa-f]{2}", "$0 ");
|
||||
string[] strArray = inputText.Split(new string[] { ",", " ", "0x", ",0X", "<22><>", "(", ")" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
|
||||
StringBuilder sbOut = new StringBuilder();
|
||||
foreach (string s in strArray)
|
||||
{
|
||||
sbOut.AppendFormat("{0:X2} ", Convert.ToByte(s, 16));
|
||||
}
|
||||
_Data = sbOut.ToString().TrimEnd(' ');
|
||||
|
||||
|
||||
_DataBytes = Array.ConvertAll<string, byte>(strArray, new Converter<string, byte>(HexStringToByte));
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ʮ<><CAAE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>תʮ<D7AA><CAAE><EFBFBD>ơ<EFBFBD>
|
||||
/// </summary>
|
||||
/// <param name="hexStr"></param>
|
||||
/// <returns></returns>
|
||||
byte HexStringToByte(string hexStr)
|
||||
{
|
||||
return Convert.ToByte(hexStr, 16);
|
||||
}
|
||||
|
||||
public SendParamFormat Format
|
||||
{
|
||||
get { return _Format; }
|
||||
set { _Format = value; }
|
||||
}
|
||||
|
||||
public SendParamMode Mode
|
||||
{
|
||||
get { return _Mode; }
|
||||
set { _Mode = value; }
|
||||
}
|
||||
|
||||
public int DelayTime
|
||||
{
|
||||
get { return _DelayTime; }
|
||||
set { _DelayTime = value; }
|
||||
}
|
||||
|
||||
public int DataLen
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_DataBytes != null)
|
||||
{
|
||||
return _DataBytes.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Data
|
||||
{
|
||||
get { return _Data; }
|
||||
}
|
||||
|
||||
public string HexString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format("{0} ", BitConverter.ToString(_DataBytes).Replace('-', ' '));
|
||||
}
|
||||
}
|
||||
|
||||
public string ASCIIString
|
||||
{
|
||||
get { return System.Text.ASCIIEncoding.Default.GetString(_DataBytes); }
|
||||
}
|
||||
|
||||
public string DecString
|
||||
{
|
||||
get
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
foreach (byte b in _DataBytes)
|
||||
{
|
||||
sb.AppendFormat("{0} ", Convert.ToInt32(b));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public byte[] DataBytes
|
||||
{
|
||||
get
|
||||
{
|
||||
return _DataBytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string ParameterString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format("{0}:{1}:{2}", (int)_Format, (int)_Mode, _DelayTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum SendParamFormat : int
|
||||
{
|
||||
ASCII = 0,
|
||||
Hex = 1
|
||||
}
|
||||
|
||||
public enum SendParamMode : int
|
||||
{
|
||||
//SendDelayTime = 0,// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
|
||||
SendAfterLastSend = 0,//<2F><>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD>
|
||||
SendAfterReceived = 1//<2F><><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><D6A1>
|
||||
}
|
||||
}
|
||||
562
常用工具集/Utility/SerialDebug/CSerialDebug.cs
Normal file
562
常用工具集/Utility/SerialDebug/CSerialDebug.cs
Normal file
@@ -0,0 +1,562 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Sockets;
|
||||
using System.IO;
|
||||
|
||||
namespace SerialDebug
|
||||
{
|
||||
class CSerialDebug
|
||||
{
|
||||
private Queue<SerialDebugReceiveData> receiveQueue = new Queue<SerialDebugReceiveData>();
|
||||
private List<CSendParam> sendList = new List<CSendParam>();
|
||||
|
||||
private SerialPort _serialPort = new SerialPort();
|
||||
private bool IsReceiveStart = false;
|
||||
private Thread receiveThread;
|
||||
private Thread parseThread;
|
||||
private bool IsSendStart = false;
|
||||
private Thread sendThread;
|
||||
private TimeSpan delayTime = new TimeSpan(10 * 100); // 100us
|
||||
private int LoopCount = 0;
|
||||
private int _ReceiveTimeOut = 3;
|
||||
private bool _SendThreadBusy = false;
|
||||
public delegate void ReceivedEventHandler(object sender, SerialDebugReceiveData e);
|
||||
public event ReceivedEventHandler ReceivedEvent;
|
||||
|
||||
public delegate void SendCompletedEventHandler(object sender, SendCompletedEventArgs e);
|
||||
public event SendCompletedEventHandler SendCompletedEvent;
|
||||
public event EventHandler SendOverEvent;
|
||||
|
||||
private AutoResetEvent waitReceiveEvent = new AutoResetEvent(false);
|
||||
private ManualResetEvent waitParseEvent = new ManualResetEvent(false);
|
||||
private ManualResetEvent uartReceivedEvent = new ManualResetEvent(false);
|
||||
|
||||
public CSerialDebug(SerialPort sport)
|
||||
{
|
||||
_serialPort = sport;
|
||||
}
|
||||
|
||||
public SerialPort serialPort
|
||||
{
|
||||
get { return _serialPort; }
|
||||
set { _serialPort = value; }
|
||||
}
|
||||
|
||||
public int ReceiveTimeOut
|
||||
{
|
||||
get { return _ReceiveTimeOut; }
|
||||
set { _ReceiveTimeOut = value; }
|
||||
}
|
||||
|
||||
public bool SendThreadBusy
|
||||
{
|
||||
get { return _SendThreadBusy; }
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
IsReceiveStart = true;
|
||||
lock (receiveQueue)
|
||||
{
|
||||
receiveQueue.Clear();
|
||||
}
|
||||
|
||||
lock (sendList)
|
||||
{
|
||||
sendList.Clear();
|
||||
}
|
||||
|
||||
uartReceivedEvent.Reset();
|
||||
waitReceiveEvent.Reset();
|
||||
waitParseEvent.Reset();
|
||||
|
||||
if (serialPort.IsOpen)
|
||||
{
|
||||
serialPort.Close();
|
||||
}
|
||||
serialPort.Open();
|
||||
serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
|
||||
|
||||
releaseThread(receiveThread);
|
||||
releaseThread(sendThread);
|
||||
|
||||
receiveThread = new Thread(new ThreadStart(ReceiveThreadHandler));
|
||||
receiveThread.IsBackground = true;
|
||||
receiveThread.Name = "receiveThread";
|
||||
receiveThread.Start();
|
||||
|
||||
parseThread = new Thread(new ThreadStart(ParseThreadHandler));
|
||||
parseThread.IsBackground = true;
|
||||
parseThread.Name = "parseThread";
|
||||
parseThread.Start();
|
||||
|
||||
Send(sendList, 1);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
IsReceiveStart = false;
|
||||
IsSendStart = false;
|
||||
if (serialPort != null)
|
||||
{
|
||||
|
||||
lock (serialPort)
|
||||
{
|
||||
serialPort.DataReceived -= new SerialDataReceivedEventHandler(serialPort_DataReceived);
|
||||
if (serialPort.IsOpen)
|
||||
{
|
||||
serialPort.Close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
releaseThread(receiveThread);
|
||||
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void StopReceive()
|
||||
{
|
||||
IsReceiveStart = false;
|
||||
}
|
||||
|
||||
public void StopSend()
|
||||
{
|
||||
IsSendStart = false;
|
||||
waitParseEvent.Set();
|
||||
waitParseEvent.Reset();
|
||||
|
||||
while (SendThreadBusy)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
|
||||
//releaseThread(sendThread);
|
||||
}
|
||||
public void Send(List<CSendParam> list)
|
||||
{
|
||||
LoopCount = 1;
|
||||
Send(list, LoopCount);
|
||||
}
|
||||
public void Send(List<CSendParam> list, int loop)
|
||||
{
|
||||
|
||||
if (sendThread != null)
|
||||
{
|
||||
if (sendThread.IsAlive)
|
||||
{
|
||||
releaseThread(sendThread);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LoopCount = loop;
|
||||
lock (sendList)
|
||||
{
|
||||
sendList.Clear();
|
||||
}
|
||||
sendList = list;
|
||||
IsSendStart = true;
|
||||
|
||||
sendThread = new Thread(new ThreadStart(SendThreadHandler));
|
||||
sendThread.IsBackground = true;
|
||||
sendThread.Name = "sendThread";
|
||||
sendThread.Start();
|
||||
}
|
||||
|
||||
private bool SerialPortWrite(byte[] bytes, int offset, int count)
|
||||
{
|
||||
if (_serialPort != null && _serialPort.IsOpen)
|
||||
{
|
||||
lock (_serialPort)
|
||||
{
|
||||
_serialPort.Write(bytes, offset, count);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void releaseThread(Thread th)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (th != null)
|
||||
{
|
||||
lock (th)
|
||||
{
|
||||
if (th.IsAlive)
|
||||
{
|
||||
th.Abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
|
||||
{
|
||||
if (uartReceivedEvent != null)
|
||||
{
|
||||
uartReceivedEvent.Set();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
||||
/// </summary>
|
||||
private void ReceiveThreadHandler()
|
||||
{
|
||||
|
||||
//byte[] receiveBytes = new byte[4 * 1024];
|
||||
while (IsReceiveStart)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_serialPort.IsOpen)
|
||||
{
|
||||
try
|
||||
{
|
||||
bool IsNeedContinueReceive = false;
|
||||
int dataLen;
|
||||
if (uartReceivedEvent.WaitOne() || IsNeedContinueReceive)
|
||||
{
|
||||
uartReceivedEvent.Reset();
|
||||
|
||||
//DateTime beginTime = DateTime.Now;
|
||||
int buffSize = 0;
|
||||
do
|
||||
{
|
||||
buffSize = serialPort.BytesToRead;
|
||||
if (buffSize >= 4 * 1024)
|
||||
{
|
||||
IsNeedContinueReceive = true;
|
||||
break;
|
||||
}
|
||||
Thread.Sleep(ReceiveTimeOut);
|
||||
|
||||
} while (buffSize != serialPort.BytesToRead);
|
||||
|
||||
if (buffSize > 0)
|
||||
{
|
||||
byte[] receiveBytes = new byte[buffSize];
|
||||
dataLen = serialPort.Read(receiveBytes, 0, receiveBytes.Length);
|
||||
if (dataLen > 0)
|
||||
{
|
||||
byte[] bytes = new byte[dataLen];
|
||||
Array.Copy(receiveBytes, bytes, dataLen);
|
||||
lock (receiveQueue)
|
||||
{
|
||||
receiveQueue.Enqueue(new SerialDebugReceiveData(bytes));
|
||||
}
|
||||
waitReceiveEvent.Set();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
if (ex is ThreadInterruptedException)
|
||||
throw;
|
||||
Debug.WriteLine(ex.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
if (ex is ThreadInterruptedException)
|
||||
break;
|
||||
Debug.WriteLine(ex.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
||||
/// </summary>
|
||||
private void ParseThreadHandler()
|
||||
{
|
||||
while (IsReceiveStart)
|
||||
{
|
||||
try
|
||||
{
|
||||
SerialDebugReceiveData data = null;
|
||||
lock (receiveQueue)
|
||||
{
|
||||
if (receiveQueue.Count > 0)
|
||||
{
|
||||
data = receiveQueue.Dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
|
||||
if (ReceivedEvent != null)
|
||||
{
|
||||
ReceivedEvent(this, data);
|
||||
}
|
||||
waitParseEvent.Set();
|
||||
}
|
||||
else
|
||||
{
|
||||
waitReceiveEvent.WaitOne(10);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("<22><><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD>̣߳<DFB3>" + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
||||
/// </summary>
|
||||
private void SendThreadHandler()
|
||||
{
|
||||
bool IsFirstSend = true;
|
||||
|
||||
if (LoopCount == 0)
|
||||
{
|
||||
LoopCount = int.MaxValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
while (LoopCount > 0 && IsSendStart)
|
||||
{
|
||||
LoopCount--;
|
||||
|
||||
waitParseEvent.Reset();
|
||||
|
||||
int index = 0;
|
||||
while (index < sendList.Count && IsSendStart)
|
||||
{
|
||||
_SendThreadBusy = true;
|
||||
|
||||
CSendParam sendParam = null;
|
||||
lock (sendList)
|
||||
{
|
||||
sendParam = sendList[index];
|
||||
}
|
||||
index++;
|
||||
|
||||
if (sendParam != null)
|
||||
{
|
||||
bool DelayEnable = true;
|
||||
if (sendParam.Mode == SendParamMode.SendAfterLastSend)
|
||||
{
|
||||
if (IsFirstSend)
|
||||
{
|
||||
DelayEnable = false;
|
||||
}
|
||||
}
|
||||
else if (sendParam.Mode == SendParamMode.SendAfterReceived)
|
||||
{
|
||||
waitParseEvent.WaitOne();
|
||||
}
|
||||
IsFirstSend = false;
|
||||
|
||||
if (DelayEnable && sendParam.DelayTime > 0)
|
||||
{
|
||||
DateTime startTime = DateTime.Now;
|
||||
TimeSpan ts = DateTime.Now - startTime;
|
||||
while (ts.TotalMilliseconds < sendParam.DelayTime)
|
||||
{
|
||||
Thread.Sleep(delayTime);
|
||||
ts = DateTime.Now - startTime;
|
||||
if (!IsSendStart)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
if (IsSendStart && SerialPortWrite(sendParam.DataBytes, 0, sendParam.DataBytes.Length))
|
||||
{
|
||||
if (SendCompletedEvent != null)
|
||||
{
|
||||
SendCompletedEventHandler handler = SendCompletedEvent;
|
||||
handler(this, new SendCompletedEventArgs(sendParam));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IsSendStart = false;
|
||||
}
|
||||
|
||||
waitParseEvent.Reset();
|
||||
}
|
||||
_SendThreadBusy = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (SendOverEvent != null)
|
||||
{
|
||||
SendOverEvent(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class SerialDebugReceiveData : EventArgs
|
||||
{
|
||||
private readonly DateTime _ReceiveTime;
|
||||
private readonly byte[] _ReceiveData;
|
||||
private readonly int _DataLen;
|
||||
|
||||
public SerialDebugReceiveData(byte[] data)
|
||||
{
|
||||
_ReceiveData = data;
|
||||
_ReceiveTime = DateTime.Now;
|
||||
if (data != null)
|
||||
{
|
||||
_DataLen = data.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
_DataLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] ReceiveData
|
||||
{
|
||||
get { return _ReceiveData; }
|
||||
}
|
||||
|
||||
public DateTime ReceiveTime
|
||||
{
|
||||
get { return _ReceiveTime; }
|
||||
}
|
||||
|
||||
public int DataLen
|
||||
{
|
||||
get { return _DataLen; }
|
||||
}
|
||||
|
||||
public string TimeString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format("[{0}.{1:D3}]", _ReceiveTime.ToString("yyyy-MM-dd HH:mm:ss.fff"), _ReceiveTime.Millisecond);
|
||||
}
|
||||
}
|
||||
|
||||
public string HexString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format("{0} ", BitConverter.ToString(_ReceiveData).Replace('-', ' '));
|
||||
}
|
||||
}
|
||||
|
||||
public string ASCIIString
|
||||
{
|
||||
get { return System.Text.ASCIIEncoding.Default.GetString(_ReceiveData); }
|
||||
}
|
||||
|
||||
public string DecString
|
||||
{
|
||||
get
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
foreach (byte b in _ReceiveData)
|
||||
{
|
||||
sb.AppendFormat("{0} ", Convert.ToInt32(b));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class SendCompletedEventArgs : EventArgs
|
||||
{
|
||||
private readonly DateTime _SendTime;
|
||||
private CSendParam _SendParam;
|
||||
|
||||
public SendCompletedEventArgs(CSendParam sendParam)
|
||||
{
|
||||
_SendTime = DateTime.Now;
|
||||
_SendParam = sendParam;
|
||||
|
||||
//if (sendParam!=null)
|
||||
//{
|
||||
// _SendParam = new CSendParam(sendParam.Format,
|
||||
// sendParam.Mode,
|
||||
// sendParam.DelayTime,
|
||||
// sendParam.DataBytes, 0, sendParam.DataLen);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// _SendParam = null;
|
||||
//}
|
||||
}
|
||||
|
||||
public DateTime SendTime
|
||||
{
|
||||
get { return _SendTime; }
|
||||
}
|
||||
|
||||
public CSendParam SendParam
|
||||
{
|
||||
get { return _SendParam; }
|
||||
}
|
||||
|
||||
public string TimeString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format("[{0}.{1:D3}]", _SendTime.ToString("yyyy-MM-dd HH:mm:ss"), _SendTime.Millisecond);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
357
常用工具集/Utility/SerialDebug/DataCheck.cs
Normal file
357
常用工具集/Utility/SerialDebug/DataCheck.cs
Normal file
@@ -0,0 +1,357 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XMX
|
||||
{
|
||||
|
||||
public enum CRCType : int
|
||||
{
|
||||
CRC16_IBM = 0,
|
||||
CRC16_MAXIM,
|
||||
CRC16_USB,
|
||||
CRC16_MODBUS,
|
||||
CRC16_CCITT,
|
||||
CRC16_CCITT_FALSE,
|
||||
CRC16_X25,
|
||||
CRC16_XMODEM,
|
||||
CRC16_DNP,
|
||||
CRC32,
|
||||
CRC32_MPEG2,
|
||||
}
|
||||
|
||||
public class DataCheck
|
||||
{
|
||||
static public CRCInfo GetCRCInfo(CRCType type)
|
||||
{
|
||||
CRCInfo param = null;
|
||||
switch (type)
|
||||
{
|
||||
case CRCType.CRC16_IBM:
|
||||
param = new CRCInfo(0x8005, 0x0000, true, true, 0x0000);
|
||||
break;
|
||||
case CRCType.CRC16_MAXIM:
|
||||
param = new CRCInfo(0x8005, 0x0000, true, true, 0xFFFF);
|
||||
break;
|
||||
|
||||
case CRCType.CRC16_USB:
|
||||
param = new CRCInfo(0x8005, 0xFFFF, true, true, 0xFFFF);
|
||||
break;
|
||||
|
||||
case CRCType.CRC16_MODBUS:
|
||||
param = new CRCInfo(0x8005, 0xFFFF, true, true, 0x0000);
|
||||
break;
|
||||
|
||||
case CRCType.CRC16_CCITT:
|
||||
param = new CRCInfo(0x1021, 0x0000, true, true, 0x0000);
|
||||
break;
|
||||
|
||||
case CRCType.CRC16_CCITT_FALSE:
|
||||
param = new CRCInfo(0x1021, 0xFFFF, false, false, 0x0000);
|
||||
break;
|
||||
|
||||
case CRCType.CRC16_X25:
|
||||
param = new CRCInfo(0x1021, 0xFFFF, true, true, 0xFFFF);
|
||||
break;
|
||||
|
||||
case CRCType.CRC16_XMODEM:
|
||||
param = new CRCInfo(0x1021, 0x0000, false, false, 0x0000);
|
||||
break;
|
||||
|
||||
case CRCType.CRC16_DNP:
|
||||
param = new CRCInfo(0x3D65, 0x0000, true, true, 0xFFFF);
|
||||
break;
|
||||
|
||||
case CRCType.CRC32:
|
||||
param = new CRCInfo(0x04C11DB7, 0xFFFFFFFF, true, true, 0xFFFFFFFF);
|
||||
break;
|
||||
case CRCType.CRC32_MPEG2:
|
||||
param = new CRCInfo(0x04C11DB7, 0xFFFFFFFF, false, false, 0x00000000);
|
||||
break;
|
||||
}
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
static public UInt32 GetCRC(CRCType type, byte[] data)
|
||||
{
|
||||
CRCInfo param;
|
||||
|
||||
param = GetCRCInfo(type);
|
||||
if (type >= CRCType.CRC16_IBM && type <= CRCType.CRC16_DNP)
|
||||
{
|
||||
return GetCRC16(param, data);
|
||||
}
|
||||
else if (type>=CRCType.CRC32 && type<=CRCType.CRC32_MPEG2)
|
||||
{
|
||||
return GetCRC32(param, data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static public UInt16 GetCRC16(CRCInfo param, byte[] data)
|
||||
{
|
||||
UInt16 crc = (UInt16)param.Init;
|
||||
UInt16 Poly = 0;
|
||||
UInt16 XorOut = (UInt16)param.XorOut;
|
||||
|
||||
if (param.RefIn)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
Poly <<= 1;
|
||||
if ((param.Poly & (1u << i)) != 0)
|
||||
{
|
||||
Poly |= 0x01;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Poly = (UInt16)param.Poly;
|
||||
}
|
||||
|
||||
foreach (byte b in data)
|
||||
{
|
||||
UInt16 bValue;
|
||||
if (param.RefOut)
|
||||
{
|
||||
bValue = Convert.ToUInt16(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
bValue = Convert.ToUInt16((UInt16)b << 8);
|
||||
}
|
||||
|
||||
crc = Convert.ToUInt16(crc ^ bValue);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (param.RefOut)
|
||||
{
|
||||
if ((crc & 0x01) != 0)
|
||||
{
|
||||
crc >>= 1;
|
||||
crc ^= Poly;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc >>= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((crc & 0x8000) != 0)
|
||||
{
|
||||
crc <<= 1;
|
||||
crc ^= Poly;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Convert.ToUInt16(crc ^ XorOut);
|
||||
}
|
||||
|
||||
static public UInt32 GetCRC32(CRCInfo param, byte[] data)
|
||||
{
|
||||
UInt32 crc = (UInt32)param.Init;
|
||||
UInt32 Poly = 0;
|
||||
UInt32 XorOut = (UInt32)param.XorOut;
|
||||
|
||||
if (param.RefIn)
|
||||
{
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
Poly <<= 1;
|
||||
if ((param.Poly & (1u << i)) != 0)
|
||||
{
|
||||
Poly |= 0x01;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Poly = (UInt32)param.Poly;
|
||||
}
|
||||
|
||||
foreach (byte b in data)
|
||||
{
|
||||
UInt32 bValue;
|
||||
if (param.RefOut)
|
||||
{
|
||||
bValue = Convert.ToUInt32(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
bValue = Convert.ToUInt32((UInt32)b << 24);
|
||||
}
|
||||
|
||||
crc = Convert.ToUInt32(crc ^ bValue);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (param.RefOut)
|
||||
{
|
||||
if ((crc & 0x01) != 0)
|
||||
{
|
||||
crc >>= 1;
|
||||
crc ^= Poly;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc >>= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((crc & 0x80000000) != 0)
|
||||
{
|
||||
crc <<= 1;
|
||||
crc ^= Poly;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Convert.ToUInt32(crc ^ XorOut);
|
||||
}
|
||||
|
||||
|
||||
static public UInt32 GetCheckSum(byte[] data)
|
||||
{
|
||||
UInt32 sum = 0;
|
||||
|
||||
foreach (byte b in data)
|
||||
{
|
||||
sum += b;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static public byte GetXor(byte[] data)
|
||||
{
|
||||
byte xor = 0;
|
||||
|
||||
foreach (byte b in data)
|
||||
{
|
||||
xor ^= b;
|
||||
}
|
||||
|
||||
return xor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class CRCInfo
|
||||
{
|
||||
private UInt32 _Poly;
|
||||
private UInt32 _Init;
|
||||
private UInt32 _XorOut;
|
||||
private bool _RefIn;
|
||||
private bool _RefOut;
|
||||
|
||||
public CRCInfo()
|
||||
: this(0, 0, false, false, 0)
|
||||
{
|
||||
|
||||
}
|
||||
public CRCInfo(UInt32 poly, UInt32 init, bool refIn, bool refOut, UInt32 xorOut)
|
||||
{
|
||||
_Poly = poly;
|
||||
_Init = init;
|
||||
_RefIn = refIn;
|
||||
_RefOut = refOut;
|
||||
_XorOut = xorOut;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 多项式
|
||||
/// </summary>
|
||||
public UInt32 Poly
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Poly;
|
||||
}
|
||||
set
|
||||
{
|
||||
_Poly = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始值
|
||||
/// </summary>
|
||||
public UInt32 Init
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Init;
|
||||
}
|
||||
set
|
||||
{
|
||||
_Init = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 输出CRC异或值
|
||||
/// </summary>
|
||||
public UInt32 XorOut
|
||||
{
|
||||
get { return _XorOut; }
|
||||
set { _XorOut = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 输入多项式反序
|
||||
/// </summary>
|
||||
public bool RefIn
|
||||
{
|
||||
get { return _RefIn; }
|
||||
set { _RefIn = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 输出数据反序
|
||||
/// </summary>
|
||||
public bool RefOut
|
||||
{
|
||||
get { return _RefOut; }
|
||||
set { _RefOut = value; }
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if ((Poly & 0xFFFF0000) != 0)
|
||||
{
|
||||
sb.AppendFormat("Poly: {0:X8}\r\n", Poly);
|
||||
sb.AppendFormat("Init: {0:X8}\r\n", Init);
|
||||
sb.AppendFormat("RefIn: {0}\r\n", RefIn ? "True" : "False");
|
||||
sb.AppendFormat("RefOut:{0}\r\n", RefOut ? "True" : "False");
|
||||
sb.AppendFormat("XorOut:{0:X8}", XorOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendFormat("Poly: {0:X4}\r\n", Poly);
|
||||
sb.AppendFormat("Init: {0:X4}\r\n", Init);
|
||||
sb.AppendFormat("RefIn: {0}\r\n", RefIn ? "True" : "False");
|
||||
sb.AppendFormat("RefOut:{0}\r\n", RefOut ? "True" : "False");
|
||||
sb.AppendFormat("XorOut:{0:X4}", XorOut);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
101
常用工具集/Utility/SerialDebug/FileTransmit/BinarySend.cs
Normal file
101
常用工具集/Utility/SerialDebug/FileTransmit/BinarySend.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using XMX.FileTransmit;
|
||||
using System.Threading;
|
||||
|
||||
|
||||
namespace XMX.FileTransmit
|
||||
{
|
||||
public class BinarySend : IFileTramsmit, ITransmitUart
|
||||
{
|
||||
private bool IsStart = false;
|
||||
Thread SendThread;
|
||||
|
||||
private int DelayTime = 10;
|
||||
public BinarySend(int delayTime)
|
||||
{
|
||||
DelayTime = delayTime;
|
||||
}
|
||||
|
||||
|
||||
private void SendThreadHandler()
|
||||
{
|
||||
while (IsStart)
|
||||
{
|
||||
if (SendNextPacket != null)
|
||||
{
|
||||
SendNextPacket(this, null);
|
||||
Thread.Sleep(DelayTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region IFileTramsmit <EFBFBD><EFBFBD>Ա
|
||||
|
||||
public event EventHandler StartSend = null;
|
||||
|
||||
public event EventHandler StartReceive = null;
|
||||
|
||||
public event EventHandler SendNextPacket;
|
||||
|
||||
public event EventHandler ReSendPacket = null;
|
||||
|
||||
public event EventHandler AbortTransmit = null;
|
||||
|
||||
public event EventHandler TransmitTimeOut = null;
|
||||
|
||||
public event EventHandler EndOfTransmit = null;
|
||||
|
||||
public event PacketEventHandler ReceivedPacket = null;
|
||||
|
||||
public void SendPacket(PacketEventArgs packet)
|
||||
{
|
||||
if (SendToUartEvent != null)
|
||||
{
|
||||
SendToUartEvent(null, new SendToUartEventArgs(packet.Packet));
|
||||
}
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
IsStart = true;
|
||||
SendThread = new Thread(new ThreadStart(SendThreadHandler));
|
||||
SendThread.IsBackground = true;
|
||||
SendThread.Start();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
IsStart = false;
|
||||
if (EndOfTransmit!=null)
|
||||
{
|
||||
EndOfTransmit(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void Abort()
|
||||
{
|
||||
IsStart = false;
|
||||
if (AbortTransmit!=null)
|
||||
{
|
||||
AbortTransmit(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ITransmitUart <EFBFBD><EFBFBD>Ա
|
||||
|
||||
public event SendToUartEventHandler SendToUartEvent;
|
||||
|
||||
public void ReceivedFromUart(byte[] data)
|
||||
{
|
||||
Console.WriteLine("<22><><EFBFBD><EFBFBD><EFBFBD>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>账<EFBFBD><E8B4A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
84
常用工具集/Utility/SerialDebug/FileTransmit/IFileTramsmit.cs
Normal file
84
常用工具集/Utility/SerialDebug/FileTransmit/IFileTramsmit.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XMX.FileTransmit
|
||||
{
|
||||
public enum TransmitMode
|
||||
{
|
||||
Receive,
|
||||
Send
|
||||
}
|
||||
|
||||
public delegate void PacketEventHandler(object sender, PacketEventArgs e);
|
||||
|
||||
interface IFileTramsmit:ITransmitUart
|
||||
{
|
||||
|
||||
|
||||
event EventHandler StartSend;
|
||||
event EventHandler StartReceive;
|
||||
event EventHandler SendNextPacket;
|
||||
event EventHandler ReSendPacket;
|
||||
event EventHandler AbortTransmit;
|
||||
event EventHandler TransmitTimeOut;
|
||||
event EventHandler EndOfTransmit;
|
||||
|
||||
event PacketEventHandler ReceivedPacket;
|
||||
|
||||
|
||||
void SendPacket(PacketEventArgs packet);
|
||||
void Start();
|
||||
void Stop();
|
||||
void Abort();
|
||||
|
||||
}
|
||||
|
||||
public class PacketEventArgs : EventArgs
|
||||
{
|
||||
private readonly int _PacketNo;
|
||||
private readonly int _PacketLen;
|
||||
private readonly byte[] _Packet;
|
||||
|
||||
|
||||
public PacketEventArgs(int packetNo, byte[] packet)
|
||||
: this(packetNo, packet, packet.Length)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public PacketEventArgs(int packetNo, byte[] packet, int packetLen)
|
||||
{
|
||||
_PacketNo = packetNo;
|
||||
|
||||
|
||||
if (packet != null)
|
||||
{
|
||||
if (packet.Length <= packetLen)
|
||||
{
|
||||
_PacketLen = packetLen;
|
||||
}
|
||||
|
||||
_Packet = new byte[_PacketLen];
|
||||
Array.Copy(packet, 0, _Packet, 0, _PacketLen);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int PacketNo
|
||||
{
|
||||
get { return _PacketNo; }
|
||||
}
|
||||
|
||||
public int PacketLen
|
||||
{
|
||||
get { return _PacketLen; }
|
||||
}
|
||||
|
||||
public byte[] Packet
|
||||
{
|
||||
get { return _Packet; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
30
常用工具集/Utility/SerialDebug/FileTransmit/ITransmitUart.cs
Normal file
30
常用工具集/Utility/SerialDebug/FileTransmit/ITransmitUart.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XMX.FileTransmit
|
||||
{
|
||||
public delegate void SendToUartEventHandler(object sender,SendToUartEventArgs e);
|
||||
|
||||
interface ITransmitUart
|
||||
{
|
||||
event SendToUartEventHandler SendToUartEvent;
|
||||
|
||||
void ReceivedFromUart(byte[] data);
|
||||
}
|
||||
|
||||
public class SendToUartEventArgs : EventArgs
|
||||
{
|
||||
private readonly byte[] _Data;
|
||||
|
||||
public SendToUartEventArgs(byte[] data)
|
||||
{
|
||||
_Data = data;
|
||||
}
|
||||
|
||||
public byte[] Data
|
||||
{
|
||||
get { return _Data; }
|
||||
}
|
||||
}
|
||||
}
|
||||
674
常用工具集/Utility/SerialDebug/FileTransmit/XModem.cs
Normal file
674
常用工具集/Utility/SerialDebug/FileTransmit/XModem.cs
Normal file
@@ -0,0 +1,674 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Collections;
|
||||
|
||||
namespace XMX.FileTransmit
|
||||
{
|
||||
|
||||
public enum XModemCheckMode
|
||||
{
|
||||
CheckSum,
|
||||
CRC16
|
||||
}
|
||||
|
||||
public enum XModemType
|
||||
{
|
||||
XModem,
|
||||
XModem_1K
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// XModem<65><6D><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
enum XmodemMessageType : int
|
||||
{
|
||||
KEY_C,
|
||||
ACK,
|
||||
NAK,
|
||||
EOT,
|
||||
PACKET,
|
||||
PACKET_ERROR,
|
||||
CAN
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// XModem<65><6D><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
internal class XmodemMessage
|
||||
{
|
||||
private XmodemMessageType _MessageType;
|
||||
private object _Value;
|
||||
|
||||
|
||||
public XmodemMessage(XmodemMessageType type)
|
||||
: this(type, null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public XmodemMessage(XmodemMessageType type, object value)
|
||||
{
|
||||
_MessageType = type;
|
||||
_Value = value;
|
||||
}
|
||||
|
||||
|
||||
public XmodemMessageType MessageType
|
||||
{
|
||||
get { return _MessageType; }
|
||||
}
|
||||
|
||||
public object Value
|
||||
{
|
||||
get { return _Value; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Xmodem<65><6D><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD>
|
||||
/// </summary>
|
||||
internal enum XmodemSendStage : int
|
||||
{
|
||||
WaitReceiveRequest, //<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>ն<EFBFBD><D5B6><EFBFBD><EFBFBD><EFBFBD>
|
||||
PacketSending,
|
||||
WaitReceiveAnswerEndTransmit
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Xmodem<65><6D><EFBFBD>ղ<EFBFBD><D5B2><EFBFBD>
|
||||
/// </summary>
|
||||
internal enum XmodemReceiveStage : int
|
||||
{
|
||||
WaitForFirstPacket,
|
||||
PacketReceiving,
|
||||
}
|
||||
|
||||
public class XModemInfo
|
||||
{
|
||||
private XModemType _XModemType;
|
||||
private TransmitMode _TransType;
|
||||
private XModemCheckMode _CheckMode;
|
||||
|
||||
public XModemInfo()
|
||||
: this(XModemType.XModem, TransmitMode.Send, XModemCheckMode.CheckSum)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public XModemInfo(XModemType type, TransmitMode transType, XModemCheckMode checkType)
|
||||
{
|
||||
_XModemType = type;
|
||||
_TransType = transType;
|
||||
_CheckMode = checkType;
|
||||
}
|
||||
|
||||
|
||||
public XModemType Type
|
||||
{
|
||||
get { return _XModemType; }
|
||||
set { _XModemType = value; }
|
||||
}
|
||||
|
||||
public TransmitMode TransMode
|
||||
{
|
||||
get { return _TransType; }
|
||||
set { _TransType = value; }
|
||||
}
|
||||
|
||||
public XModemCheckMode CheckMode
|
||||
{
|
||||
get { return _CheckMode; }
|
||||
set { _CheckMode = value; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class XModem : IFileTramsmit, ITransmitUart
|
||||
{
|
||||
private readonly byte SOH = 0x01;
|
||||
private readonly byte EOT = 0x04;
|
||||
private readonly byte ACK = 0x06;
|
||||
private readonly byte NAK = 0x15;
|
||||
private readonly byte CAN = 0x18;
|
||||
|
||||
private readonly byte STX = 0x02;
|
||||
private readonly byte KEY_C = 0x43; //'C';
|
||||
|
||||
private int RetryMax = 6;
|
||||
XModemInfo xmodemInfo = new XModemInfo();
|
||||
|
||||
|
||||
private Thread TransThread;
|
||||
private bool IsStart = false;
|
||||
private int reTryCount;
|
||||
private ManualResetEvent waitReceiveEvent = new ManualResetEvent(false);
|
||||
|
||||
|
||||
private XmodemReceiveStage ReceiveStage;
|
||||
private XmodemSendStage SendStage;
|
||||
private Queue<XmodemMessage> msgQueue = new Queue<XmodemMessage>();
|
||||
|
||||
public XModem(TransmitMode transType, XModemType xmodemType, int reTryCount)
|
||||
{
|
||||
RetryMax = reTryCount;
|
||||
|
||||
xmodemInfo.CheckMode = XModemCheckMode.CheckSum;
|
||||
xmodemInfo.Type = xmodemType;
|
||||
xmodemInfo.TransMode = transType;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
IsStart = true;
|
||||
reTryCount = 0;
|
||||
|
||||
|
||||
ReceiveStage = XmodemReceiveStage.WaitForFirstPacket;
|
||||
SendStage = XmodemSendStage.WaitReceiveRequest;
|
||||
msgQueue.Clear();
|
||||
|
||||
TransThread = new Thread(new ThreadStart(TransThreadHandler));
|
||||
TransThread.IsBackground = true;
|
||||
TransThread.Name = "XmodemTransThread";
|
||||
TransThread.Start();
|
||||
if (xmodemInfo.TransMode == TransmitMode.Receive)
|
||||
{
|
||||
if (StartReceive != null)
|
||||
{
|
||||
StartReceive(xmodemInfo, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (xmodemInfo.TransMode == TransmitMode.Receive)
|
||||
{
|
||||
Abort();
|
||||
}
|
||||
else
|
||||
{
|
||||
SendEOT();
|
||||
}
|
||||
|
||||
if (EndOfTransmit != null)
|
||||
{
|
||||
EndOfTransmit(xmodemInfo, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void Abort()
|
||||
{
|
||||
IsStart = false;
|
||||
SendCAN();
|
||||
|
||||
if (EndOfTransmit != null)
|
||||
{
|
||||
EndOfTransmit(xmodemInfo, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
private void ParseReceivedMessage(byte[] data)
|
||||
{
|
||||
XmodemMessage ReceivedMessage = null;
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
ReceivedMessage = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data[0] == STX || data[0] == SOH)
|
||||
{
|
||||
ReceivedMessage = new XmodemMessage(XmodemMessageType.PACKET_ERROR);
|
||||
int packetLen = 0;
|
||||
if (data[0] == STX)
|
||||
{
|
||||
packetLen = 1024;
|
||||
}
|
||||
else if (data[0] == SOH)
|
||||
{
|
||||
packetLen = 128;
|
||||
}
|
||||
|
||||
int checkDataLen = xmodemInfo.CheckMode == XModemCheckMode.CheckSum ? 1 : 2;
|
||||
if (packetLen + 3 + checkDataLen == data.Length)
|
||||
{
|
||||
int packetNo = 0;
|
||||
if (data[1] == Convert.ToByte((~data[2]) & 0xFF))
|
||||
{
|
||||
packetNo = data[1];
|
||||
}
|
||||
|
||||
int frameCheckCode = 0;
|
||||
int calCheckCode = -1;
|
||||
byte[] packet = new byte[packetLen];
|
||||
|
||||
Array.Copy(data, 3, packet, 0, packetLen);
|
||||
if (xmodemInfo.CheckMode == XModemCheckMode.CheckSum)
|
||||
{
|
||||
frameCheckCode = data[3 + packetLen];
|
||||
calCheckCode = Convert.ToByte(DataCheck.GetCheckSum(packet) & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
frameCheckCode = (data[3 + packetLen] << 8) + data[3 + packetLen + 1];
|
||||
calCheckCode = Convert.ToUInt16(DataCheck.GetCRC(CRCType.CRC16_XMODEM, packet) & 0xFFFF);
|
||||
}
|
||||
|
||||
if (frameCheckCode == calCheckCode)
|
||||
{
|
||||
ReceivedMessage = new XmodemMessage(XmodemMessageType.PACKET, new PacketEventArgs(packetNo, packet));
|
||||
}
|
||||
|
||||
}
|
||||
msgQueue.Enqueue(ReceivedMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (byte b in data)
|
||||
{
|
||||
ReceivedMessage = null;
|
||||
if (b == EOT)
|
||||
{
|
||||
ReceivedMessage = new XmodemMessage(XmodemMessageType.EOT);
|
||||
}
|
||||
else if (b == CAN)
|
||||
{
|
||||
ReceivedMessage = new XmodemMessage(XmodemMessageType.CAN);
|
||||
}
|
||||
else if (b == NAK)
|
||||
{
|
||||
ReceivedMessage = new XmodemMessage(XmodemMessageType.NAK);
|
||||
}
|
||||
else if (b == ACK)
|
||||
{
|
||||
ReceivedMessage = new XmodemMessage(XmodemMessageType.ACK);
|
||||
}
|
||||
else if (b == KEY_C)
|
||||
{
|
||||
ReceivedMessage = new XmodemMessage(XmodemMessageType.KEY_C);
|
||||
}
|
||||
|
||||
if (ReceivedMessage != null)
|
||||
{
|
||||
msgQueue.Enqueue(ReceivedMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
waitReceiveEvent.Set();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void SendFrameToUart(byte data)
|
||||
{
|
||||
byte[] bytes = new byte[1];
|
||||
bytes[0] = data;
|
||||
SendFrameToUart(bytes);
|
||||
}
|
||||
private void SendFrameToUart(byte[] data)
|
||||
{
|
||||
if (SendToUartEvent != null)
|
||||
{
|
||||
SendToUartEvent(xmodemInfo, new SendToUartEventArgs(data));
|
||||
}
|
||||
}
|
||||
|
||||
private void SendACK()
|
||||
{
|
||||
SendFrameToUart(ACK);
|
||||
|
||||
}
|
||||
|
||||
private void SendNAK()
|
||||
{
|
||||
SendFrameToUart(NAK);
|
||||
}
|
||||
|
||||
private void SendKEYC()
|
||||
{
|
||||
SendFrameToUart(KEY_C);
|
||||
}
|
||||
|
||||
private void SendCAN()
|
||||
{
|
||||
byte[] bytes = new byte[5];
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
bytes[i] = CAN;
|
||||
}
|
||||
SendFrameToUart(bytes);
|
||||
}
|
||||
|
||||
private void SendEOT()
|
||||
{
|
||||
SendFrameToUart(EOT);
|
||||
SendStage = XmodemSendStage.WaitReceiveAnswerEndTransmit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TransThreadHandler()
|
||||
{
|
||||
while (IsStart)
|
||||
{
|
||||
if (xmodemInfo.TransMode == TransmitMode.Send)
|
||||
{
|
||||
SendHandler();
|
||||
}
|
||||
else if (xmodemInfo.TransMode == TransmitMode.Receive)
|
||||
{
|
||||
ReceiveHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendHandler()
|
||||
{
|
||||
XmodemMessage msg = null;
|
||||
lock (msgQueue)
|
||||
{
|
||||
if (msgQueue.Count > 0)
|
||||
{
|
||||
msg = msgQueue.Dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
if (msg != null)
|
||||
{
|
||||
reTryCount = 0;
|
||||
|
||||
switch (msg.MessageType)
|
||||
{
|
||||
case XmodemMessageType.NAK:
|
||||
if (SendStage == XmodemSendStage.WaitReceiveRequest)
|
||||
{
|
||||
SendStage = XmodemSendStage.PacketSending;
|
||||
|
||||
xmodemInfo.CheckMode = XModemCheckMode.CheckSum;
|
||||
if (StartSend != null)
|
||||
{
|
||||
StartSend(xmodemInfo, null);
|
||||
}
|
||||
}
|
||||
else if (SendStage == XmodemSendStage.WaitReceiveAnswerEndTransmit)
|
||||
{
|
||||
SendEOT();
|
||||
}
|
||||
else
|
||||
{
|
||||
// ֪ͨ<CDA8>ط<EFBFBD><D8B7><EFBFBD><EFBFBD><EFBFBD>ͷһ<CDB7><D2BB>
|
||||
if (ReSendPacket != null)
|
||||
{
|
||||
ReSendPacket(xmodemInfo, null);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case XmodemMessageType.KEY_C:
|
||||
if (SendStage == XmodemSendStage.WaitReceiveRequest)
|
||||
{
|
||||
SendStage = XmodemSendStage.PacketSending;
|
||||
// ֪ͨ<CDA8><D6AA>ͷһ<CDB7><D2BB>CRC
|
||||
xmodemInfo.CheckMode = XModemCheckMode.CRC16;
|
||||
if (StartSend != null)
|
||||
{
|
||||
StartSend(xmodemInfo, null);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case XmodemMessageType.ACK:
|
||||
if (SendStage == XmodemSendStage.PacketSending)
|
||||
{
|
||||
// ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||||
if (SendNextPacket != null)
|
||||
{
|
||||
SendNextPacket(xmodemInfo, null);
|
||||
}
|
||||
}
|
||||
else if (SendStage == XmodemSendStage.WaitReceiveAnswerEndTransmit)
|
||||
{
|
||||
// ֪ͨ<CDA8><D6AA>ֹ
|
||||
//if (AbortTransmit != null)
|
||||
//{
|
||||
// AbortTransmit(xmodemInfo, null);
|
||||
//}
|
||||
if (EndOfTransmit != null)
|
||||
{
|
||||
EndOfTransmit(xmodemInfo, null);
|
||||
}
|
||||
IsStart = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case XmodemMessageType.CAN:
|
||||
// ֪ͨ<CDA8><D6AA>ֹ
|
||||
if (AbortTransmit != null)
|
||||
{
|
||||
AbortTransmit(xmodemInfo, null);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (waitReceiveEvent.WaitOne(3000))
|
||||
{
|
||||
waitReceiveEvent.Reset();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
reTryCount++;
|
||||
if (reTryCount > RetryMax)
|
||||
{
|
||||
IsStart = false;
|
||||
//֪ͨ<CDA8><D6AA><EFBFBD>ճ<EFBFBD>ʱ
|
||||
if (TransmitTimeOut != null)
|
||||
{
|
||||
TransmitTimeOut(xmodemInfo, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ReceiveHandler()
|
||||
{
|
||||
if (ReceiveStage == XmodemReceiveStage.WaitForFirstPacket)
|
||||
{
|
||||
if (reTryCount % 2 == 0)
|
||||
{
|
||||
xmodemInfo.CheckMode = XModemCheckMode.CheckSum;
|
||||
SendKEYC();
|
||||
}
|
||||
else
|
||||
{
|
||||
xmodemInfo.CheckMode = XModemCheckMode.CRC16;
|
||||
SendNAK();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
XmodemMessage msg = null;
|
||||
lock (msgQueue)
|
||||
{
|
||||
if (msgQueue.Count > 0)
|
||||
{
|
||||
msg = msgQueue.Dequeue();
|
||||
}
|
||||
|
||||
}
|
||||
if (msg != null)
|
||||
{
|
||||
reTryCount = 0;
|
||||
|
||||
switch (msg.MessageType)
|
||||
{
|
||||
case XmodemMessageType.PACKET:
|
||||
ReceiveStage = XmodemReceiveStage.PacketReceiving;
|
||||
SendACK();
|
||||
if (ReceivedPacket != null)
|
||||
{
|
||||
PacketEventArgs e = msg.Value as PacketEventArgs;
|
||||
ReceivedPacket(xmodemInfo, new PacketEventArgs(e.PacketNo, e.Packet));
|
||||
}
|
||||
|
||||
// ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||||
if (SendNextPacket != null)
|
||||
{
|
||||
SendNextPacket(xmodemInfo, null);
|
||||
}
|
||||
break;
|
||||
case XmodemMessageType.PACKET_ERROR:
|
||||
SendNAK();
|
||||
// ֪ͨ<CDA8>ط<EFBFBD>
|
||||
if (ReSendPacket != null)
|
||||
{
|
||||
ReSendPacket(xmodemInfo, null);
|
||||
}
|
||||
break;
|
||||
case XmodemMessageType.EOT:
|
||||
SendACK();
|
||||
// ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD>
|
||||
if (EndOfTransmit != null)
|
||||
{
|
||||
EndOfTransmit(xmodemInfo, null);
|
||||
}
|
||||
break;
|
||||
case XmodemMessageType.CAN:
|
||||
SendACK();
|
||||
// ֪ͨ<CDA8><D6AA>ֹ
|
||||
if (AbortTransmit != null)
|
||||
{
|
||||
AbortTransmit(xmodemInfo, null);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (waitReceiveEvent.WaitOne(3000))
|
||||
{
|
||||
waitReceiveEvent.Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
reTryCount++;
|
||||
if (reTryCount > RetryMax)
|
||||
{
|
||||
IsStart = false;
|
||||
//֪ͨ<CDA8><D6AA><EFBFBD>ճ<EFBFBD>ʱ
|
||||
if (TransmitTimeOut != null)
|
||||
{
|
||||
TransmitTimeOut(xmodemInfo, null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#region IFileTramsmit <EFBFBD><EFBFBD>Ա
|
||||
|
||||
public event EventHandler StartSend;
|
||||
|
||||
public event EventHandler StartReceive;
|
||||
|
||||
public event EventHandler SendNextPacket;
|
||||
|
||||
public event EventHandler ReSendPacket;
|
||||
|
||||
public event EventHandler AbortTransmit;
|
||||
|
||||
public event EventHandler EndOfTransmit;
|
||||
|
||||
public event EventHandler TransmitTimeOut;
|
||||
|
||||
public event PacketEventHandler ReceivedPacket;
|
||||
|
||||
public void SendPacket(PacketEventArgs packet)
|
||||
{
|
||||
int packetLen = 0;
|
||||
int checkLen = 0;
|
||||
byte[] data;
|
||||
|
||||
if (xmodemInfo.CheckMode == XModemCheckMode.CheckSum)
|
||||
{
|
||||
checkLen = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkLen = 2;
|
||||
}
|
||||
|
||||
if (xmodemInfo.Type == XModemType.XModem_1K)
|
||||
{
|
||||
packetLen = 1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
packetLen = 128;
|
||||
}
|
||||
|
||||
data = new byte[3 + packetLen + checkLen];
|
||||
|
||||
data[0] = SOH;
|
||||
if (xmodemInfo.Type == XModemType.XModem_1K)
|
||||
{
|
||||
data[0] = STX;
|
||||
}
|
||||
|
||||
data[1] = Convert.ToByte(packet.PacketNo & 0xFF);
|
||||
data[2] = Convert.ToByte((~data[1]) & 0xFF);
|
||||
Array.Copy(packet.Packet, 0, data, 3, packetLen);
|
||||
|
||||
if (xmodemInfo.CheckMode == XModemCheckMode.CheckSum)
|
||||
{
|
||||
data[3 + packetLen] = Convert.ToByte(DataCheck.GetCheckSum(packet.Packet) & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt16 crc = Convert.ToUInt16(DataCheck.GetCRC(CRCType.CRC16_XMODEM, packet.Packet) & 0xFFFF);
|
||||
data[3 + packetLen] = Convert.ToByte(crc >> 8);
|
||||
data[3 + packetLen + 1] = Convert.ToByte(crc & 0xFF);
|
||||
}
|
||||
|
||||
SendFrameToUart(data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ITransmitUart <EFBFBD><EFBFBD>Ա
|
||||
|
||||
public event SendToUartEventHandler SendToUartEvent;
|
||||
public void ReceivedFromUart(byte[] data)
|
||||
{
|
||||
ParseReceivedMessage(data);
|
||||
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
682
常用工具集/Utility/SerialDebug/FileTransmit/YModem.cs
Normal file
682
常用工具集/Utility/SerialDebug/FileTransmit/YModem.cs
Normal file
@@ -0,0 +1,682 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace XMX.FileTransmit
|
||||
{
|
||||
|
||||
public enum YModemCheckMode
|
||||
{
|
||||
CheckSum,
|
||||
CRC16
|
||||
}
|
||||
|
||||
public enum YModemType
|
||||
{
|
||||
YModem,
|
||||
YModem_1K
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// YModem<65><6D><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
enum YmodemMessageType : int
|
||||
{
|
||||
KEY_C,
|
||||
ACK,
|
||||
NAK,
|
||||
EOT,
|
||||
PACKET,
|
||||
PACKET_ERROR,
|
||||
CAN
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// YModem<65><6D><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
internal class YmodemMessage
|
||||
{
|
||||
private YmodemMessageType _MessageType;
|
||||
private object _Value;
|
||||
|
||||
|
||||
public YmodemMessage(YmodemMessageType type)
|
||||
: this(type, null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public YmodemMessage(YmodemMessageType type, object value)
|
||||
{
|
||||
_MessageType = type;
|
||||
_Value = value;
|
||||
}
|
||||
|
||||
|
||||
public YmodemMessageType MessageType
|
||||
{
|
||||
get { return _MessageType; }
|
||||
}
|
||||
|
||||
public object Value
|
||||
{
|
||||
get { return _Value; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Xmodem<65><6D><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD>
|
||||
/// </summary>
|
||||
internal enum YmodemSendStage : int
|
||||
{
|
||||
WaitReceiveRequestFileInfo, //<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>ն<EFBFBD><D5B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ͷ
|
||||
WaitReceiveRequestFirstPacket,
|
||||
PacketSending,
|
||||
WaitReceiveAnswerEndTransmit, // <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>շ<EFBFBD>Ӧ<EFBFBD><D3A6>EOT
|
||||
WaitReceiveNextFileReq, // <20>ȵȽ<C8B5><C8BD>շ<EFBFBD><D5B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ļ<EFBFBD>
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Xmodem<65><6D><EFBFBD>ղ<EFBFBD><D5B2><EFBFBD>
|
||||
/// </summary>
|
||||
internal enum YmodemReceiveStage : int
|
||||
{
|
||||
WaitForFileInfo,
|
||||
WaitForFirstPacket,
|
||||
PacketReceiving,
|
||||
}
|
||||
|
||||
public class YModemInfo
|
||||
{
|
||||
private YModemType _YModemType;
|
||||
private TransmitMode _TransType;
|
||||
|
||||
public YModemInfo()
|
||||
: this(YModemType.YModem, TransmitMode.Send)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public YModemInfo(YModemType type, TransmitMode transType)
|
||||
{
|
||||
_YModemType = type;
|
||||
_TransType = transType;
|
||||
}
|
||||
|
||||
|
||||
public YModemType Type
|
||||
{
|
||||
get { return _YModemType; }
|
||||
set { _YModemType = value; }
|
||||
}
|
||||
|
||||
public TransmitMode TransMode
|
||||
{
|
||||
get { return _TransType; }
|
||||
set { _TransType = value; }
|
||||
}
|
||||
|
||||
//public YModemCheckMode CheckMode
|
||||
//{
|
||||
// get { return _CheckMode; }
|
||||
// set { _CheckMode = value; }
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
public class YModem : IFileTramsmit, ITransmitUart
|
||||
{
|
||||
private readonly byte SOH = 0x01;
|
||||
private readonly byte STX = 0x02;
|
||||
private readonly byte EOT = 0x04;
|
||||
private readonly byte ACK = 0x06;
|
||||
private readonly byte NAK = 0x15;
|
||||
private readonly byte CAN = 0x18;
|
||||
private readonly byte KEY_C = 0x43; //'C';
|
||||
|
||||
private int RetryMax = 6;
|
||||
|
||||
YModemInfo ymodemInfo = new YModemInfo();
|
||||
|
||||
|
||||
private Thread TransThread;
|
||||
private bool IsStart = false;
|
||||
|
||||
private int reTryCount;
|
||||
private ManualResetEvent waitReceiveEvent = new ManualResetEvent(false);
|
||||
private YmodemReceiveStage ReceiveStage;
|
||||
private YmodemSendStage SendStage;
|
||||
private Queue<YmodemMessage> msgQueue = new Queue<YmodemMessage>();
|
||||
|
||||
public YModem(TransmitMode transType, YModemType ymodemType, int reTryCount)
|
||||
{
|
||||
RetryMax = reTryCount;
|
||||
|
||||
ymodemInfo.Type = ymodemType;
|
||||
ymodemInfo.TransMode = transType;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
IsStart = true;
|
||||
reTryCount = 0;
|
||||
|
||||
ReceiveStage = YmodemReceiveStage.WaitForFileInfo;
|
||||
SendStage = YmodemSendStage.WaitReceiveRequestFileInfo;
|
||||
|
||||
|
||||
TransThread = new Thread(new ThreadStart(TransThreadHandler));
|
||||
TransThread.IsBackground = true;
|
||||
TransThread.Name = "YmodemTransThread";
|
||||
TransThread.Start();
|
||||
if (ymodemInfo.TransMode == TransmitMode.Receive)
|
||||
{
|
||||
if (StartReceive != null)
|
||||
{
|
||||
StartReceive(ymodemInfo, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (ymodemInfo.TransMode == TransmitMode.Receive)
|
||||
{
|
||||
Abort();
|
||||
}
|
||||
else
|
||||
{
|
||||
SendEOT();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Abort()
|
||||
{
|
||||
IsStart = false;
|
||||
SendCAN();
|
||||
|
||||
if (EndOfTransmit != null)
|
||||
{
|
||||
EndOfTransmit(ymodemInfo, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
private void ParseReceivedMessage(byte[] data)
|
||||
{
|
||||
|
||||
YmodemMessage ReceivedMessage = null;
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
ReceivedMessage = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data[0] == STX || data[0] == SOH)
|
||||
{
|
||||
ReceivedMessage = new YmodemMessage(YmodemMessageType.PACKET_ERROR);
|
||||
int packetLen = 0;
|
||||
if (data[0] == STX)
|
||||
{
|
||||
packetLen = 1024;
|
||||
}
|
||||
else if (data[0] == SOH)
|
||||
{
|
||||
packetLen = 128;
|
||||
}
|
||||
|
||||
int checkDataLen = 2;
|
||||
if (packetLen + 3 + checkDataLen == data.Length)
|
||||
{
|
||||
int packetNo = 0;
|
||||
if (data[1] == Convert.ToByte((~data[2]) & 0xFF))
|
||||
{
|
||||
packetNo = data[1];
|
||||
}
|
||||
|
||||
int frameCheckCode = 0;
|
||||
int calCheckCode = -1;
|
||||
byte[] packet = new byte[packetLen];
|
||||
|
||||
Array.Copy(data, 3, packet, 0, packetLen);
|
||||
|
||||
frameCheckCode = (data[3 + packetLen] << 8) + data[3 + packetLen + 1];
|
||||
calCheckCode = Convert.ToUInt16(DataCheck.GetCRC(CRCType.CRC16_XMODEM, packet) & 0xFFFF);
|
||||
|
||||
|
||||
if (frameCheckCode == calCheckCode)
|
||||
{
|
||||
ReceivedMessage = new YmodemMessage(YmodemMessageType.PACKET, new PacketEventArgs(packetNo, packet));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (byte b in data)
|
||||
{
|
||||
ReceivedMessage = null;
|
||||
|
||||
if (b == EOT)
|
||||
{
|
||||
ReceivedMessage = new YmodemMessage(YmodemMessageType.EOT);
|
||||
}
|
||||
else if (b == CAN)
|
||||
{
|
||||
ReceivedMessage = new YmodemMessage(YmodemMessageType.CAN);
|
||||
}
|
||||
else if (b == NAK)
|
||||
{
|
||||
ReceivedMessage = new YmodemMessage(YmodemMessageType.NAK);
|
||||
}
|
||||
else if (b == ACK)
|
||||
{
|
||||
ReceivedMessage = new YmodemMessage(YmodemMessageType.ACK);
|
||||
}
|
||||
else if (b == KEY_C)
|
||||
{
|
||||
ReceivedMessage = new YmodemMessage(YmodemMessageType.KEY_C);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
if (ReceivedMessage!=null)
|
||||
{
|
||||
msgQueue.Enqueue(ReceivedMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
waitReceiveEvent.Set();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void SendFrameToUart(byte data)
|
||||
{
|
||||
byte[] bytes = new byte[1];
|
||||
bytes[0] = data;
|
||||
SendFrameToUart(bytes);
|
||||
}
|
||||
private void SendFrameToUart(byte[] data)
|
||||
{
|
||||
if (SendToUartEvent != null)
|
||||
{
|
||||
SendToUartEvent(ymodemInfo, new SendToUartEventArgs(data));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void SendACK()
|
||||
{
|
||||
SendFrameToUart(ACK);
|
||||
|
||||
}
|
||||
|
||||
private void SendNAK()
|
||||
{
|
||||
SendFrameToUart(NAK);
|
||||
}
|
||||
|
||||
private void SendKEYC()
|
||||
{
|
||||
SendFrameToUart(KEY_C);
|
||||
}
|
||||
|
||||
private void SendCAN()
|
||||
{
|
||||
byte[] bytes = new byte[5];
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
bytes[i] = CAN;
|
||||
}
|
||||
SendFrameToUart(bytes);
|
||||
|
||||
}
|
||||
|
||||
private void SendEOT()
|
||||
{
|
||||
SendFrameToUart(EOT);
|
||||
SendStage = YmodemSendStage.WaitReceiveAnswerEndTransmit;
|
||||
}
|
||||
|
||||
|
||||
private void SendNoFilesToSend()
|
||||
{
|
||||
//int packetLen = ymodemInfo.Type == YModemType.YModem ? 128 : 1024;
|
||||
byte[] endPacket = new byte[3 + 128 + 2];
|
||||
endPacket[0] = 0x01;
|
||||
endPacket[1] = 0x00;
|
||||
endPacket[2] = 0xFF;
|
||||
SendFrameToUart(endPacket);
|
||||
|
||||
if (EndOfTransmit != null)
|
||||
{
|
||||
EndOfTransmit(ymodemInfo, null);
|
||||
}
|
||||
IsStart = false;
|
||||
}
|
||||
|
||||
void TransThreadHandler()
|
||||
{
|
||||
while (IsStart)
|
||||
{
|
||||
if (ymodemInfo.TransMode == TransmitMode.Send)
|
||||
{
|
||||
SendHandler();
|
||||
}
|
||||
else if (ymodemInfo.TransMode == TransmitMode.Receive)
|
||||
{
|
||||
ReceiveHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendHandler()
|
||||
{
|
||||
|
||||
YmodemMessage msg;
|
||||
if (msgQueue.Count > 0)
|
||||
{
|
||||
msg = msgQueue.Dequeue();
|
||||
if (msg != null)
|
||||
{
|
||||
reTryCount = 0;
|
||||
switch (msg.MessageType)
|
||||
{
|
||||
case YmodemMessageType.NAK:
|
||||
if (SendStage == YmodemSendStage.WaitReceiveAnswerEndTransmit)
|
||||
{
|
||||
SendEOT();
|
||||
}
|
||||
else
|
||||
{
|
||||
// ֪ͨ<CDA8>ط<EFBFBD>
|
||||
if (ReSendPacket != null)
|
||||
{
|
||||
ReSendPacket(ymodemInfo, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
case YmodemMessageType.KEY_C:
|
||||
if (SendStage == YmodemSendStage.WaitReceiveRequestFileInfo)
|
||||
{
|
||||
// ֪ͨ<CDA8><D6AA>ͷһ<CDB7><D2BB>CRC
|
||||
if (StartSend != null)
|
||||
{
|
||||
StartSend(ymodemInfo, null);
|
||||
}
|
||||
}
|
||||
else if (SendStage == YmodemSendStage.WaitReceiveRequestFirstPacket) //<2F>ȴ<EFBFBD><C8B4><EFBFBD>һ<EFBFBD><D2BB>
|
||||
{
|
||||
SendStage = YmodemSendStage.PacketSending;
|
||||
// ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||||
if (SendNextPacket != null)
|
||||
{
|
||||
SendNextPacket(ymodemInfo, null);
|
||||
}
|
||||
}
|
||||
else if (SendStage == YmodemSendStage.WaitReceiveNextFileReq) //<2F><><EFBFBD>շ<EFBFBD><D5B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ļ<EFBFBD>
|
||||
{
|
||||
SendNoFilesToSend();
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case YmodemMessageType.ACK:
|
||||
if (SendStage == YmodemSendStage.WaitReceiveRequestFileInfo)
|
||||
{
|
||||
SendStage = YmodemSendStage.WaitReceiveRequestFirstPacket; //<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>շ<EFBFBD><D5B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
else if (SendStage == YmodemSendStage.PacketSending)
|
||||
{
|
||||
// ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||||
if (SendNextPacket != null)
|
||||
{
|
||||
SendNextPacket(ymodemInfo, null);
|
||||
}
|
||||
}
|
||||
else if (SendStage == YmodemSendStage.WaitReceiveAnswerEndTransmit)
|
||||
{
|
||||
SendStage = YmodemSendStage.WaitReceiveNextFileReq; //<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>շ<EFBFBD><D5B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ļ<EFBFBD>
|
||||
}
|
||||
|
||||
break;
|
||||
case YmodemMessageType.CAN:
|
||||
// ֪ͨ<CDA8><D6AA>ֹ
|
||||
if (AbortTransmit != null)
|
||||
{
|
||||
AbortTransmit(ymodemInfo, null);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (waitReceiveEvent.WaitOne(3000))
|
||||
{
|
||||
waitReceiveEvent.Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
reTryCount++;
|
||||
if (reTryCount > RetryMax)
|
||||
{
|
||||
IsStart = false;
|
||||
//֪ͨ<CDA8><D6AA><EFBFBD>ճ<EFBFBD>ʱ
|
||||
if (TransmitTimeOut != null)
|
||||
{
|
||||
TransmitTimeOut(ymodemInfo, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ReceiveHandler()
|
||||
{
|
||||
if (ReceiveStage == YmodemReceiveStage.WaitForFileInfo || ReceiveStage == YmodemReceiveStage.WaitForFirstPacket)
|
||||
{
|
||||
SendKEYC();
|
||||
}
|
||||
|
||||
if (msgQueue.Count > 0)
|
||||
{
|
||||
YmodemMessage msg = msgQueue.Dequeue();
|
||||
if (msg != null)
|
||||
{
|
||||
reTryCount = 0;
|
||||
|
||||
switch (msg.MessageType)
|
||||
{
|
||||
case YmodemMessageType.PACKET:
|
||||
|
||||
PacketEventArgs e = msg.Value as PacketEventArgs;
|
||||
if (ReceiveStage == YmodemReceiveStage.WaitForFileInfo)
|
||||
{
|
||||
if (e.PacketNo == 0)
|
||||
{
|
||||
ReceiveStage = YmodemReceiveStage.WaitForFirstPacket;
|
||||
SendACK();
|
||||
|
||||
if (ReceivedPacket != null)
|
||||
{
|
||||
ReceivedPacket(ymodemInfo, new PacketEventArgs(e.PacketNo, e.Packet));
|
||||
}
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// SendNAK();
|
||||
//}
|
||||
}
|
||||
|
||||
else if (ReceiveStage == YmodemReceiveStage.WaitForFirstPacket ||
|
||||
ReceiveStage == YmodemReceiveStage.PacketReceiving)
|
||||
{
|
||||
if (ReceiveStage == YmodemReceiveStage.WaitForFirstPacket)
|
||||
{
|
||||
ReceiveStage = YmodemReceiveStage.PacketReceiving;
|
||||
}
|
||||
|
||||
SendACK();
|
||||
|
||||
if (ReceivedPacket != null)
|
||||
{
|
||||
ReceivedPacket(ymodemInfo, new PacketEventArgs(e.PacketNo, e.Packet));
|
||||
}
|
||||
|
||||
// ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||||
if (SendNextPacket != null)
|
||||
{
|
||||
SendNextPacket(ymodemInfo, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case YmodemMessageType.PACKET_ERROR:
|
||||
SendNAK();
|
||||
// ֪ͨ<CDA8>ط<EFBFBD>
|
||||
if (ReSendPacket != null)
|
||||
{
|
||||
ReSendPacket(ymodemInfo, null);
|
||||
}
|
||||
break;
|
||||
case YmodemMessageType.EOT:
|
||||
SendACK();
|
||||
// ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD>
|
||||
if (EndOfTransmit != null)
|
||||
{
|
||||
EndOfTransmit(ymodemInfo, null);
|
||||
}
|
||||
break;
|
||||
case YmodemMessageType.CAN:
|
||||
SendACK();
|
||||
// ֪ͨ<CDA8><D6AA>ֹ
|
||||
if (AbortTransmit != null)
|
||||
{
|
||||
AbortTransmit(ymodemInfo, null);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (waitReceiveEvent.WaitOne(3000))
|
||||
{
|
||||
waitReceiveEvent.Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
reTryCount++;
|
||||
if (reTryCount > RetryMax)
|
||||
{
|
||||
IsStart = false;
|
||||
//֪ͨ<CDA8><D6AA><EFBFBD>ճ<EFBFBD>ʱ
|
||||
if (TransmitTimeOut != null)
|
||||
{
|
||||
TransmitTimeOut(ymodemInfo, null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#region IFileTramsmit <EFBFBD><EFBFBD>Ա
|
||||
|
||||
public event EventHandler StartSend;
|
||||
|
||||
public event EventHandler StartReceive;
|
||||
|
||||
public event EventHandler SendNextPacket;
|
||||
|
||||
public event EventHandler ReSendPacket;
|
||||
|
||||
public event EventHandler AbortTransmit;
|
||||
|
||||
public event EventHandler EndOfTransmit;
|
||||
|
||||
public event EventHandler TransmitTimeOut;
|
||||
|
||||
public event PacketEventHandler ReceivedPacket;
|
||||
|
||||
public void SendPacket(PacketEventArgs packet)
|
||||
{
|
||||
int packetLen = 0;
|
||||
int checkLen = 0;
|
||||
byte[] data;
|
||||
|
||||
checkLen = 2;
|
||||
|
||||
if (ymodemInfo.Type == YModemType.YModem_1K)
|
||||
{
|
||||
packetLen = 1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
packetLen = 128;
|
||||
}
|
||||
|
||||
data = new byte[3 + packetLen + checkLen];
|
||||
|
||||
data[0] = SOH;
|
||||
if (ymodemInfo.Type == YModemType.YModem_1K)
|
||||
{
|
||||
data[0] = STX;
|
||||
}
|
||||
|
||||
data[1] = Convert.ToByte(packet.PacketNo & 0xFF);
|
||||
data[2] = Convert.ToByte((~data[1]) & 0xFF);
|
||||
Array.Copy(packet.Packet, 0, data, 3, packetLen);
|
||||
|
||||
UInt16 crc = Convert.ToUInt16(DataCheck.GetCRC(CRCType.CRC16_XMODEM, packet.Packet) & 0xFFFF);
|
||||
data[3 + packetLen] = Convert.ToByte(crc >> 8);
|
||||
data[3 + packetLen + 1] = Convert.ToByte(crc & 0xFF);
|
||||
|
||||
|
||||
SendFrameToUart(data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ITransmitUart <EFBFBD><EFBFBD>Ա
|
||||
|
||||
public event SendToUartEventHandler SendToUartEvent;
|
||||
public void ReceivedFromUart(byte[] data)
|
||||
{
|
||||
ParseReceivedMessage(data);
|
||||
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
20
常用工具集/Utility/SerialDebug/ISendForm.cs
Normal file
20
常用工具集/Utility/SerialDebug/ISendForm.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace SerialDebug
|
||||
{
|
||||
public interface ISendForm
|
||||
{
|
||||
List<CSendParam> getSendList();
|
||||
|
||||
|
||||
int LoopCount
|
||||
{
|
||||
get;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user