hex2bin附源代码

2019-04-15 15:21发布

在做pic的mcu升级功能时发现mplab居然不能输出bin格式,只好自己用C写了个小工具把hex转成bin,已在pic24和pic32平台下测试过。编译器用的mingw,使用C标准库应该很容易在linux编译使用,不过没有测试过,毕竟mcu的开发环境大部分是windows的。 GenericTypeDefs.h 头文件和hex解析部分用的pic的官方驱动中的代码,虽然速度比较快,但是移植到部分平台上会有大小端的问题。 #ifndef __GENERIC_TYPE_DEFS_H_ #define __GENERIC_TYPE_DEFS_H_ /* Specify an extension for GCC based compilers */ #if defined(__GNUC__) #define __EXTENSION __extension__ #else #define __EXTENSION #endif /* get compiler defined type definitions (NULL, size_t, etc) */ #include #define TRUE 1 #define FALSE 0 typedef unsigned char BOOL; /* INT is processor specific in length may vary in size */ typedef signed int INT; typedef signed char INT8; typedef signed short int INT16; typedef signed long int INT32; /* MPLAB C Compiler for PIC18 does not support 64-bit integers */ #if !defined(__18CXX) __EXTENSION typedef signed long long INT64; #endif /* UINT is processor specific in length may vary in size */ typedef unsigned int UINT; typedef unsigned char UINT8; typedef unsigned short int UINT16; /* 24-bit type only available on C18 */ #if defined(__18CXX) typedef unsigned short long UINT24; #endif typedef unsigned long int UINT32; /* other name for 32-bit integer */ /* MPLAB C Compiler for PIC18 does not support 64-bit integers */ #if !defined(__18CXX) __EXTENSION typedef unsigned long long UINT64; #endif typedef union { UINT8 Val; struct { __EXTENSION UINT8 b0:1; __EXTENSION UINT8 b1:1; __EXTENSION UINT8 b2:1; __EXTENSION UINT8 b3:1; __EXTENSION UINT8 b4:1; __EXTENSION UINT8 b5:1; __EXTENSION UINT8 b6:1; __EXTENSION UINT8 b7:1; } bits; } UINT8_VAL, UINT8_BITS; typedef union { UINT16 Val; UINT8 v[2]; struct { UINT8 LB; UINT8 HB; } byte; struct { __EXTENSION UINT8 b0:1; __EXTENSION UINT8 b1:1; __EXTENSION UINT8 b2:1; __EXTENSION UINT8 b3:1; __EXTENSION UINT8 b4:1; __EXTENSION UINT8 b5:1; __EXTENSION UINT8 b6:1; __EXTENSION UINT8 b7:1; __EXTENSION UINT8 b8:1; __EXTENSION UINT8 b9:1; __EXTENSION UINT8 b10:1; __EXTENSION UINT8 b11:1; __EXTENSION UINT8 b12:1; __EXTENSION UINT8 b13:1; __EXTENSION UINT8 b14:1; __EXTENSION UINT8 b15:1; } bits; } UINT16_VAL, UINT16_BITS; /* 24-bit type only available on C18 */ #if defined(__18CXX) typedef union { UINT24 Val; UINT8 v[3]; struct { UINT8 LB; UINT8 HB; UINT8 UB; } byte; struct { __EXTENSION UINT8 b0:1; __EXTENSION UINT8 b1:1; __EXTENSION UINT8 b2:1; __EXTENSION UINT8 b3:1; __EXTENSION UINT8 b4:1; __EXTENSION UINT8 b5:1; __EXTENSION UINT8 b6:1; __EXTENSION UINT8 b7:1; __EXTENSION UINT8 b8:1; __EXTENSION UINT8 b9:1; __EXTENSION UINT8 b10:1; __EXTENSION UINT8 b11:1; __EXTENSION UINT8 b12:1; __EXTENSION UINT8 b13:1; __EXTENSION UINT8 b14:1; __EXTENSION UINT8 b15:1; __EXTENSION UINT8 b16:1; __EXTENSION UINT8 b17:1; __EXTENSION UINT8 b18:1; __EXTENSION UINT8 b19:1; __EXTENSION UINT8 b20:1; __EXTENSION UINT8 b21:1; __EXTENSION UINT8 b22:1; __EXTENSION UINT8 b23:1; } bits; } UINT24_VAL, UINT24_BITS; #endif typedef union { UINT32 Val; UINT16 w[2]; UINT8 v[4]; struct { UINT16 LW; UINT16 HW; } word; struct { UINT8 LB; UINT8 HB; UINT8 UB; UINT8 MB; } byte; struct { UINT16_VAL low; UINT16_VAL high; }wordUnion; struct { __EXTENSION UINT8 b0:1; __EXTENSION UINT8 b1:1; __EXTENSION UINT8 b2:1; __EXTENSION UINT8 b3:1; __EXTENSION UINT8 b4:1; __EXTENSION UINT8 b5:1; __EXTENSION UINT8 b6:1; __EXTENSION UINT8 b7:1; __EXTENSION UINT8 b8:1; __EXTENSION UINT8 b9:1; __EXTENSION UINT8 b10:1; __EXTENSION UINT8 b11:1; __EXTENSION UINT8 b12:1; __EXTENSION UINT8 b13:1; __EXTENSION UINT8 b14:1; __EXTENSION UINT8 b15:1; __EXTENSION UINT8 b16:1; __EXTENSION UINT8 b17:1; __EXTENSION UINT8 b18:1; __EXTENSION UINT8 b19:1; __EXTENSION UINT8 b20:1; __EXTENSION UINT8 b21:1; __EXTENSION UINT8 b22:1; __EXTENSION UINT8 b23:1; __EXTENSION UINT8 b24:1; __EXTENSION UINT8 b25:1; __EXTENSION UINT8 b26:1; __EXTENSION UINT8 b27:1; __EXTENSION UINT8 b28:1; __EXTENSION UINT8 b29:1; __EXTENSION UINT8 b30:1; __EXTENSION UINT8 b31:1; } bits; } UINT32_VAL; /* MPLAB C Compiler for PIC18 does not support 64-bit integers */ #if !defined(__18CXX) typedef union { UINT64 Val; UINT32 d[2]; UINT16 w[4]; UINT8 v[8]; struct { UINT32 LD; UINT32 HD; } dword; struct { UINT16 LW; UINT16 HW; UINT16 UW; UINT16 MW; } word; struct { __EXTENSION UINT8 b0:1; __EXTENSION UINT8 b1:1; __EXTENSION UINT8 b2:1; __EXTENSION UINT8 b3:1; __EXTENSION UINT8 b4:1; __EXTENSION UINT8 b5:1; __EXTENSION UINT8 b6:1; __EXTENSION UINT8 b7:1; __EXTENSION UINT8 b8:1; __EXTENSION UINT8 b9:1; __EXTENSION UINT8 b10:1; __EXTENSION UINT8 b11:1; __EXTENSION UINT8 b12:1; __EXTENSION UINT8 b13:1; __EXTENSION UINT8 b14:1; __EXTENSION UINT8 b15:1; __EXTENSION UINT8 b16:1; __EXTENSION UINT8 b17:1; __EXTENSION UINT8 b18:1; __EXTENSION UINT8 b19:1; __EXTENSION UINT8 b20:1; __EXTENSION UINT8 b21:1; __EXTENSION UINT8 b22:1; __EXTENSION UINT8 b23:1; __EXTENSION UINT8 b24:1; __EXTENSION UINT8 b25:1; __EXTENSION UINT8 b26:1; __EXTENSION UINT8 b27:1; __EXTENSION UINT8 b28:1; __EXTENSION UINT8 b29:1; __EXTENSION UINT8 b30:1; __EXTENSION UINT8 b31:1; __EXTENSION UINT8 b32:1; __EXTENSION UINT8 b33:1; __EXTENSION UINT8 b34:1; __EXTENSION UINT8 b35:1; __EXTENSION UINT8 b36:1; __EXTENSION UINT8 b37:1; __EXTENSION UINT8 b38:1; __EXTENSION UINT8 b39:1; __EXTENSION UINT8 b40:1; __EXTENSION UINT8 b41:1; __EXTENSION UINT8 b42:1; __EXTENSION UINT8 b43:1; __EXTENSION UINT8 b44:1; __EXTENSION UINT8 b45:1; __EXTENSION UINT8 b46:1; __EXTENSION UINT8 b47:1; __EXTENSION UINT8 b48:1; __EXTENSION UINT8 b49:1; __EXTENSION UINT8 b50:1; __EXTENSION UINT8 b51:1; __EXTENSION UINT8 b52:1; __EXTENSION UINT8 b53:1; __EXTENSION UINT8 b54:1; __EXTENSION UINT8 b55:1; __EXTENSION UINT8 b56:1; __EXTENSION UINT8 b57:1; __EXTENSION UINT8 b58:1; __EXTENSION UINT8 b59:1; __EXTENSION UINT8 b60:1; __EXTENSION UINT8 b61:1; __EXTENSION UINT8 b62:1; __EXTENSION UINT8 b63:1; } bits; } UINT64_VAL; #endif /* __18CXX */ /***********************************************************************************/ /* Alternate definitions */ typedef void VOID; typedef char CHAR8; typedef unsigned char UCHAR8; typedef unsigned char BYTE; /* 8-bit unsigned */ typedef unsigned short int WORD; /* 16-bit unsigned */ typedef unsigned long DWORD; /* 32-bit unsigned */ /* MPLAB C Compiler for PIC18 does not support 64-bit integers */ #if !defined(__18CXX) __EXTENSION typedef unsigned long long QWORD; /* 64-bit unsigned */ #endif /* __18CXX */ typedef signed char CHAR; /* 8-bit signed */ typedef signed short int SHORT; /* 16-bit signed */ typedef signed long LONG; /* 32-bit signed */ /* MPLAB C Compiler for PIC18 does not support 64-bit integers */ #if !defined(__18CXX) __EXTENSION typedef signed long long LONGLONG; /* 64-bit signed */ #endif /* __18CXX */ typedef union { BYTE Val; struct { __EXTENSION BYTE b0:1; __EXTENSION BYTE b1:1; __EXTENSION BYTE b2:1; __EXTENSION BYTE b3:1; __EXTENSION BYTE b4:1; __EXTENSION BYTE b5:1; __EXTENSION BYTE b6:1; __EXTENSION BYTE b7:1; } bits; } BYTE_VAL, BYTE_BITS; typedef union { WORD Val; BYTE v[2]; struct { BYTE LB; BYTE HB; } byte; struct { __EXTENSION BYTE b0:1; __EXTENSION BYTE b1:1; __EXTENSION BYTE b2:1; __EXTENSION BYTE b3:1; __EXTENSION BYTE b4:1; __EXTENSION BYTE b5:1; __EXTENSION BYTE b6:1; __EXTENSION BYTE b7:1; __EXTENSION BYTE b8:1; __EXTENSION BYTE b9:1; __EXTENSION BYTE b10:1; __EXTENSION BYTE b11:1; __EXTENSION BYTE b12:1; __EXTENSION BYTE b13:1; __EXTENSION BYTE b14:1; __EXTENSION BYTE b15:1; } bits; } WORD_VAL, WORD_BITS; typedef union { DWORD Val; WORD w[2]; BYTE v[4]; struct { WORD LW; WORD HW; } word; struct { BYTE LB; BYTE HB; BYTE UB; BYTE MB; } byte; struct { WORD_VAL low; WORD_VAL high; }wordUnion; struct { __EXTENSION BYTE b0:1; __EXTENSION BYTE b1:1; __EXTENSION BYTE b2:1; __EXTENSION BYTE b3:1; __EXTENSION BYTE b4:1; __EXTENSION BYTE b5:1; __EXTENSION BYTE b6:1; __EXTENSION BYTE b7:1; __EXTENSION BYTE b8:1; __EXTENSION BYTE b9:1; __EXTENSION BYTE b10:1; __EXTENSION BYTE b11:1; __EXTENSION BYTE b12:1; __EXTENSION BYTE b13:1; __EXTENSION BYTE b14:1; __EXTENSION BYTE b15:1; __EXTENSION BYTE b16:1; __EXTENSION BYTE b17:1; __EXTENSION BYTE b18:1; __EXTENSION BYTE b19:1; __EXTENSION BYTE b20:1; __EXTENSION BYTE b21:1; __EXTENSION BYTE b22:1; __EXTENSION BYTE b23:1; __EXTENSION BYTE b24:1; __EXTENSION BYTE b25:1; __EXTENSION BYTE b26:1; __EXTENSION BYTE b27:1; __EXTENSION BYTE b28:1; __EXTENSION BYTE b29:1; __EXTENSION BYTE b30:1; __EXTENSION BYTE b31:1; } bits; } DWORD_VAL; /* MPLAB C Compiler for PIC18 does not support 64-bit integers */ #if !defined(__18CXX) typedef union { QWORD Val; DWORD d[2]; WORD w[4]; BYTE v[8]; struct { DWORD LD; DWORD HD; } dword; struct { WORD LW; WORD HW; WORD UW; WORD MW; } word; struct { __EXTENSION BYTE b0:1; __EXTENSION BYTE b1:1; __EXTENSION BYTE b2:1; __EXTENSION BYTE b3:1; __EXTENSION BYTE b4:1; __EXTENSION BYTE b5:1; __EXTENSION BYTE b6:1; __EXTENSION BYTE b7:1; __EXTENSION BYTE b8:1; __EXTENSION BYTE b9:1; __EXTENSION BYTE b10:1; __EXTENSION BYTE b11:1; __EXTENSION BYTE b12:1; __EXTENSION BYTE b13:1; __EXTENSION BYTE b14:1; __EXTENSION BYTE b15:1; __EXTENSION BYTE b16:1; __EXTENSION BYTE b17:1; __EXTENSION BYTE b18:1; __EXTENSION BYTE b19:1; __EXTENSION BYTE b20:1; __EXTENSION BYTE b21:1; __EXTENSION BYTE b22:1; __EXTENSION BYTE b23:1; __EXTENSION BYTE b24:1; __EXTENSION BYTE b25:1; __EXTENSION BYTE b26:1; __EXTENSION BYTE b27:1; __EXTENSION BYTE b28:1; __EXTENSION BYTE b29:1; __EXTENSION BYTE b30:1; __EXTENSION BYTE b31:1; __EXTENSION BYTE b32:1; __EXTENSION BYTE b33:1; __EXTENSION BYTE b34:1; __EXTENSION BYTE b35:1; __EXTENSION BYTE b36:1; __EXTENSION BYTE b37:1; __EXTENSION BYTE b38:1; __EXTENSION BYTE b39:1; __EXTENSION BYTE b40:1; __EXTENSION BYTE b41:1; __EXTENSION BYTE b42:1; __EXTENSION BYTE b43:1; __EXTENSION BYTE b44:1; __EXTENSION BYTE b45:1; __EXTENSION BYTE b46:1; __EXTENSION BYTE b47:1; __EXTENSION BYTE b48:1; __EXTENSION BYTE b49:1; __EXTENSION BYTE b50:1; __EXTENSION BYTE b51:1; __EXTENSION BYTE b52:1; __EXTENSION BYTE b53:1; __EXTENSION BYTE b54:1; __EXTENSION BYTE b55:1; __EXTENSION BYTE b56:1; __EXTENSION BYTE b57:1; __EXTENSION BYTE b58:1; __EXTENSION BYTE b59:1; __EXTENSION BYTE b60:1; __EXTENSION BYTE b61:1; __EXTENSION BYTE b62:1; __EXTENSION BYTE b63:1; } bits; } QWORD_VAL; #endif /* __18CXX */ #undef __EXTENSION #endif /* __GENERIC_TYPE_DEFS_H_ */
main.c 最大支持512K的Flash,代码稍作修改就可以支持1M或以上。 #include #include #include #include "GenericTypeDefs.h" #if 1 #define DBG_MSG printf #else #define DBG_MSG #endif #define AsciiToHexByte(m,l) ( (AsciiToHexNibble(m) << 4 ) | AsciiToHexNibble(l) ) #define READ_BUFFER_SIZE 512 // Record buffer array size #define MAX_RECORD_LENGTH 255 // Max Hex-Record Length (converted) // Buffer for reading image file data BYTE ReadBuffer[READ_BUFFER_SIZE]; // This structure holds the translated version of the hex record typedef struct { unsigned char RecordLength; // Length record data payload (adjusted unsigned int LoadOffset; // 16-bit offset to which the data will unsigned char RecordType; // Type of data in the record unsigned char data[MAX_RECORD_LENGTH] __attribute__ ((aligned (4))); // Record data buffer - needs to be 32-bit aligned so // that we can read 32-bit words out of it. unsigned char Checksum; // Checksum of the record } RECORD_STRUCT; // hexadecimal format data for transfer to aggregator typedef enum { RECORD_START_TOKEN = 0, RECORD_BYTE_COUNT_NIBBLE_1, RECORD_BYTE_COUNT_NIBBLE_0, RECORD_ADDRESS_NIBBLE_3, RECORD_ADDRESS_NIBBLE_2, RECORD_ADDRESS_NIBBLE_1, RECORD_ADDRESS_NIBBLE_0, RECORD_TYPE_NIBBLE_1, RECORD_TYPE_NIBBLE_0, RECORD_DATA, RECORD_CHECKSUM_NIBBLE_1, RECORD_CHECKSUM_NIBBLE_0 } RECORD_STATE; typedef enum { RECORD_TYPE_DATA_RECORD = 0x00, RECORD_TYPE_EOF = 0x01, RECORD_TYPE_EXTENDED_ADDRESS = 0x04 } RECORD_TYPE; #define BIN_FILE_MAX_LEN (512*1024) // max 512K // Stores the information about the current record RECORD_STRUCT current_record; RECORD_STATE record_state; // This field specifies which part of the UINT8 bin_buffer[BIN_FILE_MAX_LEN]; UINT32 bin_size; UINT32 bin_start_address; UINT32 bin_end_address; UINT32 bin_len; /**************************************************************************** Function: unsigned char AsciiToHexNibble(unsigned char data) Description: Converts an ASCII byte in the range of "0 - 9", "A - F", or "a - f" to a hex nibble Precondition: None Parameters: data - char containing the data to convert Returns: hex value represented by the input ASCII character (0x00 - 0x0F) 0 for input values out of range. Remarks: Example: value = AsciiToHexNibble('A'); // value = 0x0A ***************************************************************************/ unsigned char AsciiToHexNibble(unsigned char data) { if (data < '0') // return 0 for an invalid characters { return 0; } else if (data <= '9') // handle numbers { return ( data - '0' ); } else if (data < 'A') { return 0; } else if (data <= 'F') // handle uppercase letters { return ( data - 'A' + 10 ); } else if (data < 'a') { return 0; } else if (data <= 'f') // handle lowercase letters { return ( data - 'a' + 10 ); } else { return 0; } } // AsciiToHexNibble int ProgramHexRecord(RECORD_STRUCT* record, UINT32 address) { UINT8 *p; UINT32 i; if(address+(*record).RecordLength > BIN_FILE_MAX_LEN-1) { printf("address over 512K! 0x%lx ", address); return 0; } p = bin_buffer + address; for(i=0; i<(*record).RecordLength; i++) { *p++ = (*record).data[i]; } if(bin_size < ((*record).RecordLength+address)) { bin_size = ((*record).RecordLength+address); } return 0; } int ConvertFile(FILE *fp) { // record is currently being read. unsigned int nRemaining; // Number of bytes remaining to decode BYTE *p_file_data; WORD_VAL byteCountASCII; DWORD_VAL addressASCII; WORD_VAL recordTypeASCII; WORD_VAL checksumASCII; WORD_VAL dataByteASCII; DWORD_VAL totalAddress; WORD_VAL extendedAddress; BYTE calculated_checksum; BYTE recordDataCounter; BYTE byteEvenVsOdd; //Generic loop index. Needs to be a WORD since a record could be 255 bytes // and in this case written 4 bytes at a time. Thus the counts for that loop // would be 252 and 256. Since 256 can't be represented in a byte, a loop // counter of a byte could only count up to 252 bytes. WORD i; DWORD numRecordsProcessed; // Read the file and program it to Flash nRemaining = 0; record_state = RECORD_START_TOKEN; numRecordsProcessed = 0; //DBG_MSG("Start convert "); while(feof(fp) != EOF) { //Read in a BL_READ_BUFFER_SIZE block of data into the ReadBuffer. This // data will be processed in the following loop. Record the number of // bytes actually read into the nRemaining variable. This variable will // track the number of bytes remaining in the ReadBuffer. nRemaining = fread(&ReadBuffer[0], 1, READ_BUFFER_SIZE, fp ); if(nRemaining == 0) { //We weren't able to read any data from the file for some reason // even though the file stream indicated that it wasn't at the end // of the file. //printf("File error - unable to read data from file even though it was not reported as EOF. " ); break; } //point to the data read from the file p_file_data = (BYTE*) &ReadBuffer[0]; //process all of the data read so far... while(nRemaining) { switch(record_state) { case RECORD_START_TOKEN: //start code if(*p_file_data == ':') { //move to the first state of the byte count record_state = RECORD_BYTE_COUNT_NIBBLE_1; } else { //If we didn't see a start code ":" where we expected it, then //ignore line feeds and line returns if((*p_file_data != 0x0D) && (*p_file_data != 0x0A)) { //If there was anything other than a line feed or line return // then there was an error with the hex file. Abort the // loading operation. printf("Start code expected but not found. " ); return 1; } } //byte read from the buffer. Advance to the next position. p_file_data++; break; case RECORD_BYTE_COUNT_NIBBLE_1: //byte count byte 1 byteCountASCII.v[1] = *p_file_data++; //move to the next state of the byte count record_state = RECORD_BYTE_COUNT_NIBBLE_0; break; case RECORD_BYTE_COUNT_NIBBLE_0: //byte count byte 2 byteCountASCII.v[0] = *p_file_data++; current_record.RecordLength = AsciiToHexByte(byteCountASCII.v[1],byteCountASCII.v[0]); byteEvenVsOdd = 0; recordDataCounter = 0; //move to the first state of the address record_state = RECORD_ADDRESS_NIBBLE_3; break; case RECORD_ADDRESS_NIBBLE_3: //address byte 1 addressASCII.v[3] = *p_file_data++; //move to the next state of the address record_state = RECORD_ADDRESS_NIBBLE_2; break; case RECORD_ADDRESS_NIBBLE_2: //address byte 2 addressASCII.v[2] = *p_file_data++; //move to the next state of the address record_state = RECORD_ADDRESS_NIBBLE_1; break; case RECORD_ADDRESS_NIBBLE_1: //address byte 3 addressASCII.v[1] = *p_file_data++; //move to the next state of the address record_state = RECORD_ADDRESS_NIBBLE_0; break; case RECORD_ADDRESS_NIBBLE_0: //address byte 4 addressASCII.v[0] = *p_file_data++; current_record.LoadOffset = ((AsciiToHexByte(addressASCII.v[3],addressASCII.v[2]))<<8) + AsciiToHexByte(addressASCII.v[1],addressASCII.v[0]); //move to the first state of the type record_state = RECORD_TYPE_NIBBLE_1; break; case RECORD_TYPE_NIBBLE_1: //record type byte 1 recordTypeASCII.v[1] = *p_file_data++; //move to the next state of the type record_state = RECORD_TYPE_NIBBLE_0; break; case RECORD_TYPE_NIBBLE_0: //record type byte 2 recordTypeASCII.v[0] = *p_file_data++; current_record.RecordType = AsciiToHexByte(recordTypeASCII.v[1],recordTypeASCII.v[0]); if(current_record.RecordLength == 0) { //There is no data stage for this record. Proceed to the // checksum. record_state = RECORD_CHECKSUM_NIBBLE_1; } else { //move to the data state record_state = RECORD_DATA; } break; case RECORD_DATA: //data if(byteEvenVsOdd == 0) { dataByteASCII.v[1] = *p_file_data++; byteEvenVsOdd = 1; } else { dataByteASCII.v[0] = *p_file_data++; current_record.data[recordDataCounter++] = AsciiToHexByte(dataByteASCII.v[1],dataByteASCII.v[0]); byteEvenVsOdd = 0; } //If we have read all of the data, then move to the next state if(recordDataCounter == current_record.RecordLength) { record_state = RECORD_CHECKSUM_NIBBLE_1; } break; case RECORD_CHECKSUM_NIBBLE_1: //checksum byte 1 checksumASCII.v[1] = *p_file_data++; //move to the next state of the checksum record_state = RECORD_CHECKSUM_NIBBLE_0; break; case RECORD_CHECKSUM_NIBBLE_0: //checksum byte 2 checksumASCII.v[0] = *p_file_data++; current_record.Checksum = AsciiToHexByte(checksumASCII.v[1],checksumASCII.v[0]); numRecordsProcessed++; //Calculate the checksum of the data calculated_checksum = current_record.RecordLength + (current_record.LoadOffset&0xFF) + ((current_record.LoadOffset>>8)&0xFF) + current_record.RecordType; for(i=0;i= bin_start_address) { if(ProgramHexRecord(¤t_record, totalAddress.Val-bin_start_address)) { printf("USB:There was an error programming the data "); //There was an error programming the data. The // error status is already set by the ProgramHexRecord function // so we just need to close the file and exit here. return 1; } } else { DBG_MSG("hex_address(0x%lx) < start_address(0x%lx), ignored! ", totalAddress.Val, bin_start_address); //return 1; } break; case RECORD_TYPE_EOF: //FSfclose( fp ); break; case RECORD_TYPE_EXTENDED_ADDRESS: extendedAddress.v[1] = current_record.data[0]; extendedAddress.v[0] = current_record.data[1]; break; } //Move to the start token phase. This record is complete. // Start looking for the next record. record_state = RECORD_START_TOKEN; break; default: //If for some reason we are not in one of the predetermined // states, then exit. printf("Loader state machine in an unknown state. " ); return 1; } //We have finished processing this byte. There is now one less byte // in the ReadBuffer. nRemaining--; } } return 0; } UINT32 AsciiToHex(char *Strg) { UINT8 i; UINT32 Val=0; if ((Strg[0] == '0') && ((Strg[1] == 'x')||((Strg[1] == 'X')))) { Strg+= 2; } for (i=0; Strg[i]; i++) { if ((Strg[i] >= '0') && (Strg[i] <= '9')) { Val <<= 4; Val |= (Strg[i] - '0'); } else if ((Strg[i] >= 'a') && (Strg[i] <= 'f')) { Val <<= 4; Val |= (Strg[i] - 'a' + 10); } else if ((Strg[i] >= 'A') && (Strg[i] <= 'F')) { Val <<= 4; Val |= (Strg[i] - 'A' + 10); } else { break; } } return Val; } int main(int argc, char *argv[]) { #define HEX_FILE_NAME argv[1] FILE *fp_hex; FILE *fp_bin; char *bin_file_name; int bin_file_name_len; if(argc < 2) { printf("too few arguments: hex2bin.exe xxx.hex [start] [end] "); return 1; } // get bin file name bin_file_name_len = strlen(HEX_FILE_NAME); bin_file_name = (char *)malloc(bin_file_name_len+1); if(bin_file_name == NULL) { printf("can't malloc bin_file_name "); return 1; } strcpy(bin_file_name, HEX_FILE_NAME); if((bin_file_name[bin_file_name_len-3] != 'h') || (bin_file_name[bin_file_name_len-2] != 'e') || (bin_file_name[bin_file_name_len-1] != 'x')) { printf("hex2bin.exe xxx.hex [start] [end] "); return 1; } bin_file_name[bin_file_name_len-3] = 'b'; bin_file_name[bin_file_name_len-2] = 'i'; bin_file_name[bin_file_name_len-1] = 'n'; if((fp_hex=fopen(HEX_FILE_NAME, "r"))==NULL) { printf("Can't open %s! ", HEX_FILE_NAME); free(bin_file_name); return 1; } // convert bin_size = 0; bin_start_address = 0; bin_end_address = BIN_FILE_MAX_LEN-1; if(argc > 2) bin_start_address = AsciiToHex(argv[2]); if(argc > 3) bin_end_address = AsciiToHex(argv[3]); memset(bin_buffer, 0xFF, sizeof(bin_buffer)); if(ConvertFile(fp_hex)) { printf("Convert hex file failed! "); fclose(fp_hex); free(bin_file_name); return 1; } if((bin_end_address-bin_start_address) < bin_size) bin_size = (bin_end_address-bin_start_address); // save to bin file if((fp_bin=fopen(bin_file_name, "wb"))==NULL) { printf("Cannot open %s! ", bin_file_name); fclose(fp_hex); free(bin_file_name); return 1; } bin_len = bin_size; DBG_MSG("%s ", bin_file_name); DBG_MSG("start: 0x%lx ", bin_start_address); DBG_MSG("end: 0x%lx ", bin_size); DBG_MSG("length: 0x%lx, %ldK ", bin_len, bin_len/1024); if(fwrite(&bin_buffer[0], 1, bin_len, fp_bin) != bin_len) { printf("Write %s failed! ", bin_file_name); } fclose(fp_hex); fclose(fp_bin); free(bin_file_name); return 0; }
biuld.bat 类似makefile功能的脚本,偷懒用的偷笑,安装目录自己根据需要修改。 @echo off set install_dir=D:"Program Files"hex2bin :start echo m: make echo i: install echo c: clear echo x: exit set /p cho=input: if /i "%cho%"=="m" goto make if /i "%cho%"=="i" goto install if /i "%cho%"=="x" goto out if /i "%cho%"=="c" goto clear echo Invalid input! echo. goto start :make gcc -Wall main.c -o hex2bin echo. goto start :install if not exist %install_dir% mkdir %install_dir% if not exist hex2bin.exe gcc -Wall main.c -o hex2bin if exist hex2bin.exe copy hex2bin.exe %install_dir% echo Install successed! echo. goto start :clear if exist hex2bin.exe del hex2bin.exe if exist %install_dir% rd /s /q %install_dir% echo. goto start :out exit
creatbin.bat hex2bin.exe最少需要2个参数,转换的文件名和起始地址,第3个参数结束地址可选。编译安装完hex2bin之后,在mplab等mcu开发工具中直接调用此脚本就可以了。 @echo off D:"Program Files"hex2binhex2bin.exe mcu123.hex D000 2A800 pause