`
helpbs
  • 浏览: 1164287 次
文章分类
社区版块
存档分类
最新评论

S-Record格式分析代码

 
阅读更多

//========================================================================
//TITLE:
// S-Record格式分析代码
//AUTHOR:
// norains
//DATE:
// Wednesday 30-April-2008
//Environment:
// NULL
//========================================================================
MOTOROLA S-Record的格式并不复杂,相关的描述可以参考我另一篇文章《S-Record格式详解》:http://blog.csdn.net/norains/archive/2008/04/25/2326306.aspx。本文主要是在代码层次对S-Record进行分析。

和以往相同,为了方便使用,将S-Record的分析代码封装为一个CSrecParse类。

以下为CSrecParse类代码:


//////////////////////////////////////////////////////////////////////
// SrecParse.h: interface for the CSrecParse class.
//
//////////////////////////////////////////////////////////////////////
#pragma once

#include <string>
#include <vector>


#ifdef UNICODE
typedef std::wstring TSTRING;
#else
typedef std::string TSTRING;
#endif

class CSrecParse
{
public:
enum Type
{
S0 = 0,
S1,
S2,
S3,
S4,
S5,
S6,
S7,
S8,
S9
};


public:
//Interface
bool SetFile(const TSTRING & strFile);
bool GetNextData(CSrecParse::Type &type, DWORD &dwAddr,std::vector<BYTE> &vctData, bool &bChkSum);

public:
CSrecParse(void);
~CSrecParse(void);
void Reset(void);


protected:
DWORD HexToDec(const char *pChar,int iLen = -1);

private:
std::string::size_type m_stPos;
std::string m_strContent;

};
//////////////////////////////////////////////////////////////////////
// SrecParse.cpp
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SrecParse.h"

CSrecParse::CSrecParse(void):
m_stPos(0)
{
}

CSrecParse::~CSrecParse(void)
{
}


//----------------------------------------------------------
//Description:
// Set the S-Record file to parse
//
//----------------------------------------------------------
bool CSrecParse::SetFile(const TSTRING & strFile)
{

HANDLE hFile = CreateFile(&strFile[0],GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(INVALID_HANDLE_VALUE == hFile)
{
return false;
}

DWORD dwFileSize = GetFileSize(hFile,NULL);
if(m_strContent.capacity() < dwFileSize)
{
m_strContent.resize(dwFileSize);
}

DWORD dwFileRead = 0;
ReadFile(hFile,&m_strContent[0],dwFileSize,&dwFileRead,NULL);
CloseHandle(hFile);

return true;
}


//----------------------------------------------------------
//Description:
// Get the next data. If you want to get the first data,you should call Reset() before calling the function.
//
//Parameter:
// type : [out] The data type
// dwAddr : [out] The address
// vctData : [out] The buffer for store the data.
// bChkSum : [out] The checksum is right or not.
//
//----------------------------------------------------------
bool CSrecParse::GetNextData(CSrecParse::Type &type, DWORD &dwAddr,std::vector<BYTE> &vctData, bool &bChkSum)
{
m_stPos = m_strContent.find("S",m_stPos);
if(m_stPos != std::string.npos)
{
std::string strCvrt(10,0);
std::vector<BYTE> vctStore;
DWORD dwSum = 0;

//The type
strCvrt[0] = m_strContent[m_stPos + 1];
strCvrt[1] = '/0';
type = static_cast<CSrecParse::Type>(atoi(&strCvrt[0]));
if(type == S5)
{
//Doesn't support the S5 type in current
return false;
}

//The length, include <address>,<data>,<checksum> field;
strCvrt[0] = m_strContent[m_stPos + 2];
strCvrt[1] = m_strContent[m_stPos + 3];
strCvrt[2] = '/0';
int iLength = static_cast<int>(HexToDec(&strCvrt[0])) * 2; //Plus 2 to convert to the string length.

dwSum += static_cast<int>(HexToDec(&strCvrt[0]));

if(type == S0)
{
//Address
dwAddr = 0;

//The data
for(int i = 0; i < iLength - 6; i += 2)
{
strCvrt[0] = m_strContent[m_stPos + 8 + i];
strCvrt[1] = m_strContent[m_stPos + 9 + i];
strCvrt[2] = '/0';

BYTE uData = static_cast<BYTE>(HexToDec(&strCvrt[0]));
vctStore.push_back(uData);
dwSum += uData;
}
vctData = vctStore;

//The checksum
strCvrt[0] = m_strContent[m_stPos + iLength + 2];
strCvrt[1] = m_strContent[m_stPos + iLength + 3];
strCvrt[2] = '/0';

bChkSum = (static_cast<BYTE>(HexToDec(&strCvrt[0])) == ( 0xFF - (dwSum & 0xFF)));

m_stPos ++;

return true;
}
else
{
//S1,S2,S3,S7,S8,S9


//The address
int iLenAddr = 0;
switch(type)
{
case S1:
case S9:
iLenAddr = 2 * 2;//Plus 2 to convert to the string length.
break;
case S2:
case S8:
iLenAddr = 3 * 2;//Plus 2 to convert to the string length.
break;
case S3:
case S7:
iLenAddr = 4 * 2;//Plus 2 to convert to the string length.
break;
}
for(int i = 0; i < iLenAddr; i++)
{
strCvrt[i] = m_strContent[m_stPos + 4 + i];
}
strCvrt[iLenAddr] = '/0';
dwAddr = HexToDec(&strCvrt[0]);

for(int i = 0; i < iLenAddr; i += 2)
{
dwSum += HexToDec(&strCvrt[i],2);
}

//The data
int iCount = iLength - iLenAddr - 2; //The length of 2 is checksum.
std::string::size_type stPosBegin = m_stPos + 3 + iLenAddr + 1;
for(int i = 0; i < iCount; i += 2)
{
strCvrt[0] = m_strContent[stPosBegin + i];
strCvrt[1] = m_strContent[stPosBegin + i + 1];
strCvrt[2] = '/0';

BYTE uData = static_cast<BYTE>(HexToDec(&strCvrt[0]));
vctStore.push_back(uData);
dwSum += uData;
}
vctData = vctStore;

//The checksum.
strCvrt[0] = m_strContent[m_stPos + iLength + 2];
strCvrt[1] = m_strContent[m_stPos + iLength + 3];
strCvrt[2] = '/0';

bChkSum = (static_cast<BYTE>(HexToDec(&strCvrt[0])) == ( 0xFF - (dwSum & 0xFF)));
}

}
else
{
return false;
}

m_stPos ++;
return true;
}


//----------------------------------------------------------
//Description:
// Reset the indext to call GetNextData() to get the first data.
//
//----------------------------------------------------------
void CSrecParse::Reset(void)
{
m_stPos = 0;
}


//----------------------------------------------------------
//Description:
// Hex convert to decade.
//
//Parameter:
// pChar : [in] The string to convert. If iLen is -1,it must be with the NULL terminate end.
// iLen : [in] The length of the pChar buffer. The default value is -1;
//
//----------------------------------------------------------
DWORD CSrecParse::HexToDec(const char *pChar,int iLen)
{
DWORD val = 0;
int iCount = 0;
while(*pChar)
{
if(*pChar >= 'a' && *pChar <= 'f')
{
val = val * 16 + *pChar - 'a' + 10;
}
else if(*pChar >= 'A' && *pChar <= 'F')
{
val = val * 16 + *pChar - 'A' + 10;
}
else if(*pChar >= '0' && *pChar <= '9')
{
val = val * 16 + *pChar - '0';
}
else
{
break;
}
pChar++;

if(iLen != -1)
{
iCount ++;
if(iCount >= iLen)
{
return val;
}
}
}
return val;
}


该类的使用非常简单,现在以一个很基本的代码作为示例:

CSrecParse parse;

//设置需要分析的文件路径
parse.SetFile(&strFile[0]);

//数据的类型
CSrecParse::Type type;

//数据的地址
DWORD dwAddr;

//存储数据的缓存
std::vector<BYTE> vctData;

//ChkSum位是否正确
bool bChkSum;


std::vector<BYTE> vctStore;

while(parse.GetNextData(type,dwAddr,vctData,bChkSum) == true)
{
if(type == CSrecParse::S5)
{
//S5格式暂时不支持
break;
}
else
{
//...
//根据分析回来的数据去做相应处理
}
}

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/norains/archive/2008/04/30/2349903.aspx

分享到:
评论

相关推荐

    编译原理——词法分析代码

    s 表示运算符(学生编程时类号分别为1,2,3,4,5)。 对于标识符和常数,需分别与标识符表和常数表中已登记的元素相比较,如表中已有该元素,则记录其在表中的位置,如未出现过,将标识符按顺序填入数组 id 中,将常数...

    matlab精度检验代码-Cat_skin:猫皮

    -Record data from strain gauges on a skin using C++ and MATLAB code 数据分析(GitHub:) -K-Nearest-Neighbor (KNN) approach to train and test the biped's CoP preciction accuracy -5-Fold Cross-...

    (重要)AIX command 使用总结.txt

    F Format -&gt;以用户指定格式输出,Format参数为预定义或自定义设备对象类中的列名,如:name status等 H -&gt;显示列输出前面的头部分,即输出中包括列头部分 P -&gt;列出预定义设备对象类中设备的有关信息,即支持的设备,...

    如何编写批处理文件批处理文件批处理文件

    批处理文件是无格式的文本文件,它包含一条或多条命令。它的文件扩展名为 .bat 或 .cmd。在命令提示下键入批处理文件的名称,或者双击该批处理文件,系统就会调用Cmd.exe按照该文件中各个命令出现的顺序来逐个运行...

    uboott移植实验手册及技术文档

    了解 U-Boot-1.3.1 的代码结构,掌握其移植方法。 【实验环境】 1、Ubuntu 7.0.4发行版 2、u-boot-1.3.1 3、FS2410平台 4、交叉编译器 arm-softfloat-linux-gnu-gcc-3.4.5 【实验步骤】 一、建立自己的平台...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 第一章 Oracle入门 一、 数据库概述 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今五十年前。简单来说是本身可视...

    Quantify-1.pdf

    代码静态度量分析质量检查工具:logiscope和Macabe等 黑盒测试工具主要有: 客户端功能测试:MI公司的winrunner,compuware的qarun,Rational的SQA robot等等 服务器端压力性能测试: MI公司的winload,compuware的...

    screencast-1-ember-route-hooks:EmberJS截屏视频的代码,涵盖了启动和关闭路由钩子

    然后,运行以下命令分析每个图像,并使用其大小和纵横比更新数据库。 $ rake image:record_sizes 然后只需使用以下命令启动rails应用程序: $ bundle exec rails s 现在,您将在以下端口上运行Rails服务器:3000...

    Python操作MySQL简单实现方法

    本文实例讲述了Python操作MySQL简单实现方法。分享给大家供大家参考。具体分析如下: 一、安装: 安装MySQL 安装MySQL不用多说了,... print ‘there has %s rows record’ % count   #插入 def Insert(cur):  sq

    操作系统实验

    在Linux系统下,使用与文件相关的系统调用实现对物理设备文件的读写,参照Linux系统源代码以及Grub系统的源代码,对不同介质上的FAT格式文件系统进行分析。要求在Linux环境下设计出C语言程序,实现以下功能: 1)...

    用C编写班级成绩管理系统

    代码设计: 初始化函数 STUDENT *init() 这是一个无参函数,里面只有两个语句,它的作用是使链表初始化,使head的值为NULL和一个清屏语句。比如:没有这个函数的话,在你没有输入任何数据的情况下,去执行显示功能的...

    中国电信计费模型:数据模型

    4.2.24 客户忠诚度评估记录(Cust_Loyalty_Record)实体 113 4.2.25 企业客户信息(Cust_Corporate_Info)实体 114 4.2.26 客户协议(Agreement)实体 116 4.2.27 协议相关对象(Agreement_Object)实体 118 4.2.28 协议属性...

    用于学习测试的神经网络ea.mq4

    In order not to lose ourselves, we will record the stage number in the input of the ATS identified as "pass". Identifiers of inputs corresponding with the stage number will and in the number equal to ...

    华为编程开发规范与案例

    软件编程规范培训实例与练习 软件编程规范培训实例与练习  问题分类 1 逻辑类问题(A类)-指设计、编码中出现的计算正确性和一致性...再分析整个函数,pSpcCB在函数前部分已经被赋值, pSpcCB = SpcCB + (PortTable...

    最全的oracle常用命令大全.txt

    数据字典里存有用户信息、用户的权限信息、所有数据对象信息、表的约束条件、统计分析数据库的视图等。 我们不能手工修改数据字典里的信息。  很多时候,一般的ORACLE用户不知道如何有效地利用它。  dictionary...

    Toad 使用快速入门

    12. 内置对PL/Formatter,可以用PL/Formatter对存储过程进行格式化,并且可以提供存储过程的概要分析和修改建议 PL/Formatter可以对现有的存储过程进行高速的格式化,使所有的存储过程都符合同样的编写标准,这样既...

    Oracle9i的init.ora参数中文说明

    ), interpreted (然后 PL/SQL 模块将被编译为 PL/SQL 字节代码格式), debug (PL/SQL 模块将用探测调试符号来编译), non_debug。 默认值: " interpreted, non_debug " plsql_native_linker: 说明: 此参数指定链接...

    网上购物系统

    对购物车执行了这次添加后,大部分其余的ASP代码就不再最新网上购物系统 执行,因为它应用于其他的工作模式,模式的选择都是采用IF语句来实最新网上购物系统 现的,而每次check.asp只会在一个模式下工作的。 &lt;最新...

Global site tag (gtag.js) - Google Analytics