车载网络测试实操源码_使用CAPL解析S19文件

系列文章目录

车载网络测试实操源码_使用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进行刷写下载。

  • 19
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
CAPL是一种编程语言,通常用于编写测试和仿真脚本,不直接支持解析S19文件。但是,CAPL提供了一个二进制文件I/O库,可以用于读写二进制文件,因此可以使用CAPL来读取S19文件并提取其中的数据。 S19文件是一种十六进制文件格式,用于存储嵌入式系统的程序和数据。它包含了一些元数据和十六进制数据记录。下面是一个S19文件的示例: ``` S1130000C0F2BEEF00000000000000000000000000B6 S11300100000000000000000000000000000000000A6 S9030000FC ``` 每行记录由以下几部分组成: - 起始符号"S1"或"S9",表示数据记录类型。S1表示数据记录,S9表示文件结束记录。 - 记录长度,以十六进制表示。例如,S113表示记录长度为19字节(0x13)。 - 起始地址,以十六进制表示。例如,0000表示起始地址为0。 - 记录类型,以十六进制表示。例如,C0表示数据记录。 - 数据,以十六进制表示。例如,F2BEEF表示数据为0xF2, 0xBE, 0xEF。 要解析S19文件,可以使用CAPL的二进制文件I/O库和字符串处理函数。基本的步骤如下: 1. 打开S19文件使用fopen函数打开文件并返回一个文件指针。 2. 读取每行记录,使用fgets函数读取文件中的每一行。 3. 解析每行记录,使用字符串处理函数和类型转换函数将每行记录转换为数据。 4. 处理解析后的数据,根据记录类型将数据存储到相应的位置。 以下是一个简单的CAPL代码示例,演示了如何读取S19文件并提取其中的数据。 ``` variables { FILE* fp; char line[80]; unsigned char data[1024]; unsigned long address = 0; } on start { fp = fopen("program.s19", "r"); if (fp == NULL) { write("Failed to open file"); return; } while (fgets(line, sizeof(line), fp)) { if (line[0] != 'S') { continue; // skip comments and other lines } int len = (int)strtol(line + 2, NULL, 16); // parse length field int type = (int)strtol(line + 8, NULL, 16); // parse type field if (type == 0) { int i; for (i = 0; i < len - 5; i += 2) { int byte = (int)strtol(line + 10 + i, NULL, 16); // parse data byte data[address++] = (unsigned char)byte; } } else if (type == 9) { break; // end of file } } fclose(fp); // process data here } ``` 该代码打开名为“program.s19”的文件,并逐行读取文件内容。对于每个数据记录,它解析长度、类型和数据,将数据存储到data数组中,并将地址address增加相应的字节数。最后,它关闭文件并在此处处理data数组中的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MrxMyx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值