初始化
This commit is contained in:
591
SERVER/HexFile.cs
Normal file
591
SERVER/HexFile.cs
Normal file
@@ -0,0 +1,591 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SERVER
|
||||
{
|
||||
/// <summary>
|
||||
/// Hex文件处理
|
||||
/// </summary>
|
||||
public class HexFile
|
||||
{
|
||||
/// <summary> 加载文件大小 </summary>
|
||||
private const int _loadFileSize = 1024 * 1024 * 2;
|
||||
|
||||
/// <summary> 加载数据大小 </summary>
|
||||
private const int _loadDataSize = 1024 * 1024 * 2;
|
||||
|
||||
/// <summary> 加载Hex文件数据 </summary>
|
||||
private byte[] _LoadHexFileData = new byte[_loadFileSize];
|
||||
|
||||
/// <summary> 加载数据Buff </summary>
|
||||
private byte[] _LoadDataBuff = new byte[_loadDataSize];
|
||||
|
||||
/// <summary> 加载结束地址 </summary>
|
||||
private int _LoadEndAddr;
|
||||
|
||||
/// <summary> C1-Hex文件起始值 </summary>
|
||||
private int _HexStart_C1 = 0;
|
||||
|
||||
/// <summary> 解析出的文件数据 </summary>
|
||||
private byte[] _ParseData;
|
||||
|
||||
/// <summary> 解析出的配置数据 </summary>
|
||||
private byte[] _ParseConfigData;
|
||||
|
||||
|
||||
/// <summary> 匹配起始值 </summary>
|
||||
private int _matchingValue;
|
||||
|
||||
private readonly int _matchingAddr = 49152; //0xC000 匹配数据起始地址
|
||||
|
||||
|
||||
|
||||
/// <summary> 匹配数据 </summary>
|
||||
private byte[] _matchingData = new byte[512];
|
||||
|
||||
/// <summary>
|
||||
/// 解析Hex文件
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
public byte[] DealHexFile(Stream filePath)
|
||||
{
|
||||
|
||||
bool tmpRet = LoadDataFromFile(filePath);
|
||||
byte[] checkSum = new byte[4];
|
||||
|
||||
int tmpIdx = 0;
|
||||
int tmpLineCnt = 1;
|
||||
int tmpHexValidLenght = _LoadEndAddr - _HexStart_C1;
|
||||
|
||||
if (tmpRet)
|
||||
{
|
||||
StringBuilder parse = new StringBuilder();
|
||||
//Dim tmpStrBuffer As String
|
||||
for (tmpIdx = _HexStart_C1; tmpIdx < _LoadEndAddr; tmpIdx++)
|
||||
{
|
||||
parse.Append(HexByteStr(_LoadDataBuff[tmpIdx])); //<10ms
|
||||
}
|
||||
_ParseData = ConvertHexStringToBytes(parse.ToString());
|
||||
|
||||
Array.Copy(_ParseData, _matchingValue, _matchingData, 0, _matchingData.Length);
|
||||
//Console.WriteLine($"——解析匹配数据——:{vbCrLf}{BitConverter.ToString(_matchingData)}")
|
||||
|
||||
|
||||
|
||||
//'Dim a() As Byte = {&H0}
|
||||
//'Dim b As String = Encoding.GetEncoding("GBK").GetString(a)
|
||||
|
||||
|
||||
////_matchingData
|
||||
//byte[] project = new byte[2]; //项目编码 2 Bytes
|
||||
//Array.Copy(_matchingData, 0, project, 0, project.Length);
|
||||
////Dim projects As String = Encoding.GetEncoding("GBK").GetString(project)
|
||||
//string projects = $"{project[0] + project[1] * 256}";
|
||||
//projects = projects.Replace("\0", "");
|
||||
|
||||
//byte[] roomId = new byte[4]; //房型Id 4 Bytes
|
||||
//Array.Copy(_matchingData, project.Length, roomId, 0, roomId.Length);
|
||||
////Dim roomIds As String = Encoding.GetEncoding("GBK").GetString(roomId)
|
||||
//string roomIds = $"{BitConverter.ToUInt32(roomId, 0)}";
|
||||
//roomIds = roomIds.Replace("\0", "");
|
||||
|
||||
//byte[] version = new byte[20]; //版本号 20 Bytes
|
||||
//Array.Copy(_matchingData, (project.Length + roomId.Length), version, 0, version.Length);
|
||||
//string versions = Encoding.GetEncoding("GBK").GetString(version);
|
||||
//versions = versions.Replace("\0", "");
|
||||
|
||||
//byte[] mcu = new byte[16]; //MCU型号 16 Bytes
|
||||
//Array.Copy(_matchingData, (project.Length + roomId.Length + version.Length), mcu, 0, mcu.Length);
|
||||
//string mcus = Encoding.GetEncoding("GBK").GetString(mcu);
|
||||
//mcus = mcus.Replace("\0", "");
|
||||
|
||||
//byte[] central = new byte[16]; //中控型号 16 Bytes
|
||||
//Array.Copy(_matchingData, (project.Length + roomId.Length + version.Length + mcu.Length), central, 0, central.Length);
|
||||
//string centrals = Encoding.GetEncoding("GBK").GetString(central);
|
||||
//centrals = centrals.Replace("\0", "");
|
||||
|
||||
//byte[] remark = new byte[64]; //备注 64 Bytes
|
||||
//Array.Copy(_matchingData, (project.Length + roomId.Length + version.Length + mcu.Length + central.Length), remark, 0, remark.Length);
|
||||
// string remarks = Encoding.GetEncoding("GBK").GetString(remark);
|
||||
//remarks = remarks.Replace("\0", "");
|
||||
|
||||
////MatchingInfo(projects, roomIds, versions, mcus, centrals, remarks);
|
||||
}
|
||||
return _ParseData;
|
||||
}
|
||||
|
||||
public string Get_HexStart_C1()
|
||||
{
|
||||
return HexStringToBytes(_HexStart_C1);
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取Hex文件中信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetHexInfo()
|
||||
{
|
||||
//_matchingData
|
||||
byte[] project = new byte[2]; //项目编码 2 Bytes
|
||||
Array.Copy(_matchingData, 0, project, 0, project.Length);
|
||||
//Dim projects As String = Encoding.GetEncoding("GBK").GetString(project)
|
||||
string projects = $"{project[0] + project[1] * 256}";
|
||||
projects = projects.Replace("\0", "");
|
||||
|
||||
byte[] roomId = new byte[4]; //房型Id 4 Bytes
|
||||
Array.Copy(_matchingData, project.Length, roomId, 0, roomId.Length);
|
||||
//Dim roomIds As String = Encoding.GetEncoding("GBK").GetString(roomId)
|
||||
string roomIds = $"{BitConverter.ToUInt32(roomId, 0)}";
|
||||
roomIds = roomIds.Replace("\0", "");
|
||||
|
||||
byte[] version = new byte[20]; //版本号 20 Bytes
|
||||
Array.Copy(_matchingData, (project.Length + roomId.Length), version, 0, version.Length);
|
||||
string versions = Encoding.GetEncoding("GBK").GetString(version);
|
||||
versions = versions.Replace("\0", "");
|
||||
|
||||
byte[] mcu = new byte[16]; //MCU型号 16 Bytes
|
||||
Array.Copy(_matchingData, (project.Length + roomId.Length + version.Length), mcu, 0, mcu.Length);
|
||||
string mcus = Encoding.GetEncoding("GBK").GetString(mcu);
|
||||
mcus = mcus.Replace("\0", "");
|
||||
|
||||
byte[] central = new byte[16]; //中控型号 16 Bytes
|
||||
Array.Copy(_matchingData, (project.Length + roomId.Length + version.Length + mcu.Length), central, 0, central.Length);
|
||||
string centrals = Encoding.GetEncoding("GBK").GetString(central);
|
||||
centrals = centrals.Replace("\0", "");
|
||||
|
||||
byte[] remark = new byte[64]; //备注 64 Bytes
|
||||
Array.Copy(_matchingData, (project.Length + roomId.Length + version.Length + mcu.Length + central.Length), remark, 0, remark.Length);
|
||||
string remarks = Encoding.GetEncoding("GBK").GetString(remark);
|
||||
remarks = remarks.Replace("\0", "");
|
||||
|
||||
return centrals;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 加载hex文件数据
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
private bool LoadDataFromFile(Stream path)
|
||||
{
|
||||
Array.Clear(_LoadHexFileData, 0, _LoadHexFileData.Length);
|
||||
try
|
||||
{
|
||||
//System.IO.Stream fs = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read);
|
||||
if (path.Length <= _loadFileSize)
|
||||
{
|
||||
path.Read(_LoadHexFileData, 0, (int)path.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
path.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return HexFileToData(_LoadHexFileData, _LoadDataBuff, ref _LoadEndAddr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private string HexByteStr(byte hexByte)
|
||||
{
|
||||
if (hexByte < 16)
|
||||
{
|
||||
return "0" + Convert.ToString(hexByte, 16).ToUpper();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Convert.ToString(hexByte, 16).ToUpper();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 解析Hex文件到Byte数组
|
||||
/// </summary>
|
||||
/// <param name="hexBuffer"></param>
|
||||
/// <param name="dataBuffer"></param>
|
||||
/// <param name="endAddr"></param>
|
||||
/// <returns></returns>
|
||||
private bool HexFileToData(byte[] hexBuffer, byte[] dataBuffer, ref int endAddr)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
//行数
|
||||
int LineCnt = 0;
|
||||
int DataType_00_Idx = 0;
|
||||
|
||||
//清空数据缓存区域
|
||||
for (i = 0; i < dataBuffer.Length; i++)
|
||||
{
|
||||
dataBuffer[i] = 0xFF;
|
||||
}
|
||||
|
||||
//本行数据缓存
|
||||
byte[] dataStrBuf = new byte[32];
|
||||
byte[] dataValBuf = new byte[16];
|
||||
|
||||
//首地址标记
|
||||
bool headAddrFlag = true;
|
||||
|
||||
//本行地址值
|
||||
int tmpLineAdd = 0;
|
||||
|
||||
//偏移地址 0x04 数据类型指示偏移地址
|
||||
int LineAddOffestBase = 0;
|
||||
|
||||
//结束地址
|
||||
endAddr = 0;
|
||||
|
||||
byte[] flashAddressBuf = new byte[4];
|
||||
int flashAddress = 0;
|
||||
|
||||
//INSTANT C# NOTE: The ending condition of VB 'For' loops is tested only on entry to the loop. Instant C# has created a temporary variable in order to use the initial value of hexBuffer.Length for every iteration:
|
||||
int tempVar = hexBuffer.Length;
|
||||
for (i = 0; i < tempVar; i++)
|
||||
{
|
||||
//首先找到冒号
|
||||
if (hexBuffer[i] == 0x3A) //&H3A = ":"
|
||||
{
|
||||
LineCnt += 1;
|
||||
//B0:数据长度
|
||||
int dataLen = (StrToHex(hexBuffer[i + 1]) * 16 + StrToHex(hexBuffer[i + 2]));
|
||||
if (dataLen > 0)
|
||||
{
|
||||
//By:CheckSum
|
||||
byte checkSum = (byte)(StrToHex(hexBuffer[i + 9 + dataLen * 2]) * 16 + StrToHex(hexBuffer[i + 10 + dataLen * 2]));
|
||||
|
||||
//取出整行数据
|
||||
byte[] rowDataStrBuf = new byte[42];
|
||||
byte[] rowDataValBuf = new byte[21];
|
||||
int rowLen = 0;
|
||||
Array.Clear(rowDataStrBuf, 0, 42);
|
||||
Array.Clear(rowDataValBuf, 0, 21);
|
||||
|
||||
rowLen = (dataLen * 2) + 10;
|
||||
Array.Copy(hexBuffer, i + 1, rowDataStrBuf, 0, rowLen);
|
||||
StrToHex(rowDataValBuf, rowDataStrBuf, Convert.ToUInt16(rowLen / 2.0));
|
||||
|
||||
//using System;
|
||||
|
||||
int tempVar2 = Convert.ToInt32(rowLen / 2.0);
|
||||
byte tempCheckSum = GetSumChecks(rowDataValBuf, ref tempVar2);
|
||||
|
||||
if (tempCheckSum != 0xFF)
|
||||
{
|
||||
return false; //CheckSum校验不通过,返回错误
|
||||
}
|
||||
|
||||
//B4~Bx:数据内容
|
||||
Array.Clear(dataStrBuf, 0, 32);
|
||||
Array.Clear(dataValBuf, 0, 16);
|
||||
Array.Copy(hexBuffer, i + 9, dataStrBuf, 0, dataLen * 2);
|
||||
StrToHex(dataValBuf, dataStrBuf, (UInt16)dataLen);
|
||||
}
|
||||
|
||||
//B1~B2:取出地址位的值
|
||||
Array.Copy(hexBuffer, i + 3, flashAddressBuf, 0, 4);
|
||||
|
||||
//本行地址取出来放在 flashAddress中’
|
||||
UInt16 tempVar3 = (UInt16)tmpLineAdd;
|
||||
StrToHex(ref tempVar3, flashAddressBuf);
|
||||
tmpLineAdd = tempVar3;
|
||||
flashAddress = LineAddOffestBase + tmpLineAdd;
|
||||
|
||||
//B3:数据类型
|
||||
var dataType = StrToHex(hexBuffer[i + 8]);
|
||||
switch (dataType)
|
||||
{
|
||||
case 0: //数据记录
|
||||
DataType_00_Idx = DataType_00_Idx + 1;
|
||||
//将第一个00类型数据的地址作为起始地址, 保存到 _HexStart_C1
|
||||
if (DataType_00_Idx == 1)
|
||||
{
|
||||
_HexStart_C1 = flashAddress;
|
||||
_matchingValue = _matchingAddr - _HexStart_C1;
|
||||
}
|
||||
Array.Copy(dataValBuf, 0, dataBuffer, flashAddress, dataLen);
|
||||
endAddr = flashAddress + dataLen;
|
||||
break;
|
||||
case 1: //文件结束
|
||||
if (endAddr == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
//break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 5: //扩展段地址, 开始段地址, 开始线性地址’
|
||||
continue;
|
||||
case 4: //扩展线性地址
|
||||
if (dataLen == 2)
|
||||
{
|
||||
LineAddOffestBase = (dataValBuf[0] * 256 + dataValBuf[1]) * 65536;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false; //确认DataLen必须是2,否则报错
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static void StrToHex(byte[] pbDest, byte[] pbSrc, UInt16 nLen)
|
||||
{
|
||||
byte h1 = 0;
|
||||
byte h2 = 0;
|
||||
byte s1 = 0;
|
||||
byte s2 = 0;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < nLen; i++)
|
||||
{
|
||||
h1 = pbSrc[2 * i];
|
||||
h2 = pbSrc[2 * i + 1];
|
||||
|
||||
s1 = (byte)(toupper(h1) - 0x30);
|
||||
if (s1 > 9)
|
||||
{
|
||||
s1 -= 7;
|
||||
}
|
||||
|
||||
s2 = (byte)(toupper(h2) - 0x30);
|
||||
if (s2 > 9)
|
||||
{
|
||||
s2 -= 7;
|
||||
}
|
||||
|
||||
pbDest[i] = (byte)(s1 * 16 + s2);
|
||||
}
|
||||
}
|
||||
|
||||
private void StrToHex(ref UInt16 pbDest, byte[] pbSrc)
|
||||
{
|
||||
byte[] pBufDest = new byte[2];
|
||||
byte h1 = 0;
|
||||
byte h2 = 0;
|
||||
byte s1 = 0;
|
||||
byte s2 = 0;
|
||||
UInt16 i = 0;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
h1 = pbSrc[2 * i];
|
||||
h2 = pbSrc[2 * i + 1];
|
||||
|
||||
s1 = (byte)(toupper(h1) - 0x30);
|
||||
if (s1 > 9)
|
||||
{
|
||||
s1 -= 7;
|
||||
}
|
||||
|
||||
s2 = (byte)(toupper(h2) - 0x30);
|
||||
if (s2 > 9)
|
||||
{
|
||||
s2 -= 7;
|
||||
}
|
||||
|
||||
pBufDest[i] = (byte)(s1 * 16 + s2);
|
||||
}
|
||||
//pbDest = (pBufDest(0) << 8) + pBufDest(1)
|
||||
pbDest = (UInt16)(pBufDest[0] * 256 + pBufDest[1]);
|
||||
}
|
||||
|
||||
private byte StrToHex(/*object*/ int src)
|
||||
{
|
||||
if (Convert.ToInt32(src) >= 0x30 && Convert.ToInt32(src) <= 0x39)
|
||||
{
|
||||
return Convert.ToByte((src - 0x30));
|
||||
}
|
||||
else if (Convert.ToInt32(src) >= 0x41 && Convert.ToInt32(src) <= 0x46)
|
||||
{
|
||||
return Convert.ToByte((src - 0x41 + 10));
|
||||
}
|
||||
else if (Convert.ToInt32(src) >= 0x61 && Convert.ToInt32(src) <= 0x66)
|
||||
{
|
||||
return Convert.ToByte((src - 0x61 + 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
public static byte toupper(byte val)
|
||||
{
|
||||
if (val >= 0x61 && val <= 0x7A)
|
||||
{
|
||||
return (byte)(val - 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 和校验
|
||||
/// 求Byte数组的和校验
|
||||
/// </summary>
|
||||
/// <param name="dataPacket">Byte数组</param>
|
||||
/// <returns></returns>
|
||||
public byte GetSumChecks(byte[] dataPacket, ref int len)
|
||||
{
|
||||
int sum = 0;
|
||||
for (var idx = 0; idx < len; idx++)
|
||||
{
|
||||
sum += dataPacket[idx];
|
||||
sum &= 0xFF;
|
||||
}
|
||||
|
||||
sum = (~sum) & 0xFF;
|
||||
return (byte)sum;
|
||||
}
|
||||
|
||||
|
||||
//&H
|
||||
public byte[] GetStringToDataByte(string str)
|
||||
{
|
||||
List<byte> dataList = new List<byte>();
|
||||
|
||||
for (int index = 0; index < str.Length; index += 2)
|
||||
{
|
||||
dataList.Add(Convert.ToByte($"{str.Substring(index, 2)}"));
|
||||
}
|
||||
return dataList.ToArray();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 16进制原码字符串转字节数组
|
||||
/// </summary>
|
||||
/// <param name="hexString">"AABBCC"或"AA BB CC"格式的字符串</param>
|
||||
/// <returns></returns>
|
||||
public static byte[] ConvertHexStringToBytes(string hexString)
|
||||
{
|
||||
hexString = hexString.Replace(" ", "");
|
||||
if (hexString.Length % 2 != 0)
|
||||
{
|
||||
throw new ArgumentException("参数长度不正确,必须是偶数位。");
|
||||
}
|
||||
byte[] returnBytes = new byte[hexString.Length / 2];
|
||||
for (int i = 0; i < returnBytes.Length; i++)
|
||||
{
|
||||
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
|
||||
}
|
||||
|
||||
return returnBytes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Byte[] 转 File
|
||||
/// </summary>
|
||||
/// <param name="fileData"></param>
|
||||
public void ByteToFile(byte[] fileData)
|
||||
{
|
||||
string fileName = DateTime.Now.ToString("yyyyMMddhhmmss") + ".bin";
|
||||
string dirPath = @"D:\测试";
|
||||
|
||||
if (!Directory.Exists(dirPath))
|
||||
Directory.CreateDirectory(dirPath);
|
||||
|
||||
string filePath = Path.Combine(dirPath, fileName);
|
||||
FileStream fileStream = new(filePath, FileMode.Create);
|
||||
fileStream.Write(fileData, 0, fileData.Length);
|
||||
fileStream.Close();
|
||||
}
|
||||
|
||||
|
||||
public string HexStringToBytes(int set)
|
||||
{
|
||||
string str = set.ToString("X6");
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// Name: CRC-16/IBM x16+x15+x2+1
|
||||
/// Poly: 0x8005
|
||||
/// Init: 0x0000
|
||||
/// Refin: true
|
||||
/// Refout: true
|
||||
/// Xorout: 0x0000
|
||||
///*************************************************************************
|
||||
public static byte[] Crc16(byte[] buffer, int start = 0, int len = 0)
|
||||
{
|
||||
if (buffer == null || buffer.Length == 0) return null;
|
||||
if (start < 0) return null;
|
||||
if (len == 0) len = buffer.Length - start;
|
||||
int length = start + len;
|
||||
if (length > buffer.Length) return null;
|
||||
ushort crc = 0;// Initial value
|
||||
for (int i = start; i < length; i++)
|
||||
{
|
||||
crc ^= buffer[i];
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
if ((crc & 1) > 0)
|
||||
crc = (ushort)((crc >> 1) ^ 0xA001);// 0xA001 = reverse 0x8005
|
||||
else
|
||||
crc = (ushort)(crc >> 1);
|
||||
}
|
||||
}
|
||||
byte[] ret = BitConverter.GetBytes(crc);
|
||||
Array.Reverse(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public static int NetCRC16_Data(byte[] aStr, int len, int crc_id)
|
||||
{
|
||||
int xda, xdapoly;
|
||||
int i, j, xdabit;
|
||||
xda = 0xFFFF;
|
||||
xdapoly = 0xA001; // (X**16 + X**15 + X**2 + 1)
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if ((i == crc_id) || (i == (crc_id + 1)))
|
||||
{
|
||||
xda ^= 0x00;
|
||||
}
|
||||
else
|
||||
{
|
||||
xda ^= aStr[i];
|
||||
}
|
||||
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
xdabit = (byte)(xda & 0x01);
|
||||
xda >>= 1;
|
||||
if (xdabit!=0) xda ^= xdapoly;
|
||||
}
|
||||
}
|
||||
return xda;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user