首页 > 编程知识 正文

妖法hex解析,单片机hex文件怎么生成

时间:2023-05-04 07:06:24 阅读:156340 作者:865

包括单片机在内的电子产品批量生产时使用. hex文件或.欢呼的茉莉花。 hex是包含地址信息和数据信息的十六进制数字,但欢呼的茉莉花文件是二进制文件,不包含地址的只有数据。 每个文件都有一定的格式规范,而hex文件也有完整的格式规范。 今天和大家分享hex是如何被解析的。

一. hex文件分析

可以使用UltraEdit、Notepad、记事本等工具打开hex文件。 在Notepad中打开时,将显示与以下内容类似的数据内容:

用Notepad打开后意义不同的数据,颜色不同。 每行的数据以冒号开头,后面的数据由数据长度、地址、标识符、有效数据、验证数据等组成。 上图中的第一个行为示例进行分析:

第一个字节10指示一行具有0x10个数据,即16字节的数据;

第2、第3字节的C000表示该行的开头地址是0xC000;

第四个字节的00表示该行中记录了数据。

第5-20字节表示有效数据

第21字节73表示前一数据的检查数据,并输出校验方法:0x100-前面字节累加和

其中,第四字节有五种类型。 00-05是如下的意思。

字段的意义00指示下一个记录是数据01,指示文件已结束,附图标记02表示扩展段地址,附图标记03表示开始段地址,附图标记04表示扩展线性地址,而附图标记05表示线性地址的单个麦克风hex文件的结尾部分如下图所示。

最后一行的01表示文件已结束,最后的FF显示验证数据,可从0x100-0x01=0xFF中获得。

二.扩展地址

细心的同学可能注意到了,上面的地址都是2字节,范围是0x000-0xFFFF。 如果地址是0x17FFFF该怎么办? 这将使用扩展字段。 例如以下所示。

第一行的第一个字节为0x02,表示只有两个字节的数据,而扩展段的标识符0x04表示后续数据0x0800是扩展线性地址。 基地址的计算方法如下。

(0x080016 )=0x 08000000,0x 04标识段出现之前,以下所有数据均为此基地址。

第二行的地址必须是0x0000,实际的地址必须是0x080000000x0000=0x08000000;

第二行的地址必须是0x0010,实际地址必须是0x080000000x0010=0x08000010;

使用Notepad工具,可以通过颜色来确认验证数据是否正确。 如果验证数据的颜色不是绿色,则验证结果错误。

三.程序如何实现hex分析

经常用上位机软件实现单片机的写入,上位机必须对hex文件进行分析。 程序如何实现对hex文件的分析呢?

头文件的代码如下:

# ifndef _ hex lexer _ h _ # define _ hex lexer _ h _ # include cstdio # include cstring # includecstdlib/* Intel hex文件管理器recordmarkrecordlengthloadoffsetrecordtypedatachecksum存储在Intel Hex文件中,RecordMark存储在“:”*/# pragma warning (禁用: )中voidparsehex(char*data ); 解析//HEX文件中的voidparserecord(charch ); //每个记录size_t GetRecordLength (; //获取记录长度char GetRecordMark (; //获取记录标记char *GetLoadOffset (); //获取内存安装偏移char *GetRecordType (); //获取记录类型char *GetData (; //获取数据char*GetChecksum (); //校验和private : charm _ c buffer [ max _ buffer _ size ]; //保存要解析的记录char m_cRecordMark; //记录标记size_t m_nRecordLength; //记录长度char *m_pLoadOffset; //安装偏移char *m_pRecordType; //记录类型char *m_pData; //数据字段char *m_pChecksum; //校验和bool m_bRecvStatus; //接收状态标志//size_t m_nIndex; //缓存的字符索引值; hex:3360hex(char傲娇毛衣) { this-m_cRecordMark=傲娇毛衣; m_cBuffer[0]='”; //m_pBuffer=NULL; m_nRecordLength=0; m_pLoadOffset

= NULL; m_pRecordType = NULL; m_pData = NULL; m_pChecksum = NULL; m_bRecvStatus = false; //m_nIndex = 0;}Hex::~Hex(){ delete m_pLoadOffset, m_pRecordType, m_pData, m_pChecksum;}#endif

 代码如下所示。

