系列文章目录
车载网络测试实操源码_使用CAPL脚本解析hex、S19、vbf文件
车载网络测试实操源码_使用CAPL脚本对CAN报文的Counter和CRC进行实时监控
车载网络测试实操源码_使用CAPL脚本模拟发送符合协议要求的Counter和CRC的CAN报文
车载网络测试实操源码_使用CAPL脚本实现安全访问解锁
车载网络测试实操源码_使用CAPL脚本进行DTC自动化测试
车载网络测试实操源码_使用CAPL脚本进行UDS刷写及其自动化测试
车载网络测试实操源码_使用CAPL脚本进行UDS协议测试
粉丝问题解答系列文章… …
其他持续更新中… …
前言
在车载软件开发和测试过程中,我们经常会需要刷写S19文件,可能很多时候大家都是利用现成的软件工具进行烧写,所以并不了解S19文件的数据格式,也不需要对其进行解析。如果各位在遇到需要自己编写刷写软件或脚本,或者需要对刷写功能进行测试时,那么本篇文章就会对你非常有用。今天我们就来讲一下如何使用CAPL脚本对S19文件进行数据解析。
一、S19文件介绍
S19文件(S-record)是由Motorola创建的一种文件格式,是一种ASCII十六进制文本文件格式,它通常用于对微控制器、EPROM 和其他类型的可编程逻辑设备进行编程。具体格式如下:
type(类型):用来描述记录的类型 (S0,S1,S2,S3,S5,S7,S8,S9)。
S0 Record0x5330):地址场没有被用,用零置位(0x0000)。数据场中的信息被划分为以下四个子域:name(名称):20个字符,用来编码单元名称;ver(版本):2个字符,用来编码版本号;rev(修订版本):2个字符,用来编码修订版本号;description(描述):0-36个字符,用来编码文本注释。此行表示程序的开始,不需烧入memory。(不是所有的S-record文件都包含S0记录,因为它不是必需的。)
S1 Record (0x5331):地址场由2个字节地址来说明。数据场由可载入的数据组成。
S2 Record (0x5332):地址场由3个字节地址来说明。数据场由可载入的数据组成。
S3 Record(0x5333):地址场由4个字节地址来说明。数据场由可载入的数据组成。
S5 Record(0x5335):地址场由2字节的值说明,包含了先前传输的S1、S2、S3记录的计数。没有数据场。
S7 Record(0x5337):地址场由4字节的地址说明,包含了开始执行地址。没有数据场。此行表示程序的结束,不需烧入memory。
S8 Record(0x5338):地址场由3字节的地址说明,包含了开始执行地址。没有数据场。此行表示程序的结束,不需烧入memory。
S9 Record(0x5339):地址场由2字节的地址说明,包含了开始执行地址。没有数据场。此行表示程序的结束,不需烧入memory。
count(计数):(address + data + checksum)区域的字节总数。
address(地址):用来组成和说明了一个16进制的值,显示了数据应该装载的地址, 这部分的长度取决于载入地址的字节数。2个字节的地址占用4个字符,3个字节的地址占用6个字符,4个字节的地址占用8个字符。
data(数据):内存载入数据或者描述信息的16进制的值。
checksum(校验和):这些字符当被配对并换算成16进制数据的时候形成了一个最低有效字符节。即计数值、地址场和数据场的若干字符以两个字符为一对,将它们相加求和,和的溢出部分不计,只保留最低两位字符NN,checksum =0xFF-0xNN。
二、S19文件解析
以下是一个实际的S19文件示例,大家可以对应上面的格式进行理解:
根据前面的讲解我们已经知道,上面示例中框选的部分就是数据内容,我们实际主要做的就是把数据区的内容解析出来,用于程序烧写。
话不多说,上代码(以解析上图格式的S19文件为示例)
/*@!Encoding:936*/
includes
{
}
variables
{
/*flashDriver和app的S19文件定义*/
const dword S19File_TotalMaxLen = 0x300000;
struct S19data
{
dword dataLength;
dword dataStartAddr;
byte data[S19File_TotalMaxLen];
dword CRC;
};
struct S19data flashDriverS19Data;
struct S19data AppS19data;
/* 指定待解析的文件 */
char FlashDriverS19_PathFile[200] = "E:\\TEST\\XXX_DRIVER.s19";
char AppS19_PathFile[200] = "E:\\TEST\\XXX_APP.s19";
}
/*将char字符转换为byte*/
byte char2byte(char ch)
{
byte val = 0;
if ( ch >= '0' && ch <= '9')
{
val = ch - '0';
}
if ( ch >= 'a' && ch <= 'f')
{
val = (ch - 'a') + 10;
}
if ( ch >= 'A' && ch <= 'F')
{
val = (ch - 'A') + 10;
}
return val;
}
/*解析S19文件*/
void S19File_Parse(byte File_Select,struct S19data File_obj)
{
char UpdateFileAdress[200];
char UpdateFileBuffer[200];
dword UpdateFileHandle;
long char_index;
long buff_index;
char_index = 0;
buff_index = 0;
File_obj.dataLength = 0;
/*获取文件路径*/
if(File_Select == 1)//FlashDriver
{
memcpy(UpdateFileAdress,FlashDriverS19_PathFile,elcount(FlashDriverS19_PathFile));
File_obj.dataStartAddr = 0x00120000;/*flashdriver下载地址(本处填固定值作为示例,也可以解析文件中的地址)*/
}
else if(File_Select == 2)//APP
{
memcpy(UpdateFileAdress,AppS19_PathFile,elcount(AppS19_PathFile));
File_obj.dataStartAddr = 0x12003400;/*APP下载地址(本处填固定值作为示例,也可以解析文件中的地址)*/
}
/*以文本模式打开文件*/
UpdateFileHandle = OpenFileRead(UpdateFileAdress,0);
/*读取文件数据*/
if ( UpdateFileHandle!=0 )
{
while( fileGetString(UpdateFileBuffer,elcount(UpdateFileBuffer),UpdateFileHandle)!=0 )
{
if( strlen(UpdateFileBuffer) > 20 ) //剔除非数据区
{
/*解析长度*/
File_obj.dataLength += 16;//每一行16个字节
/*解析数据*/
for(char_index = 12; char_index < 44; char_index += 2)
{
File_obj.data[buff_index++]=char2byte(UpdateFileBuffer[char_index])*0x10 + char2byte(UpdateFileBuffer[char_index+1]);
}
}
}
fileClose (UpdateFileHandle);
}
else
{
write ("Failed to read file.");
}
//File_obj.CRC = Voyah_crc32(File_obj.data, File_obj.dataLength);
}
/*解析函数调用示例*/
void S19ParseMain()
{
S19File_Parse(1,flashDriverS19Data);
S19File_Parse(2,AppS19data);
}
解析完的FlashDriver和App程序数据就存在flashDriverS19Data和AppS19data中,包括数据长度、数据内容、数据地址、CRC校验(CRC校验算法函数没有在上面代码中贴出,各位可以根据自己实际项目的需求进行实现)
以上代码是根据上面的示例S19文件进行编写的,如果你的S19文件中数据长度不一样,需要调整一下脚本中解析的数据字节长度。
总结
本文简单介绍了S19文件的格式,以及如何使用CAPL脚本对S19文件中的数据进行解析,希望对大家有所帮助。本文只讲解了如何解析出S19文件中的数据,后续文章会讲解如何将解析出来的数据通过CAN进行刷写下载。