(开源-C#)分享一个自己写的HEX2BIN源代码
本帖最后由 SUPER_CRJ 于 2019-10-15 12:44 编辑RT
C#写的,把HEX转换为bin文件。没有用的部分用的是0填充。
大神轻拍。
解决昨天提到的,部分HEX文件没有按照地址顺序排列。
https://www.amobbs.com/thread-5720131-1-1.html
另外:我从网上下载几个HEX2BIN文件都不能解析地址乱的问题,我写的这个可以解决。
(具体思路是:定义一个大数组,数组地址就相当于HEX文件地址,然后进行解析填充,最后再进行截断生成一个bin文件)
(另外有帖子提到,可以先进行HEX地址排序,但是如果存在线性附加地址的话,实现比较麻烦,排序出来可能就乱了。)
可以使用到STM8/STM32生成的HEX生成BIN文件。
s_path = txb_SouceBinPath.Text;
FileInfo myFile = new FileInfo(s_path);
string fileExtension = Path.GetExtension(myFile.FullName).ToLower();// 用来获取扩展名,而且变为小写返回,因为扩展名会存在大小写的情况
if (fileExtension == ".hex")// 日后会增加各种文件的支持,hex文件的解析需要用点时间
{
FileStream fs;
try
{
fs = new FileStream(s_path, FileMode.Open);//open file
}
catch
{
MessageBox.Show("文件访问错误,请检查是否设置读保护以及文件是否被占用!", "错误");
return;
}
StreamReader HexReader = new StreamReader(fs); //读取数据流
string szLine = "";// 因为Hex文件是以每行为单位的,所以也就是说读取可以用读取行的方式来操作
//string szHex = ""; // 这个用的是string类别
StringBuilder szHex0 = new StringBuilder();// 比直接读取string要快许多。
startAddress = 0xFFFFFFFF;// 最大的地址,需要一直减小
endAddress = 0;// 最大的地址,需要一直减小
UInt32 currentAddress = 0;// 当前地址,用于严谨的判断:防止地址不连续的时候出现,因为会有人使用Boot+App,然后拼接的形式生成HEX文件,用于下载。
UInt32 currentAddressEnd = 0;
UInt32 addressPrefix = 0; // 当前地址前缀,因为HEX文件的特性,使得前缀会被另外的放置。
while (true)
{
szLine = HexReader.ReadLine();
if (szLine == null) { break; } //读取完毕,退出
if (szLine.Substring(0, 1) == ":") //判断首字符是”:”,理论是这个是一定会的
{
switch (szLine.Substring(8, 1))
{
case "0":// 数据纪录,表示是数据,注意其中含有2个字节地址。
{ // 重点处理
currentAddress = addressPrefix + Convert.ToUInt32(szLine.Substring(3, 4), 16);// 找到当前的地址。
currentAddressEnd = currentAddress + Convert.ToUInt32(szLine.Substring(1, 2), 16); //
{
if( currentAddress <= startAddress )
{
startAddress = currentAddress;
}
if( currentAddressEnd >= endAddress )
{
endAddress = currentAddressEnd;
}
}
{// 进行数据填充
for( int i = (int)currentAddress , j = 0 ; i<currentAddressEnd;i++ ,j++)
{
enoughDataFile = Convert.ToByte(szLine.Substring(9+j*2, 2), 16);
}
}
}
break;
case "1":// 文件线束记录
break;
case "4":// 扩展线性地址记录,这个在STM32中遇到过。
addressPrefix = (UInt32)(Convert.ToUInt16(szLine.Substring(9, szLine.Length - 11), 16) << 16);
break;
// 下面几个都没有遇到过!但是到目前为止,只用上面3个也一直没有出过问题。
case "2":// 扩展段地址记录,这个没有遇到到。
// 这个是<<4位,相对于04的<<8位,这个只移动了一半。
addressPrefix = (UInt32)(Convert.ToUInt16(szLine.Substring(9, szLine.Length - 11), 16) << 4);
break;
case "3":// 开始段地址记录,这个没有遇到过。
// 好像用不到
break;
case "5":// 开始线性地址记录,这个没有遇到过。
// 好像用不到
break;
default:
break;
}
}
else
{
break;
}
}
{ // 关闭文件访问
HexReader.Close();
}
{// 处理截断数据
binFileData.Clear();
bindataLen = endAddress - startAddress;
for (UInt32 i = startAddress; i < endAddress; i++)
binFileData.Add(enoughDataFile);
byte[] buffer_Temp = new byte;
for (int tmp0 = 0; tmp0 < binFileData.Count; tmp0++)
{
buffer_Temp = binFileData;
}
tmpSumValue = GetSumOf16Bit(buffer_Temp, binFileData.Count);
// 进行显示操作:
label4.Text = "0x"+ startAddress.ToString("X");
label5.Text = "0x" + endAddress.ToString("X");
label6.Text = "0x" + bindataLen.ToString("X");
label7.Text = "0x" + tmpSumValue.ToString("X");
// 进行文件输出操作。
FileStream fBin = new FileStream(txb_targetBinPath.Text, FileMode.Create);
BinaryWriter BinWrite = new BinaryWriter(fBin);
BinWrite.Write(buffer_Temp, 0, buffer_Temp.Length); //
BinWrite.Flush();//释放缓存
BinWrite.Close();//关闭文件
MessageBox.Show("文件转换完成! ", "提示");
}
}
直接用各种gcc binutils里附带的objcopy不就完了... tomzbj 发表于 2019-10-15 14:28
直接用各种gcc binutils里附带的objcopy不就完了...
是真的不会。。。一直写的嵌入式,C#用的都头疼。这个代码正好集成在配置软件里面 SUPER_CRJ 发表于 2019-10-15 14:44
是真的不会。。。一直写的嵌入式,C#用的都头疼。这个代码正好集成在配置软件里面 ...
objcopy是个可执行文件, 运行objcopy -I ihex -O binary xxx.hex xxx.bin, 就完事了.
mingw里有, winavr里有, stm32的各种yagarto/sourcery之类gcc包里也都有, 随便哪个都能用. 记下2楼的objcopy。 如果不需要BIN文件的加密,或者需要添加其他信息,一般编译器可以直接编译生成BIN文件。 多谢分享,回来再弄个加密,给后面IAP用~ 楼主有才,我一般是用各种烧录下载软件代替。
例如STC-ISP,打开hex文件,然后另存为bin文件。
并不限于烧录软件本身支持的MCU型号。 health 发表于 2019-10-25 11:44
楼主有才,我一般是用各种烧录下载软件代替。
例如STC-ISP,打开hex文件,然后另存为bin文件。
并不限于烧 ...
因为这个要给别人用,你让他自己转换下,他会觉得麻烦,所以还是写吧。 如果遇到空间地址不连续怎么办,新塘的0x0000~0xffff,0x100000~0x1003fff这样你的bin文件怎么处理呢 way2888 发表于 2019-10-25 12:43
如果遇到空间地址不连续怎么办,新塘的0x0000~0xffff,0x100000~0x1003fff这样你的bin文件怎么处理呢 ...
你看我的楼主位说明的方法,这边用的是填充法。没有的地址填充0 SUPER_CRJ 发表于 2019-10-25 13:18
你看我的楼主位说明的方法,这边用的是填充法。没有的地址填充0
要这样填充,那个bin文件就太大了,还是hex格式最灵活 way2888 发表于 2019-10-25 19:10
要这样填充,那个bin文件就太大了,还是hex格式最灵活
bin文件不带有地址信息,除非拆分成两个。 SUPER_CRJ 发表于 2019-10-25 20:59
bin文件不带有地址信息,除非拆分成两个。
如果一个文件拆分成2个文件,而且无法自动识别它的地址的时候,只能通过用文件名称来标识分别,这样反而累赘了,这就是我一直用hex格式而不用bin格式的原因了 多谢分享,正在研究HexToBin. SUPER_CRJ 发表于 2019-10-25 13:18
你看我的楼主位说明的方法,这边用的是填充法。没有的地址填充0
刚看了一下这被挖出来的古文,想建议楼主若可能的话,在于没有用的部分空间应给使用者一个可以输入自订值来进行填充,
或是采用一般预设值的那 0xFF 来填充,因为在于 Flash 或 EPROM 等储存器清为零时就都为 1,故为 Byte 表示时应为 0xFF。
上述仅供楼主参考,谢谢。
多谢分享,
页:
[1]