|
本帖最后由 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[i] = 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[i]);
- byte[] buffer_Temp = new byte[binFileData.Count];
- for (int tmp0 = 0; tmp0 < binFileData.Count; tmp0++)
- {
- buffer_Temp[tmp0] = binFileData[tmp0];
- }
- 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("文件转换完成! ", "提示");
- }
- }
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
阿莫论坛才是最爱国的,关心国家的经济、社会的发展、担心国家被别国牵连卷入战争、知道珍惜来之不易的和平发展,知道师夷之长,关注世界的先进文化与技术,也探讨中国文化的博大精深,也懂得警惕民粹主义的祸国殃民等等等等,无不是爱国忧民的表现。(坛友:tianxian)
|