烧录文件bin、Motorola、hex格式介绍及解析 | 您所在的位置:网站首页 › 瑞萨rfp支持bin文件烧录吗 › 烧录文件bin、Motorola、hex格式介绍及解析 |
微处理器一般又称单片机,其可以根据人们编写的代码执行相关的逻辑操作。程序员将产品的逻辑操作抽象为C代码,然后通过编译器的编译和链接,生成微处理器可执行的机器码。通常编译器封装的不带调试信息的机器码有3种格式,分别为bin、motorola、hex,下面将分别介绍其特点: 1、Bin格式: Bin文件是二进制文件,是编译器生成的机器码文件,烧录工具可以直接读取该文件的内容而不用解析,然后通过烧录口直接烧录到微处理器的程序空间,但烧录前要指定程序存储空间的起始地址。由于Bin文件不带文件内容校验功能,因此要注意其文件内容的破坏。 2、Motorola格式: Motorola格式记录文件是ASCII格式的文件,又称SREC、S19,其是对机器码的一种封装描述。Motolora格式的文件相对于Bin文件来说,其带有程序的地址信息和数据校验功能,其Wiki的详细解说网址如下所示: https://en.wikipedia.org/wiki/SREC_(file_format)
其数据组织方式为: Record type Byte count Address Data Checksum
Record type: Record type为2个字节ASCII字符,第一个字符为‘S’,第二个字符为ASCII数字的‘0’~‘9’,下面将介绍其区别: 记录 类型 记录 目的 地址域 数据域 描述 S0 头说明 16位,默认值为“0000” 有 本记录为供应商特定的ASCII字符串信息,通常该值默认为“HDR”。 S1 数据 16位地址 有 本记录包含了数据内容和其16位地址信息,适用于8位单片机。 S2 数据 24位地址 有 本记录包含了数据内容和其24位地址信息。 S3 数据 32位地址 有 本记录包含了数据内容和其32位地址信息,适用于32位芯片。 S4 保留 N/A N/A 本记录保留,未定义 S5 计数 16位计数 无 本记录为可选记录,记录S1/S2/S3计数,当计数值大于0xFFFF,S6记录被使用 S6 计数 24位计数 无 本记录为可选记录,记录S1/S2/S3计数,当计数值小于0xFFFF,S5记录被使用 S7 起始地址或结束 32位地址 无 本记录用于定义32位可执行起始地址,也用于S3记录结束的标志。当SREC文件只是用于内存编程,则忽略起始地址。 S8 起始地址或结束 24位地址 无 本记录用于定义24位可执行起始地址,也用于S2记录结束的标志。当SREC文件只是用于内存编程,则忽略起始地址。 S9 起始地址或结束 16位地址 无 本记录用于定义16位可执行起始地址,也用于S1记录结束的标志。当SREC文件只是用于内存编程,则忽略起始地址。 对不同宽度的地址,其使用S19记录类型也不一样,对16位宽度的地址而言,其使用S0、S1、S5、S9类型的数据记录;对24位宽度的地址而言,其使用S0、S2、S5、S8类型的数据记录;对32位宽度的地址而言,其使用 S0、S3、S5、S7类型的数据记录。
Byte count: Byte count为2个16进制的ASCII数字,定义了Address + Data + Checksum域字节总数目。
Address: Address为4/6/8个16进制的ASCII数字,该个数取决于Record type的类型,用于表示数据的起始绝对地址,其数据格式为大端模式(即低地址为高字节数据)。
Data: Data为2*n个16进制的ASCII数字(n字节数据)。
Checksum: Checksum为2个16进制的ASCII数字,用于校验该行数据的完整性。该校验算法为将Byte count、Address、Data域的值进行相加,取低8位的和,然后取和的反值作为校验值,比如某S19文件中某记录为 S1090170E002FA050000A4,其数据和为: 09 + 01 + 70 + E0 + 02 + FA + 05 + 00 + 00 = 5B,5B的反值为A4,因此该行数据记录的校验值为A4。
S19数据记录以 行结束符 作为记录的结束,对不同的操作系统而言其行结束符是不一样的,比如对于Windows操作系统而言,其行结束符为CR LF(0x0D 0x0A)(‘\r’ ‘\n’),对于Linux操作系统而言,其行结束符为LF。
3、Hex格式: Hex文件是ASCII格式的文件,其也是对机器码的一种封装描述。Hex格式的文件相对于Bin文件来说,其也是带有程序的地址信息和数据校验功能,其Wiki的解说网址如下所示: https://en.wikipedia.org/wiki/Intel_HEX
其数据组织方式为:
Start code
Byte Count Address Record type Data Checksum
Start code: Start code为1个ASCII字符’:’,用于标志一行Hex记录的开始。
Byte count: Byte count为2个16进制的ASCII数字,定义Data域字节数目。
Address: Address为4个16进制的ASCII数字,用于表示数据的偏移地址,其数据格式为大端模式(即低地址为高字节数据)。
Record type: Record type为2个16进制的ASCII数字,其值范围为00 ~05,用于定义记录的类型。
Hex code Record type Description Example 00 数据(Data) 包含了数据内容和其偏移地址 :087DD00000A24A0400000000BB 本记录定义了偏移地址为0x7DD0的8个字节数据,分别为00,A2,4A,04,00,00,00,00
01 文件结束(End Of File) 该记录为Hex文件的最后一个记录,用于标志Hex文件记录的结束,该记录的固定格式为::00000001FF :00000001FF 本记录用于标志Hex文件记录的结束。 02 扩展分片地址(Extended Segment Address) 该记录数据域定义了分片的基础地址,地址域为0x0000 :020000021200EA 03 分片起始地址(Start Segment Address) 该行数据域定义了分片的起始地址,地址域为0x0000 :0400000300003800C1 04 扩展线性地址(Extended Linear Address) 该行数据域定义了随后分片数据地址的高16位地址,使用00 和 02数据记录可以计算出分片数据的绝对地址,该地址域为0x0000 :02000004FFFFFC 05 起始线性地址(Start Linear Address) 该数据域定义了起始线性地址,该地址域为0x0000 :04000005080060EDA2 对使用不同宽度地址而言,其使用Hex记录类型也不一样,对16位宽度的地址而言,其使用00和01类型的数据记录;对20位宽度的地址而言,其使用00、01、02、03类型的数据记录;对32位宽度的地址而言,其使用 00、01、04、05类型的数据记录。
Data: Data为2*n个16进制的ASCII数字(n字节数据)。 Checksum: Checksum为2个16进制的ASCII数字,用于校验该行数据的完整性。该校验算法为将Byte count、Address、Record type、Data域的值进行相加,取低8位的和,然后取和的互补值(取反加1)作为校验值,比如hex文件中某hex记录为 :020000040800F2,其数据和为:02 + 00 + 00 + 04 + 08 + 00 = 0E,0E的互补值为F2,因此该行数据记录的校验值为F2。
HEX数据记录以 行结束符 作为记录的结束,对不同的操作系统而言其行结束符是不一样的,比如对于Windows操作系统而言,其行结束符为CR LF(0x0D 0x0A)(‘\r’ ‘\n’),对于Linux操作系统而言,其行结束符为LF。
4、区别: Bin格式、Motorola格式、Hex格式的区别如下表所示:
Bin格式 Motorola格式 Hex格式 文件格式 二进制 ASCII ASCII 文件大小 小 大 大 是否带有地址信息 无 有 有 程序地址格式 无 绝对地址 相对地址 内容校验 无 有 有
5、格式解析代码: motorola和hex解析头文件为ProgramFileDecode.h,其内容如下所示: #ifndef __PROGRAM_FILE_DECODE_H #define __PROGRAM_FILE_DECODE_H #define PROGRAM_ARGUMENT_ERROR (-1) #define PROGRAM_UNKNOWN_CONTENT (-2) #define PROGRAM_S19_RECORD_UNKNOWN_ERROR (-3) #define PROGRAM_S19_RECORD_CHECKSUM_ERROR (-4) #define PROGRAM_HEX_RECORD_UNKNOWN_ERROR (-3) #define PROGRAM_HEX_RECORD_CHECKSUM_ERROR (-4) #define PROGRAM_ADDRESS_OVERLAP_ERROR (-5) #define SUPPORT_MAX_SEGMENT (100) #define SUPPORT_SEGMENT_SIZE (0xFFFF) typedef struct { uint8_t* data[SUPPORT_MAX_SEGMENT]; int dataLen[SUPPORT_MAX_SEGMENT]; uint32_t address[SUPPORT_MAX_SEGMENT]; int segmentNum; }ProgramSegment; typedef enum { START_OUT_END_OUT=0, START_OUT_END_IN, START_IN_END_IN, START_IN_END_OUT, START_OUT_END_OUT1 }ADDR_STATE; extern ProgramSegment gProgramSegment; int ProgramFileDecode(char *program,int programLen,uint32_t startAddress,uint32_t endAddress,ProgramSegment *segment); #endif 其C文件内容如下所示: #include #include "ProgramFileDecode.h" int gS4_Error = 0; uint8_t gU1_ProgramData[SUPPORT_MAX_SEGMENT * SUPPORT_SEGMENT_SIZE]; uint32_t gU4_ProgramDataUsedCnt = 0;//用于计数gU1_ProgramData的使用数目 char gU1_RecordArray[512]; uint32_t gU4_RecordArrayLen=0; uint8_t gU1_RecordArrayBinValue[256]; uint8_t gU1_RecordData[256]; uint8_t gU1_RecordType=0,gU1_ByteCount = 0,gU1_DataLen = 0; uint32_t gU4_AddressStart=0; uint32_t gU4_AddressEnd=0; uint32_t gU4_AddressEndLast=0; ADDR_STATE addressState = START_OUT_END_OUT; uint32_t gU4_IgnoreByteCnt=0; uint32_t gU4_PaddingByteLen=0; uint32_t gU4_ValidDataLen = 0; uint32_t gU4_ProgramDataLen=0; uint8_t gU1_MemoryBusWith = 1; int gS4_AddressWidth = 1; int gS4_EndLineCharType = 0; int gS4_PaddingSwitch = 0; int gU1_PaddingValue = 0xFF; ProgramSegment gProgramSegment; void ProgramDecodeModeSet(int addressWidth,int endLineCharType,int paddingSwitch,uint8_t paddingValue) { gS4_AddressWidth = addressWidth; gS4_EndLineCharType = endLineCharType; gS4_PaddingSwitch = paddingSwitch; gU1_PaddingValue = paddingValue; } char *getARecord(char *str,char *record,unsigned int *recordLen) { char *pLF,*pCR; size_t len=0; if(((*str) == 'S') || ((*str) == ':')) { pLF = strchr(str,10); pCR = pLF-1; if((*pCR) == 13) { //Windows system len = (size_t)(pCR - str); strncpy(record,str,len); } else { //Linux system len = (size_t)(pLF - str); strncpy(record,str,len); } record[len]=0; *recordLen = len; return (++pLF); } else return 0; } uint32_t getValueFromArray(uint8_t *data,int len) { int i; uint32_t value=0; if(len > 4) return 0; value = 0; for(i=0;i int i,j,byteCnt; uint8_t hexValue=0; byteCnt=len / 2;//字符串的长度必须为2的整数倍 hexValue=0; for(j=0;j if(str[i] >= '0' && str[i] hexValue=hexValue * 16 + (10 + str[i] - 'a'); } else if(str[i] >= 'A' && str[i] uint8_t type=0,byteCountTemp=0,addressAndCountLen=0; uint8_t checkSumOrigion = 0,checkSumCal = 0; uint8_t binValueArrayLen = 0; int i; if(record[0] == 'S') { type = record[1] - '0'; if(type > 9) return PROGRAM_S19_RECORD_UNKNOWN_ERROR; *recordType = type; binValueArrayLen = (uint8_t)getBinValueFromHexAsciiArray(&record[2],recordLen - 2,gU1_RecordArrayBinValue); byteCountTemp = gU1_RecordArrayBinValue[0]; if(byteCountTemp < 3) return PROGRAM_S19_RECORD_UNKNOWN_ERROR; *byteCount = byteCountTemp; checkSumOrigion = (uint8_t)getValueFromArray(&gU1_RecordArrayBinValue[1 + byteCountTemp - 1],1); checkSumCal = 0; for(i=0;i case 0: addressAndCountLen = 2; break; case 1: addressAndCountLen = 2; break; case 2: addressAndCountLen = 3; break; case 3: addressAndCountLen = 4; break; case 4: //TODO return break; case 5: addressAndCountLen = 2; break; case 6: addressAndCountLen = 3; break; case 7: addressAndCountLen = 4; break; case 8: addressAndCountLen = 3; break; case 9: addressAndCountLen = 2; break; default: //TODO return return PROGRAM_S19_RECORD_UNKNOWN_ERROR; break; } *address = getValueFromArray(&gU1_RecordArrayBinValue[1],addressAndCountLen); memcpy(data,&gU1_RecordArrayBinValue[1 + addressAndCountLen],byteCountTemp - addressAndCountLen -1); *dataLen = binValueArrayLen - 2 - addressAndCountLen; return 0; } else { return PROGRAM_S19_RECORD_UNKNOWN_ERROR; } } int getHexRecordInfo(char *record,int recordLen,uint8_t *byteCount,uint32_t *address,uint8_t *recordType,uint8_t *data,uint8_t *dataLen) { uint8_t byteCountTemp=0; uint8_t checkSumOrigion = 0,checkSumCal = 0; int i; if(record[0] == ':') { getBinValueFromHexAsciiArray(&record[1],recordLen - 1,gU1_RecordArrayBinValue); byteCountTemp = (uint8_t)getValueFromArray(gU1_RecordArrayBinValue,1); checkSumOrigion = (uint8_t)getValueFromArray(&gU1_RecordArrayBinValue[4 + byteCountTemp],1); checkSumCal = 0; for(i=0;i return PROGRAM_HEX_RECORD_UNKNOWN_ERROR; } } int ProgramFileDecode(char *program,int programLen,uint32_t startAddress,uint32_t endAddress,ProgramSegment *segment) { char *pNextRecord; char *pEndRecord; uint8_t *programData = NULL; uint32_t programSegmentLen = 0; uint32_t extendedLinearAddr = 0; gS4_Error = 0; if((program == NULL) || (startAddress >= endAddress) || (segment == NULL)) { gS4_Error = PROGRAM_ARGUMENT_ERROR; return gS4_Error; } pNextRecord = program; pEndRecord = &program[programLen]; gU4_ProgramDataLen =0; gU4_AddressEndLast = 0; gU4_ValidDataLen = 0; gU4_IgnoreByteCnt = 0; extendedLinearAddr = 0; while(pNextRecord < pEndRecord) { pNextRecord = getARecord(pNextRecord,gU1_RecordArray,&gU4_RecordArrayLen); if(pNextRecord == 0) { break; } if(gU1_RecordArray[0] == 'S') { gS4_Error = getMotorolaRecordInfo(gU1_RecordArray,gU4_RecordArrayLen,&gU1_RecordType,&gU1_ByteCount,&gU4_AddressStart,gU1_RecordData,&gU1_DataLen); if(gS4_Error < 0) { //Some error happend return gS4_Error; } gU1_DataLen = gU1_DataLen / gU1_MemoryBusWith; gU4_AddressEnd =gU4_AddressStart + gU1_DataLen - 1; //Program data switch(gU1_RecordType) { //Header case 0: break; //Data case 1: case 2: case 3: if(gU4_AddressStart < startAddress) { if(gU4_AddressEnd < startAddress) addressState = START_OUT_END_OUT; else addressState = START_OUT_END_IN; } else if(gU4_AddressStart addressState = START_OUT_END_OUT1; } switch(addressState) { case START_OUT_END_OUT: gU4_IgnoreByteCnt = gU4_IgnoreByteCnt + gU1_DataLen; break; case START_OUT_END_IN: gU4_ProgramDataUsedCnt = 0; programSegmentLen = 0; segment->segmentNum = 1; segment->address[segment->segmentNum - 1] = startAddress; segment->data[segment->segmentNum - 1] = &gU1_ProgramData[0]; programData = segment->data[segment->segmentNum - 1]; gU4_ValidDataLen = gU4_AddressEnd - startAddress + 1; memcpy(&programData[0],&gU1_RecordData[(gU1_DataLen - gU4_ValidDataLen) * gU1_MemoryBusWith],gU4_ValidDataLen*gU1_MemoryBusWith); programSegmentLen = gU4_ValidDataLen * gU1_MemoryBusWith; segment->dataLen[segment->segmentNum - 1] = programSegmentLen; gU4_AddressEndLast = gU4_AddressEnd; break; case START_IN_END_IN: if(gU4_AddressEndLast == 0)//首个分片 { gU4_ProgramDataUsedCnt = 0; programSegmentLen = 0; segment->segmentNum = 1; segment->address[segment->segmentNum - 1] = startAddress; segment->data[segment->segmentNum - 1] = &gU1_ProgramData[0]; programData = segment->data[segment->segmentNum - 1]; } else if((gU4_AddressEndLast + 1) < gU4_AddressStart)//出现新的程序分片 { gU4_ProgramDataUsedCnt = gU4_ProgramDataUsedCnt + programSegmentLen; programSegmentLen = 0; segment->segmentNum++; segment->address[segment->segmentNum - 1] = gU4_AddressStart; segment->data[segment->segmentNum - 1] = &gU1_ProgramData[gU4_ProgramDataUsedCnt]; programData = segment->data[segment->segmentNum - 1]; } else if((gU4_AddressEndLast + 1) == gU4_AddressStart)//地址连续 { } else//出现错误,地址冲突 { gS4_Error = PROGRAM_ADDRESS_OVERLAP_ERROR; return gS4_Error; } gU4_ValidDataLen = gU1_DataLen; memcpy(&programData[programSegmentLen],&gU1_RecordData[0],gU4_ValidDataLen*gU1_MemoryBusWith); programSegmentLen = programSegmentLen + gU4_ValidDataLen * gU1_MemoryBusWith; segment->dataLen[segment->segmentNum - 1] = programSegmentLen; gU4_AddressEndLast = gU4_AddressEnd; break; case START_IN_END_OUT: if(gU4_AddressEndLast == 0)//首个分片 { gU4_ProgramDataUsedCnt = 0; programSegmentLen = 0; segment->segmentNum = 1; segment->address[segment->segmentNum - 1] = startAddress; segment->data[segment->segmentNum - 1] = &gU1_ProgramData[0]; programData = segment->data[segment->segmentNum - 1]; } else if((gU4_AddressEndLast + 1) < gU4_AddressStart)//出现新的程序分片 { gU4_ProgramDataUsedCnt = gU4_ProgramDataUsedCnt + segment->dataLen[segment->segmentNum - 1]; programSegmentLen = 0; segment->segmentNum++; segment->address[segment->segmentNum - 1] = gU4_AddressStart; segment->data[segment->segmentNum - 1] = &gU1_ProgramData[gU4_ProgramDataUsedCnt]; programData = segment->data[segment->segmentNum - 1]; } else if((gU4_AddressEndLast + 1) == gU4_AddressStart)//地址连续 { } else//出现错误,地址冲突 { gS4_Error = PROGRAM_ADDRESS_OVERLAP_ERROR; return gS4_Error; } gU4_ValidDataLen = endAddress - gU4_AddressStart + 1; memcpy(&programData[programSegmentLen],&gU1_RecordData[0],gU4_ValidDataLen*gU1_MemoryBusWith); programSegmentLen = programSegmentLen + gU4_ValidDataLen * gU1_MemoryBusWith; segment->dataLen[segment->segmentNum - 1] = programSegmentLen; gU4_ProgramDataUsedCnt = gU4_ProgramDataUsedCnt + programSegmentLen; gU4_AddressEndLast = gU4_AddressEnd; break; case START_OUT_END_OUT1: break; default: ; break; } break; //Reserve case 4: break; //Count case 5: case 6: break; //End flag case 7: case 8: case 9: break; default: ; } } else if(gU1_RecordArray[0] == ':') { gS4_Error = getHexRecordInfo(gU1_RecordArray,gU4_RecordArrayLen,&gU1_ByteCount,&gU4_AddressStart,&gU1_RecordType,gU1_RecordData,&gU1_DataLen); if(gS4_Error < 0) { return gS4_Error; } switch(gU1_RecordType) { //Data case 0: gU4_AddressStart = gU4_AddressStart + extendedLinearAddr; gU1_DataLen = gU1_DataLen / gU1_MemoryBusWith; gU4_AddressEnd =gU4_AddressStart + gU1_DataLen - 1; if(gU4_AddressStart < startAddress) { if(gU4_AddressEnd < startAddress) addressState = START_OUT_END_OUT; else addressState = START_OUT_END_IN; } else if(gU4_AddressStart addressState = START_OUT_END_OUT1; } switch(addressState) { case START_OUT_END_OUT: gU4_IgnoreByteCnt = gU4_IgnoreByteCnt + gU1_DataLen; break; case START_OUT_END_IN: gU4_ProgramDataUsedCnt = 0; programSegmentLen = 0; segment->segmentNum = 1; segment->address[segment->segmentNum - 1] = startAddress; segment->data[segment->segmentNum - 1] = &gU1_ProgramData[0]; programData = segment->data[segment->segmentNum - 1]; gU4_ValidDataLen = gU4_AddressEnd - startAddress + 1; memcpy(&programData[0],&gU1_RecordData[(gU1_DataLen - gU4_ValidDataLen) * gU1_MemoryBusWith],gU4_ValidDataLen*gU1_MemoryBusWith); programSegmentLen = gU4_ValidDataLen * gU1_MemoryBusWith; segment->dataLen[segment->segmentNum - 1] = programSegmentLen; gU4_AddressEndLast = gU4_AddressEnd; break; case START_IN_END_IN: if(gU4_AddressEndLast == 0)//首个分片 { gU4_ProgramDataUsedCnt = 0; programSegmentLen = 0; segment->segmentNum = 1; segment->address[segment->segmentNum - 1] = startAddress; segment->data[segment->segmentNum - 1] = &gU1_ProgramData[0]; programData = segment->data[segment->segmentNum - 1]; } else if((gU4_AddressEndLast + 1) < gU4_AddressStart)//出现新的程序分片 { gU4_ProgramDataUsedCnt = gU4_ProgramDataUsedCnt + segment->dataLen[segment->segmentNum - 1]; programSegmentLen = 0; segment->segmentNum++; segment->address[segment->segmentNum - 1] = gU4_AddressStart; segment->data[segment->segmentNum - 1] = &gU1_ProgramData[gU4_ProgramDataUsedCnt]; programData = segment->data[segment->segmentNum - 1]; } else if((gU4_AddressEndLast + 1) == gU4_AddressStart)//地址连续 { } else//出现错误,地址冲突 { gS4_Error = PROGRAM_ADDRESS_OVERLAP_ERROR; return gS4_Error; } gU4_ValidDataLen = gU1_DataLen; memcpy(&programData[programSegmentLen],&gU1_RecordData[0],gU4_ValidDataLen*gU1_MemoryBusWith); programSegmentLen = programSegmentLen + gU4_ValidDataLen * gU1_MemoryBusWith; segment->dataLen[segment->segmentNum - 1] = programSegmentLen; gU4_AddressEndLast = gU4_AddressEnd; break; case START_IN_END_OUT: if(gU4_AddressEndLast == 0)//首个分片 { gU4_ProgramDataUsedCnt = 0; programSegmentLen = 0; segment->segmentNum = 1; segment->address[segment->segmentNum - 1] = startAddress; segment->data[segment->segmentNum - 1] = &gU1_ProgramData[0]; programData = segment->data[segment->segmentNum - 1]; } else if((gU4_AddressEndLast + 1) < gU4_AddressStart)//出现新的程序分片 { gU4_ProgramDataUsedCnt = gU4_ProgramDataUsedCnt + segment->dataLen[segment->segmentNum - 1]; programSegmentLen = 0; segment->segmentNum++; segment->address[segment->segmentNum - 1] = gU4_AddressStart; segment->data[segment->segmentNum - 1] = &gU1_ProgramData[gU4_ProgramDataUsedCnt]; programData = segment->data[segment->segmentNum - 1]; } else if((gU4_AddressEndLast + 1) == gU4_AddressStart)//地址连续 { } else//出现错误,地址冲突 { gS4_Error = PROGRAM_ADDRESS_OVERLAP_ERROR; return gS4_Error; } gU4_ValidDataLen = endAddress - gU4_AddressStart + 1; memcpy(&programData[programSegmentLen],&gU1_RecordData[0],gU4_ValidDataLen*gU1_MemoryBusWith); programSegmentLen = programSegmentLen + gU4_ValidDataLen * gU1_MemoryBusWith; segment->dataLen[segment->segmentNum - 1] = programSegmentLen; gU4_AddressEndLast = gU4_AddressEnd; break; case START_OUT_END_OUT1: break; default: ; break; } break; //End of file case 1: break; //Extended segment address case 2: break; //Start segment address case 3: break; //Extended linear address case 4: extendedLinearAddr = ((gU1_RecordData[0] int n; ssize_t size; int fileHandle = 0; int ret = 0; int k = 0; n = GetFileInfo(programFilePath,&size); fileHandle = OpenFile(programFilePath,VAL_READ_ONLY,VAL_OPEN_AS_IS,VAL_BINARY ); ret = ReadFile(fileHandle,hexFileContent,size); if(ret != size) { DebugInfo(LEVEL_ERROR,"Read program file failed\r\n"); } ProgramFileDecode(hexFileContent,size,gU4_FlashStartAddr,gU4_FlashEndAddr,&gProgramSegment); GetPageAddress(gProgramSegment.address[0],gU4_FlashPageSize,&gU4_ProgramStartPageAddress); GetPageAddress(gProgramSegment.address[gProgramSegment.segmentNum - 1] + gProgramSegment.dataLen[gProgramSegment.segmentNum - 1],gU4_FlashPageSize,&gU4_ProgramEndPageAddress); gU4_ProgramEndPageAddress = gU4_ProgramEndPageAddress + gU4_FlashPageSize - 1; //DebugInfo(LEVEL_NORMAL,"StartPageAddress = 0x%X,EndPageAddress = 0x%X\r\n",gU4_ProgramStartPageAddress,gU4_ProgramEndPageAddress); if(gProgramSegment.address[0] != gU4_ProgramStartPageAddress) { DebugInfo(LEVEL_WARNING,"Attention!.Program start address is not page address.\r\n"); } ProgramUpgrade1(&programUpgradeCancel); return 0; }
|
今日新闻 |
推荐新闻 |
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 |