BIN,S19,M0T,SREC,HEX文件解析;FileParse(二)之源码解析
简介
- 一、摘要
- 1.描述
- 2.关键字
- 二、为何选择C#解析
- 三、BIN文件解析
- 四、BIN文件生成
- 五、S19,M0T,SREC文件解析
- 六、S19,M0T,SREC文件生成
- 七、HEX文件解析
- 八、HEX文件生成
- 九、源码下载
- 十、其他
- 十一、参考
一、摘要
1.描述
- 本文主要描述的是如何通过使用C#解析常用MCU的刷写格式文件,如Bin,S19,Hex,Mot,Serc。
- 本软编写的语言是基于C#语言,并未使用其他关联的DLL文件,所以不同的电脑之间兼容性很好,不会出现调用异常的问题。
- 郑重申明,关于实现方法,我也是从网上很多地方学习而来,大家若觉得版权问题可以联系我随时删除。
2.关键字
文件解析,C#,Bin,S19,Hex,Mot,Serc。
二、为何选择C#解析
- C#解析文件有很多好用的字符串处理函数,不过其实方式方法都一样,只要知道了解析方法,使用任何语言都是一样轻松的。
三、BIN文件解析
/*-----define---------------------------------*/private const int BLOCK_BUFF_LEN = 83886080;private const byte MOT_LINE_LEN = 16;private const byte HEX_LINE_LEN = 16;/*-----enum and struct------------------------*/private class DataInfo_Type{internal int len;internal uint startAddr;internal uint endAddr;internal byte[] buff;}/*-----variable statement---------------------*/private readonly List<DataInfo_Type> g_DataInfos = new List<DataInfo_Type>();/************************************************ Name :PushDataInfo* Author :WangHu* Function:**** Version :V1.0.0* Data :2022.5.20***********************************************/private void PushDataInfo(uint? startAddr, uint? endAddr, uint? minStartAddr, uint? maxEndAddr, byte[] p_buff, int len){int m = 0; int n = 0;if (minStartAddr == null) { minStartAddr = 0; }if (maxEndAddr == null) { maxEndAddr = 0xFFFFFFFF; }if ((startAddr > maxEndAddr) || (endAddr < minStartAddr)) { return; }if (startAddr < minStartAddr) { m = (int)(minStartAddr - startAddr); }if (endAddr > maxEndAddr) { n = (int)(endAddr - maxEndAddr); }len = len - m - n;DataInfo_Type dataInfo = new DataInfo_Type{len = len,startAddr = (uint)(startAddr + m),endAddr = (uint)(endAddr - n),buff = new byte[len]};CommonLib.Copy(dataInfo.buff, p_buff, m, len);g_DataInfos.Add(dataInfo);}/************************************************ Name :AnalysisBinFile* Author :WangHu* Function:**** Version :V1.0.0* Data :2022.5.20***********************************************/private bool AnalysisBinFile(string path, uint? minStartAddr, uint? maxEndAddr){try{FileStream file = new FileStream(path, FileMode.Open);int lenth = (int)file.Length;if (lenth == 0) { return false; }byte[] data = new byte[BLOCK_BUFF_LEN];uint? startAddr = minStartAddr;if (startAddr == null) { startAddr = 0; }uint? endAddr = (uint?)(startAddr + lenth - 1);_ = file.Read(data, 0, lenth);PushDataInfo(startAddr, endAddr, minStartAddr, maxEndAddr, data, lenth);file.Close();return true;}catch { return false; }}
四、BIN文件生成
/************************************************ Name :StorageBinFile* Author :WangHu* Function:**** Version :V1.0.0* Data :2022.5.20***********************************************/private bool StorageBinFile(string path, uint startAddr, byte[] p_buff, int len){try{Stream file = new FileStream(path, FileMode.Create);BinaryWriter binWriter = new BinaryWriter(file, Encoding.Unicode);binWriter.Write(p_buff, (int)startAddr, len);binWriter.Close();file.Close();return true;}catch { return false; }}
五、S19,M0T,SREC文件解析
/************************************************ Name :MotCheckSum* Author :WangHu* Function:**** Version :V1.0.0* Data :2022.5.20***********************************************/private byte MotCheckSum(byte[] buff, int len){byte ret = 0x00;for (int i = 0; i < len; i++) { ret += buff[i]; }return (byte)(0xFF - ret);}/************************************************ Name :AnalysisMotFile* Author :WangHu* Function:**** Version :V1.0.0* Data :2022.5.20***********************************************/private bool AnalysisMotFile(string path, uint? minStartAddr, uint? maxEndAddr, List<string> ignoreLines){int lenth = 0;uint? startAddr = null;uint? endAddr = null;byte[] data = new byte[BLOCK_BUFF_LEN];StreamReader reader = new StreamReader(path);while (true){string line = reader.ReadLine();if (line == null) { break; }if (line == string.Empty) { continue; }if (ignoreLines != null) { foreach (string str in ignoreLines) { if (str == line.Replace(" ", "")) { continue; } } }string type = line.Substring(0, 2);int len = (line.Length / 2) - 1;if (len != (Convert.ToInt32(line.Substring(2, 2), 16) + 1)){reader.Close();reader.Dispose();return false;}byte[] buff = new byte[256];for (int i = 0; i < len; i++) { buff[i] = Convert.ToByte(line.Substring((i + 1) * 2, 2), 16); }if (buff[len - 1] != MotCheckSum(buff, len - 1)){reader.Close();reader.Dispose();return false;}uint address;switch (type){case "S1":address = 0;address |= ((uint)buff[1]) << 8;address |= ((uint)buff[2]) << 0;if (startAddr == null) { startAddr = address; }if ((endAddr != null) && (address != (endAddr + 1))){PushDataInfo(startAddr, endAddr, minStartAddr, maxEndAddr, data, lenth);lenth = 0;startAddr = address;}endAddr = address + (uint)(len - 4) - 1;CommonLib.Copy(data, lenth, buff, 3, len - 4);lenth += len - 4;break;case "S2":address = 0;address |= ((uint)buff[1]) << 16;address |= ((uint)buff[2]) << 8;address |= ((uint)buff[3]) << 0;if (startAddr == null) { startAddr = address; }if ((endAddr != null) && (address != (endAddr + 1))){PushDataInfo(startAddr, endAddr, minStartAddr, maxEndAddr, data, lenth);lenth = 0;startAddr = address;}endAddr = address + (uint)(len - 5) - 1;CommonLib.Copy(data, lenth, buff, 4, len - 5);lenth += len - 5;break;case "S3":address = 0;address |= ((uint)buff[1]) << 24;address |= ((uint)buff[2]) << 16;address |= ((uint)buff[3]) << 8;address |= ((uint)buff[4]) << 0;if (startAddr == null) { startAddr = address; }if ((endAddr != null) && (address != (endAddr + 1))){PushDataInfo(startAddr, endAddr, minStartAddr, maxEndAddr, data, lenth);lenth = 0;startAddr = address;}endAddr = address + (uint)(len - 6) - 1;CommonLib.Copy(data, lenth, buff, 5, len - 6);lenth += len - 6;break;case "S7":case "S8":case "S9":break;default:break;}}if (lenth != 0) { PushDataInfo(startAddr, endAddr, minStartAddr, maxEndAddr, data, lenth); }reader.Close();reader.Dispose();return true;}
六、S19,M0T,SREC文件生成
/************************************************ Name :StorageMotFile* Author :WangHu* Function:**** Version :V1.0.0* Data :2022.5.20***********************************************/private bool StorageMotFile(string path, uint? startAddr, byte[] p_buff, int len){try{int lenth;int block = len / MOT_LINE_LEN;byte[] buff = new byte[256];if (startAddr == null) { startAddr = 0x00; }StreamWriter writeFile = new StreamWriter(path);string str = "S011000000486578766965772056312E3038D1";writeFile.WriteLine(str);if ((len % MOT_LINE_LEN) != 0) { block += 1; }byte addrLen = startAddr > 0xFFFFFF ? (byte)4 : (byte)3;for (int i = 0; i < block; i++){for (int j = 0; j < addrLen; j++) { buff[j + 1] = (byte)((startAddr + (i * MOT_LINE_LEN)) >> ((addrLen - j - 1) * 8)); }lenth = ((i + 1) * MOT_LINE_LEN) > len ? len - (i * MOT_LINE_LEN) : MOT_LINE_LEN;buff[0] = (byte)(lenth + addrLen + 1);CommonLib.Copy(buff, addrLen + 1, p_buff, MOT_LINE_LEN * i, lenth);buff[lenth + addrLen + 1] = MotCheckSum(buff, lenth + addrLen + 1);str = "S" + Convert.ToString(addrLen - 1, 16);str += CommonLib.ToStr(buff, lenth + addrLen + 2).Replace(" ", "");writeFile.WriteLine(str);}buff[0] = (byte)(addrLen + 1);CommonLib.Fill(buff, 1, 0xFF, 4);buff[addrLen + 1] = MotCheckSum(buff, addrLen + 1);str = "S" + Convert.ToString(11 - addrLen, 16);str += CommonLib.ToStr(buff, addrLen + 2).Replace(" ", "");writeFile.WriteLine(str);writeFile.Flush();writeFile.Close();return true;}catch { return false; }}
七、HEX文件解析
/************************************************ Name :HexCheckSum* Author :WangHu* Function:**** Version :V1.0.0* Data :2022.5.20***********************************************/private byte HexCheckSum(byte[] buff, int len){byte ret = 0x00;for (int i = 0; i < len; i++) { ret += buff[i]; }return (byte)(0x100 - ret);}/************************************************ Name :AnalysisBinFile* Author :WangHu* Function:**** Version :V1.0.0* Data :2022.5.20***********************************************/private bool AnalysisHexFile(string path, uint? minStartAddr, uint? maxEndAddr, List<string> ignoreLines){int lenth = 0;uint? deviationAddr = null;uint? startAddr = null;uint? endAddr = null;byte[] data = new byte[BLOCK_BUFF_LEN];StreamReader reader = new StreamReader(path);while (true){string line = reader.ReadLine();if (line == null) { break; }if (line == string.Empty) { continue; }if (ignoreLines != null) { foreach (string str in ignoreLines) { if (str == line.Replace(" ", "")) { continue; } } }if (line.Substring(0, 1) != ":"){reader.Close();reader.Dispose();return false;}byte type = Convert.ToByte(line.Substring(7, 2), 16);int len = line.Length / 2;if (len != (Convert.ToInt32(line.Substring(1, 2), 16) + 5)){reader.Close();reader.Dispose();return false;}byte[] buff = new byte[80];for (int i = 0; i < len; i++) { buff[i] = Convert.ToByte(line.Substring((i * 2) + 1, 2), 16); }if (buff[len - 1] != HexCheckSum(buff, len - 1)){reader.Close();reader.Dispose();return false;}switch (type){case 0x00:if (deviationAddr == null) { deviationAddr = 0x00; }uint? address = deviationAddr;address += ((uint)buff[1]) << 8;address += ((uint)buff[2]) << 0;if (startAddr == null) { startAddr = address; }if ((endAddr != null) && (address != (endAddr + 1))){PushDataInfo(startAddr, endAddr, minStartAddr, maxEndAddr, data, lenth);lenth = 0;startAddr = address;}endAddr = address + (uint)(len - 5) - 1;CommonLib.Copy(data, lenth, buff, 4, len - 5);lenth += len - 5;break;case 0x01:break;case 0x02:deviationAddr = 0x00;for (int i = 0; i < len - 5; i++){deviationAddr <<= 8;deviationAddr += buff[i + 4];}deviationAddr <<= 4;break;case 0x03:break;case 0x04:deviationAddr = 0x00;for (int i = 0; i < len - 5; i++){deviationAddr <<= 8;deviationAddr += buff[i + 4];}deviationAddr <<= 16;break;case 0x05:break;default:break;}}if (lenth != 0) { PushDataInfo(startAddr, endAddr, minStartAddr, maxEndAddr, data, lenth); }reader.Close();reader.Dispose();return true;}
八、HEX文件生成
/************************************************ Name :StorageHexFile* Author :WangHu* Function:**** Version :V1.0.0* Data :2022.5.20***********************************************/private bool StorageHexFile(string path, uint? startAddr, byte[] p_buff, int len){try{ushort? address = null;uint? deviationAddr = null;int block = len / HEX_LINE_LEN;byte[] buff = new byte[256];if (startAddr == null) { startAddr = 0x00; }StreamWriter writeFile = new StreamWriter(path);if ((len % HEX_LINE_LEN) != 0) { block += 1; }string str;for (int i = 0; i < block; i++){if ((address == null) || (address == 0x00)){buff[0] = 0x02;buff[1] = 0x00;buff[2] = 0x00;buff[3] = startAddr > 0xFFFFF ? (byte)4 : (byte)2;if (buff[3] == 2){buff[4] = (byte)(startAddr >> 12);buff[5] = (byte)(startAddr >> 4);deviationAddr = startAddr & 0xFFFFFFF0;}if (buff[3] == 4){buff[4] = (byte)(startAddr >> 24);buff[5] = (byte)(startAddr >> 16);deviationAddr = startAddr & 0xFFFF0000;}buff[6] = HexCheckSum(buff, 6);str = ":" + CommonLib.ToStr(buff, 7).Replace(" ", "");writeFile.WriteLine(str);address = (ushort)(startAddr - deviationAddr);}buff[1] = (byte)(address >> 8);buff[2] = (byte)(address >> 0);buff[3] = 0x00;int lenth = ((i + 1) * HEX_LINE_LEN) > len ? len - (i * HEX_LINE_LEN) : HEX_LINE_LEN;buff[0] = (byte)lenth;address += (ushort)lenth;startAddr += (uint)lenth;CommonLib.Copy(buff, 4, p_buff, HEX_LINE_LEN * i, lenth);buff[lenth + 4] = HexCheckSum(buff, lenth + 4);str = ":" + CommonLib.ToStr(buff, lenth + 5).Replace(" ", "");writeFile.WriteLine(str);}str = ":00000001FF";writeFile.WriteLine(str);writeFile.WriteLine("");writeFile.Flush();writeFile.Close();return true;}catch { return false; }}
九、源码下载
- 文件转换工具(FileCrcCreat)点击此处进行下载。
十、其他
本文主要是讲解BIN,S19,M0T,SREC,HEX文件解析,后续章节会对源码的内容进行讲解,方便新手查询,有些地方可能会有描述性的错误,希望看到的朋友及时指出,我会及时更正错误,其他地方有些借鉴的描述,写此文章的目的是为了交流,非商业用途,欢迎私信讨论,感谢大家阅读。
十一、参考
【1】:S19文件格式详解
【2】:HEX文件格式详解
BIN,S19,M0T,SREC,HEX文件解析;FileParse(二)之源码解析相关推荐
- Android Glide图片加载框架(二)源码解析之load()
文章目录 一.前言 二.源码分析 1.load() Android Glide图片加载框架系列文章 Android Glide图片加载框架(一)基本用法 Android Glide图片加载框架(二)源 ...
- Spring源码深度解析(郝佳)-学习-源码解析-创建AOP静态代理实现(八)
继上一篇博客,我们继续来分析下面示例的 Spring 静态代理源码实现. 静态 AOP使用示例 加载时织入(Load -Time WEaving,LTW) 指的是在虚拟机载入字节码时动态织入 Aspe ...
- Spring源码深度解析(郝佳)-学习-源码解析-基于注解切面解析(一)
我们知道,使用面积对象编程(OOP) 有一些弊端,当需要为多个不具有继承关系的对象引入同一个公共的行为时,例如日志,安全检测等,我们只有在每个对象引用公共的行为,这样程序中能产生大量的重复代码,程序就 ...
- Spring源码深度解析(郝佳)-学习-源码解析-Spring MVC(三)-Controller 解析
在之前的博客中Spring源码深度解析(郝佳)-学习-源码解析-Spring MVC(一),己经对 Spring MVC 的框架做了详细的分析,但是有一个问题,发现举的例子不常用,因为我们在实际开发项 ...
- Android Glide图片加载框架(二)源码解析之into()
文章目录 一.前言 二.源码解析 1.into(ImageView) 2.GlideContext.buildImageViewTarget() 3.RequestBuilder.into(Targe ...
- Android Glide图片加载框架(二)源码解析之with()
文章目录 一.前言 二.如何阅读源码 三.源码解析 1.with() Android Glide图片加载框架系列文章 Android Glide图片加载框架(一)基本用法 Android Glide图 ...
- Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)
在Spring源码深度解析(郝佳)-学习-源码解析-基于注解bean解析(一)博客中,己经对有注解的类进行了解析,得到了BeanDefinition,但是我们看到属性并没有封装到BeanDefinit ...
- Mybatis 源码解析 -- 基于配置的源码解析(二)
为什么80%的码农都做不了架构师?>>> mapper解析 接着上篇的配置,本篇主要讲解mappers标签 <?xml version="1.0" e ...
- Hotspot 垃圾回收之oop_iterate(二) 源码解析
目录 1.java.lang.Class 1.1.Class实例中oop_size.klass等属性是哪来的? 1.2._offset_of_static_fields 1.3 为什么从_offset ...
- Hotspot 重量级锁ObjectMonitor(二) 源码解析
目录 1.AddWaiter / DequeueWaiter /DequeueSpecificWaiter 2.wait 3.notify 4.notifyAll 5.exit 6.try_enter ...
最新文章
- 双重指针作为函数参数的妙用
- mysql e 导出数据库_mysql导出数据库几种方法
- 35丨基础篇:C10K和C1000K回顾
- 数据库-优化-groupby的优化
- .attr()与.removeAttr()
- PHP写webservice服务端
- python图形库使用教程_PySide——Python图形化界面入门教程(四)
- 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅵ
- 一个参数在注塑行业的影响——“停留时间”
- RationalDMIS 2020 网络报表/网络编程连接设置
- 联想笔记本电脑键盘灯怎么开启_联想键盘灯怎么开
- Access的DateAdd 函数
- 雷电网络 微支付通道
- 【降维打击,带你深度学习CPU(上)】
- 论文笔记:Parallel Tracking and Verifying: A Framework for Real-Time and High Accuracy Visual Tracking...
- Web自动化测试-Protractor基础(二)
- python小游戏:“不要做”游戏取词器
- D - Squirrel and chestnut(二分)
- 贩妖记 第六十六章,水底大鱼
- WPF-实现TextBox和PasswordBox显示背景文字
热门文章
- 蓝牙技术|了解蓝牙LE Audio的Auracast广播音频
- 忘记Hololens开机密码,重置系统
- 【考研政治】2021肖八整理(时政部分)
- 201506051031_《JavaScript权威指南》(p104-143)
- 3GPP 首个5G标准
- 软考高级已过,可以继续考软考中级吗?
- 百万调音师—Audition 标记
- Mysql数据库备份——数据库备份和表备份
- 谣言检测相关论文阅读笔记:Towards Multi-Modal Sarcasm Detection via Hierarchical Congruity Modeling
- 系统集成项目管理之项目质量管理