📄 hextobin.cpp
字号:
//获取本行的数据类型
if( OP_FAIL == AsciiToHex(l_buf[7],l_buf[8],&g_hex.type) )
{
printf("传入的hex文件格式错误5,转换终止!\n");
exit(3);
}
///////////////////////////////////////////////////////////////////
//判断数据类型是否合法
if( 0x00 != g_hex.type && 0x01 != g_hex.type && 0x02 != g_hex.type && 0x04 != g_hex.type)
{
printf("传入的hex文件格式错误6,转换终止!\n");
exit(3);
}
//////////////////////////////////////////////////////////////////
//获取数据
if( g_hex.length > 0 )
{
for(j=0;j<g_hex.length;j++)
{
if( OP_FAIL == AsciiToHex(l_buf[2*j+9],l_buf[2*j+10],&g_hex.data[j]) )
{
printf("传入的hex文件格式错误7,转换终止!\n");
exit(3);
}
}
}
i=9+2*g_hex.length;
//////////////////////////////////////////////////////////////////
//获取校验和
if( OP_FAIL == AsciiToHex(l_buf[i],l_buf[i+1],&g_hex.check) )
{
printf("传入的hex文件格式错误8,转换终止!\n");
exit(3);
}
//////////////////////////////////////////////////////////////////
//判断校验和是否正确
l_sum =g_hex.length;
l_sum +=(g_hex.offset>>8);
l_sum +=(g_hex.offset&0xFF);
l_sum +=g_hex.type;
l_sum +=g_hex.check;
for(i=0;i<g_hex.length;i++)
{
l_sum +=g_hex.data[i];
}
//校验和必然是256的整数倍,如果有御书则认为校验和失败
if( l_sum & 0xFF )
{
printf("传入的hex文件校验和错误9,转换终止!\n");
exit(3);
}
//////////////////////////////////////////////////////////////////
//根据数据类型决定是否写数据到bin文件中
i=0;
l_addr=0;
switch( g_hex.type )
{
case 0x00: //本行的数据类型为“数据记录”
//本行所从属的数据类型为“数据记录”
if( 0x00 == g_hex.format )
{
l_addr =(INT32U)g_hex.offset;
}
//本行所从属的数据类型为“扩展段地址记录”(HEX86)--20位地址
else if( 0x02 == g_hex.format)
{
l_addr =((INT32U)g_hex.address<<4)+(INT32U)g_hex.offset;
}
//本行所从属的数据类型为“扩展线性地址记录”(HEX386)--32位地址
else if( 0x04 == g_hex.format)
{
l_addr =((INT32U)g_hex.address<<8)+(INT32U)g_hex.offset;
}
//文件结束
else
{
i=1;
break;
}
//文件重定位
if( 0 == fseek(f_bin,l_addr,SEEK_SET))
{
//写入数据到bin文件中
if( g_hex.length > 0)
{
l_num =fwrite(g_hex.data,sizeof(INT8U),g_hex.length,f_bin);
//判断写操作是否成功
if( l_num != g_hex.length ) i =2;
}
}
break;
case 0x01: //本行的数据类型为“文件结束记录”
//文件结束记录的数据个数一定是0x00
if( g_hex.length == 0x00 ) i =1;
g_hex.format =0x01;
break;
case 0x02: //本行的数据类型为“扩展段地址记录”
//扩展段地址记录的数据个数一定是0x02
if( g_hex.length != 0x02 ) i =3;
//扩展段地址记录的地址一定是0x0000
if( g_hex.offset != 0x0000) i =3;
//更改hex从属的数据类型
g_hex.format =0x02;
//获取段地址
g_hex.address =(((INT16U)g_hex.data[0]<<8)|g_hex.data[1]);
break;
case 0x04: //本行的数据类型为“扩展线性地址记录”
//扩展线性地址记录中的数据个数一定是0x02
if( g_hex.length != 0x02 ) i =4;
//扩展线性地址记录的地址一定是0x0000
if( g_hex.offset != 0x0000) i =4;
//更改hex从属的数据类型
g_hex.format =0x04;
//获取高16位地址
g_hex.address =(((INT16U)g_hex.data[0]<<8)|g_hex.data[1]);
break;
}
//如果出现异常或文件结束退出循环
if( i > 0 )
{
if( 1 == i )
{
printf("Hex转bin成功,正常退出!\n");
break;
}
if( 2 == i )
{
printf("写入到bin文件失败,异常退出\n");
break;
}
if( 3 == i )
{
printf("扩展段地址记录数据格式出错,异常退出\n");
break;
}
if( 4 == i )
{
printf("扩展线性地址记录数据格式出错,异常退出\n");
break;
}
}
//记录地址中的最大值
if( g_max_addr < l_addr ) g_max_addr =l_addr;
}
}
printf("Hex中的最大地址为:0x%08x.\n",g_max_addr);
//关闭文件
fclose(f_hex);
fclose(f_bin);
}
/*****************************************************************************************
*函数名称:MemcopyStr()
*入口参数:源指针、目的指针、数据个数
*出口参数:无
*功能描述:拷贝指定数量的数据到目的指针。
*抛出异常:无
******************************************************************************************/
void MemcopyStr(const INT8S *p_source,INT8S *p_dest,INT8U num)
{
while(num--)
{
*p_dest++ =toupper(*p_source++);
}
}
/*****************************************************************************************
*函数名称:main()
*入口参数:参数个数、参数列表
*出口参数:无
*功能描述:Hex转bin文件的具体实现函数。
*抛出异常:1.
******************************************************************************************/
void main(int argc,char **argv)
{
INT8S p_str[20];
INT8U hexdata; //ascii转为Hex后的数据
INT8U verify_type; //校验类型
INT8U filldata[100];//填充字符
INT8U filllength=0; //填充字符的长度
/////////////////////////////////////////////////////////////////////////////////////
//判断传入的参数个数是否满足要求
if( argc <= 1 )
{
DispHelp();
exit(1);
}
//参数太少给出提示后退出
if( argc < 3 )
{
printf("没有指定输入或输出文件的名称,转换失败!\n");
exit(2);
}
////////////////////////////////////////////////////////////////////////////////////
//判断是否需要加入校验和
if( argc < 4 )
{
//将输入的hex格式文件转bin文件
HexToBin(argv[1],argv[2],filllength,filldata);
}
else
{
//判断校验和类型
MemcopyStr(argv[3],p_str,sizeof(argv[3]));
//加入结尾符号
p_str[4]='\0';
//显示校验类型
if(0 == strcmp(p_str,"/BCC"))
{
printf("加入的校验和类型为:BCC(异或运算).\n");
verify_type =BCC;
}
else if( 0 == strcmp(p_str,"/CRC"))
{
printf("加入的校验和类型为:CRC(欧洲标准).\n");
verify_type =CRC;
}
else
{
printf("暂不支持此种校验类型,校验和将不增加!\n");
verify_type =0xFF;
}
//////////////////////////////////////////////////////////////////////////////////
//获取校验和存放的地址
if( verify_type != 0xFF)
{
if( OP_OK == AsciiToHex(argv[3][5],argv[3][6],&hexdata))
{
verify_addr =hexdata<<24;
}
else
{
printf("输入的校验和存放地址中包含非法字符,异常终止");
exit(4);
}
//继续判断
if( OP_OK == AsciiToHex(argv[3][7],argv[3][8],&hexdata))
{
verify_addr |=hexdata<<16;
}
else
{
printf("输入的校验和存放地址中包含非法字符,异常终止");
exit(4);
}
//继续判断
if( OP_OK == AsciiToHex(argv[3][9],argv[3][10],&hexdata))
{
verify_addr |=hexdata<<8;
}
else
{
printf("输入的校验和存放地址中包含非法字符,异常终止");
exit(4);
}
//继续判断
if( OP_OK == AsciiToHex(argv[3][11],argv[3][12],&hexdata))
{
verify_addr |=hexdata<<0;
}
else
{
printf("输入的校验和存放地址中包含非法字符,异常终止");
exit(4);
}
//显示校验和存放的地址
printf("校验和存放的地址为:0x%08x.\n",verify_addr);
//判断地址是否合法
if( g_max_addr >= verify_addr )
{
printf("校验和存放地址小于二进制代码存放的最大地址,异常终止.\n");
exit(4);
}
else if( verify_addr > 0xFFFFFFFC )
{
printf("校验和存放的最大地址空间为:0xFFFFFFFC,异常终止.\n");
exit(4);
}
}
/////////////////////////////////////////////////////////////////////////////////
//获取填充的数据个数和指针
if( argc >= 5 )
{
if( OP_OK == AsciiToHex(argv[4][0],argv[4][1],&filllength))
{
printf("填充的数据长度为:%d.\n",filllength);
//判断填充的数据长度是否满足要求
if( filllength >= 100 )
{
printf("填充字符的数据太多(限定100),异常终止.\n");
}
}
else
{
printf("输入的填充数据长度不合法,操作异常终止.\n");
exit(4);
}
//判断数据长度和数据个数是否满足要求
if( argc != (filllength+5) )
{
printf("传入的数据个数不满足要求,操作异常终止!.\n");
exit(4);
}
//////////////////////////////////////////////////////////////////////////////
//获取填充的数据
for(INT8U i=0,j=5;i<filllength;i++,j++)
{
if( OP_FAIL == AsciiToHex(argv[j][0],argv[j][1],&filldata[i]))
{
printf("填充的数据中包含非法字符,操作异常终止.\n");
exit(5);
}
}
}
//////////////////////////////////////////////////////////////////////////////////
//进行Hex转bin
HexToBin(argv[1],argv[2],filllength,filldata);
//////////////////////////////////////////////////////////////////////////////////
//加入校验和 -- 合法的校验类型才允许加入
if(verify_type != 0xFF )
{
AddVerifyToBin(argv[2],verify_type);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -