如下是s19实现解析简易代码,具体如下:
外部调用接口:ParseS19
输入参数:
1、path:文件绝对路径
输出参数:
1、startAddr:文件烧入芯片起始地址
2、BinData:文件二进制流List,List类型为Byte
设计要点:
1、读取行直至读不到数据结束
2、通过判断S1、S2、S3类型确定文件长度,将ASCII转换为字节流数据
3、使用Byte List存储数据
待完善:
1、未判断s19文件是否存在
2、未判断s0、S5、S7、S8、S9
3、未对文件做校验功能判断
/******************************************************************************* 该部分为S19文件和srec文件解析规则 * S0,位于文件的第一行,和其他行不同,地址部分没有使用,用0000置位,整行表示记录的开始* S1表示地址长度为两字节(4字符)的记录,包含类型、长度、地址、数据和校验和五个部分* S2表示地址长度为三字节(6字符)的记录,包含类型、长度、地址、数据和校验和五个部分* S3表示地址长度为四字节(8字符)的记录,包含类型、长度、地址、数据和校验和五个部分* S5表示文件中含有S1、S2、S3记录的个数,其后不接数据,包含S5的记录并不是每个文件必须的* S7表示地址长度为四字节(8字符)的记录,包含类型、长度、地址和校验和四个部分,此行表示程序的结束* S8表示地址长度为三字节(6字符)的记录,包含类型、长度、地址和校验和四个部分,此行表示程序的结束* S9表示地址长度为两字节(4字符)的记录,包含类型、长度、地址和校验和四个部分,此行表示程序的结束* 只有S1、S2、S3需要写入Flash中* ***************************************************************************/public static string ParseS19(string path, ref UInt32 startAddr, ref List<Byte> BinData)
{try{uint sumLen = 0;//记录的是字符的长度int lineNum = 0;string szLine = ""; //数据处理临时字符串string sTemp = "";int nowLineAddressLen = 0;int nowLineRecordLen = 0;uint nowLineAddr;//打开文件StreamReader HexReader = new StreamReader(path);while (true){//读取一行数据szLine = HexReader.ReadLine();//读完所有行导出最后一个块if (szLine == null){//Log("总函数:" + lineNum.ToString() + ",总长度:" + sumLen.ToString());sumLen = 0;break;}lineNum++;//判断第1字符是否是Sif (szLine.Substring(0, 1) != "S"){HexReader.Close();throw new Exception("S19文件第1个字符不是S");}//获取类型sTemp = szLine.Substring(0, 2);//为S0或S5 S7-S9则略过if (sTemp == "S0" || sTemp == "S5" || sTemp == "S7" || sTemp == "S8" | sTemp == "S9"){continue;}//获取当前行内数据的地址长度nowLineRecordLen = Convert.ToInt32(szLine.Substring(2, 2), 16);//Console.WriteLine("line=" + lineNum.ToString() + ",len=" + nowLineRecordLen.ToString());if (nowLineRecordLen % 2 != 0){//throw new Exception("S19文件第"+lineNum.ToString()+ "行数据长度不对");}//获取当前行内数据的地址nowLineAddressLen = ParseAddressLen(sTemp);nowLineAddr = Convert.ToUInt32(szLine.Substring(4, nowLineAddressLen), 16);//首行地址当作文件起始地址if (sumLen == 0){startAddr = nowLineAddr;}记录数据int dataLen = nowLineRecordLen*2 - nowLineAddressLen - 2;sTemp = szLine.Substring(4 + nowLineAddressLen, dataLen);for (int i = 0; i < dataLen; i += 2){string valStr = sTemp.Substring(i, 2);BinData.Add(Convert.ToByte(valStr, 16));sumLen += 1;}}HexReader.Close();return "OK";}catch (Exception ex){return ex.Message;}
}//返回地址长度
private static int ParseAddressLen(string SecondFlag)
{int AddressLen = 0;switch (SecondFlag){case "S0":AddressLen = 2 * 2;break;case "S1":AddressLen = 2 * 2;break;case "S2":AddressLen = 3 * 2;break;case "S3":AddressLen = 4 * 2;break;case "S7":AddressLen = 4 * 2;break;case "S8":AddressLen = 3 * 2;break;case "S9":AddressLen = 2 * 2;break;}return AddressLen;
}