#include "HexLexer.h"#include <iostream>using namespace std;//获取记录标识char Hex::GetRecordMark(){ return this->m_cRecordMark;}//获取每条记录的长度size_t Hex::GetRecordLength(){ //char *len = (char*)malloc(sizeof(char)* 3); if (strlen(m_cBuffer)>=2) { char len[3]; len[0] = m_cBuffer[0]; len[1] = m_cBuffer[1]; len[2] = ''; char *p = NULL; return strtol(len, &p, 16); } else { return 0; }}//获取装载偏移char* Hex::GetLoadOffset(){ if (strlen(m_cBuffer) == (GetRecordLength() + 5) * 2) { char *offset = (char*)malloc(sizeof(char)* 5); for (int i = 0; i < 4; ++i) { offset[i] = m_cBuffer[i + 2]; } offset[4] = ''; m_pLoadOffset = offset; offset = NULL; } return m_pLoadOffset;}//获取记录类型char* Hex::GetRecordType(){ if (strlen(m_cBuffer) == (GetRecordLength() + 5) * 2) { char *type=(char*)malloc(sizeof(char)*3); type[0] = m_cBuffer[6]; type[1] = m_cBuffer[7]; type[2] = ''; m_pRecordType = type; type = NULL; } return m_pRecordType;}//获取数据char* Hex::GetData(){ if (strlen(m_cBuffer) == (GetRecordLength() + 5) * 2) { int len = GetRecordLength(); char *data = (char*)malloc(sizeof(char)*(len * 2 + 1)); for (int i = 0; i < len * 2;++i) { data[i] = m_cBuffer[i + 8]; } data[len * 2] = ''; m_pData = data; data = NULL; } return m_pData;}//获取校验和char* Hex::GetChecksum(){ int len = GetRecordLength(); if (strlen(m_cBuffer) == (len + 5) * 2) { char *checksum=(char*)malloc(sizeof(char)*3); checksum[0] = m_cBuffer[(len + 5) * 2 - 2]; checksum[1] = m_cBuffer[(len + 5) * 2-1]; checksum[2] = ''; m_pChecksum = checksum; checksum=NULL; } return m_pChecksum;}//解析Hex文件中的每一条记录void Hex::ParseRecord(char ch){ size_t buf_len = strlen(m_cBuffer); if (GetRecordMark()==ch) { m_bRecvStatus = true; m_cBuffer[0] = ''; //m_nIndex = 0; return; } if ((buf_len==(GetRecordLength()+5)*2-1)) { //接收最后一个字符 m_cBuffer[buf_len] = ch; m_cBuffer[buf_len + 1] = ''; //检验接收的数据 char temp[3]; char *p = NULL; long int checksum = 0; for (int i = 0; i < strlen(m_cBuffer);i+=2) { temp[0] = m_cBuffer[i]; temp[1] = m_cBuffer[i + 1]; temp[2] = ''; checksum += strtol(temp, &p, 16); temp[0] = ''; } checksum &= 0x00ff;//取计算结果的低8位 if (checksum==0)//checksum为0说明接收的数据无误 { cout << "RecordMark " << GetRecordMark() << endl; cout << "RecordLength " << GetRecordLength() << endl; cout << "LoadOffset " << GetLoadOffset() << endl; cout << "RecordType " << GetRecordType() << endl; cout << "Data " << GetData() << endl; cout << "Checksum " << GetChecksum() << endl; } else//否则接收数据有误 { cout << "Error!" << endl; } m_cBuffer[0] = ''; m_bRecvStatus = false; m_nRecordLength = 0; m_pLoadOffset = NULL; m_pRecordType = NULL; m_pChecksum = NULL; m_bRecvStatus = false; } else if (m_bRecvStatus) { m_cBuffer[buf_len] = ch; m_cBuffer[buf_len + 1] = ''; //m_nIndex++; }}//解析Hex文件void Hex::ParseHex(char *data){ for (int i = 0; i < strlen(data);++i) { ParseRecord(data[i]); }}int main(int argc, char *argv[]){ freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); Hex hex(':'); char ch; while (cin>>ch) { hex.ParseRecord(ch); } fclose(stdout); fclose(stdin); return 0;}

是不是这样呢?赶紧打开.hex文件来看一下吧。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。