一、hex文件解析
最近有解析hex文件的需求,肝出来后共享给大家。
bool CUDSOperation::checkCRC(tagHexDataStruct input)
{
int sum = 0;
sum = sum + input.nDataLen;
sum = sum + input.addr1;
sum = sum + input.addr2;
sum = sum + input.type;
for (int i = 0; i < input.nDataLen; i++)
{
sum += input.data[i];
}
sum = sum & 0x00FF;
sum = (0x100 - sum);
sum = sum & 0x00FF;
if (sum == input.check)
{
return true;
}
return false;
}
bool CUDSOperation::convertData()
{
char buf[80]; //hex每一行的数据
Addr addr_t = { 0 }; //32位地址
ifstream in_file(m_strHexName);
if (!in_file.is_open()) {
error_code = 1;
return false;
}
int i_char_num = 0; //读取的行数据长度,最少为11
unsigned int line_number = 1; //记录行数
int file_end_flag = 0; //hex文件结束行(:00000001FF)标志
in_file.getline(buf, 50);
m_vecHexResolve.clear();
while (!in_file.eof()) {
i_char_num = 0;
while (buf[i_char_num] != '\0') {
i_char_num++;
}
if (i_char_num < 11) {
error_code = 2;
error_rec = line_number;
return false;
}
tagHexDataStruct node;
if (buf[0] == ':') //:起始
{
int nLen = Char2IntByte(buf[1] , buf[2]);//数据长度
node.nDataLen = nLen;
node.type = Char2IntByte(buf[7], buf[8]);
node.check = Char2IntByte(buf[9 + nLen*2], buf[9 + nLen*2 + 1]);
node.addr1 = Char2IntByte(buf[3], buf[4]);
node.addr2 = Char2IntByte(buf[5], buf[6]);
addr_t.addr_16.addr_l = Char2ShortInt(buf[3], buf[4], buf[5], buf[6]);//地址
if (0x00 == node.type) { //数据标识
for (int i = 0; i < nLen; i++)
{
node.data[i] = Char2IntByte(buf[9 + i * 2], buf[9 + i * 2 + 1]);
}
}
else if (0x01 == node.type) { //本行为文件结束标识
file_end_flag = 1;
break;
}
else if (0x02 == node.type) { //扩展段地址标识
addr_t.addr_16.addr_h = Char2ShortInt(buf[9], buf[10], buf[11], buf[12]);
}
else if (0x03 == node.type) { //起始段地址标识
addr_t.addr_16.addr_h = Char2ShortInt(buf[9], buf[10], buf[11], buf[12]);
}
else if (0x04 == node.type) { //扩展线性地址标识
addr_t.addr_16.addr_h = Char2ShortInt(buf[9], buf[10], buf[11], buf[12]);
for (int i = 0; i < nLen; i++)
{
node.data[i] = Char2IntByte(buf[9 + i * 2], buf[9 + i * 2 + 1]);
}
}
else if (0x05 == node.type) { //起始线性地址记录标识
addr_t.addr_16.addr_h = Char2ShortInt(buf[9], buf[10], buf[11], buf[12]);
for (int i = 0; i < nLen; i++)
{
node.data[i] = Char2IntByte(buf[9 + i * 2], buf[9 + i * 2 + 1]);
}
}
else {
error_code = FILE_LINE_TYPE_ERROR;
error_rec = line_number;
return false;
}
node.addr = addr_t.addr_32;
checkCRC(node);//校验
//地址转换
if((node.addr & 0xF0000000) == 0xA0000000)
{
node.addr = node.addr & (~0x20000000);//烧写使用地址
}
else
{
//不做操作
}
}
else {
error_code = FILE_LINE_ERROR;
error_rec = line_number;
return false;
}
m_vecHexResolve.emplace_back(node);
in_file.getline(buf, 139);
line_number++;
}
in_file.close();
if (file_end_flag) {
return true;
}
else {
error_code = 7;
error_rec = line_number;
return false;
}
return false;
}
/**
* Char2ShortInt char --> short int(16 bit)
* 将4个字符转换为长度为16位的short int
*
* @param d_4 15-12
* @param d_3 11-8
* @param d_2 7-4
* @param d_1 3-0
*
* @return 16位的short int
*/
unsigned short int CUDSOperation::Char2ShortInt(char d_4, char d_3, char d_2, char d_1)
{
return (Char2Int(d_4) << 12 | Char2Int(d_3) << 8 | Char2Int(d_2) << 4 | Char2Int(d_1));
}
/**
* Char2IntByte char --> short int(8 bit)
* 将2个字符转换为长度为8位的int(short int低8位)
*
* @param d_h 7-4
* @param d_l 3-0
*
* @return short int 低8位有效
*/
unsigned short int CUDSOperation::Char2IntByte(char d_h, char d_l)
{
return (Char2Int(d_h) << 4 | Char2Int(d_l));
}
/**
* Char2Int 将单个字符转换为与之对应的int值
*
* @param ch 字符
*
* @return 转换后的int值,若转换失败则返回0
*
* @error
* FILE_ILLEGAL_CHAR_ERROR 数据转换错误, 非法字符
*/
unsigned short int CUDSOperation::Char2Int(char ch)
{
unsigned short int t;
switch (ch) {
case '0':
t = 0x0;
break;
case '1':
t = 0x1;
break;
case '2':
t = 0x2;
break;
case '3':
t = 0x3;
break;
case '4':
t = 0x4;
break;
case '5':
t = 0x5;
break;
case '6':
t = 0x6;
break;
case '7':
t = 0x7;
break;
case '8':
t = 0x8;
break;
case '9':
t = 0x9;
break;
case 'A':
t = 0xA;
break;
case 'B':
t = 0xB;
break;
case 'C':
t = 0xC;
break;
case 'D':
t = 0xD;
break;
case 'E':
t = 0xE;
break;
case 'F':
t = 0xF;
break;
default:
error_code = FILE_ILLEGAL_CHAR_ERROR;
t = 0;
}
return t;
}
直接上代码了,有需要的自取