在做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 <stddef.h> #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;
#endiftypedef 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;
#endiftypedef 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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#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 (adjustedunsigned int        LoadOffset;     // 16-bit offset to which the data will unsigned char       RecordType;     // Type of data in the recordunsigned 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 aggregatortypedef 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 nibblePrecondition:NoneParameters:data            - char containing the data to convertReturns: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;}} // AsciiToHexNibbleint 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\r\n", 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 decodeBYTE          *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 FlashnRemaining  = 0;record_state = RECORD_START_TOKEN;numRecordsProcessed = 0;//DBG_MSG("Start convert\r\n");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.\r\n" );break; }//point to the data read from the filep_file_data = (BYTE*) &ReadBuffer[0];//process all of the data read so far...while(nRemaining){switch(record_state){case RECORD_START_TOKEN: //start codeif(*p_file_data == ':'){//move to the first state of the byte countrecord_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 returnsif((*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.\r\n" );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 1byteCountASCII.v[1] = *p_file_data++;//move to the next state of the byte countrecord_state = RECORD_BYTE_COUNT_NIBBLE_0;break;case RECORD_BYTE_COUNT_NIBBLE_0: //byte count byte 2byteCountASCII.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 addressrecord_state = RECORD_ADDRESS_NIBBLE_3;break;case RECORD_ADDRESS_NIBBLE_3: //address byte 1addressASCII.v[3] = *p_file_data++;//move to the next state of the addressrecord_state = RECORD_ADDRESS_NIBBLE_2;break;case RECORD_ADDRESS_NIBBLE_2: //address byte 2addressASCII.v[2] = *p_file_data++;//move to the next state of the addressrecord_state = RECORD_ADDRESS_NIBBLE_1;break;case RECORD_ADDRESS_NIBBLE_1: //address byte 3addressASCII.v[1] = *p_file_data++;//move to the next state of the addressrecord_state = RECORD_ADDRESS_NIBBLE_0;break;case RECORD_ADDRESS_NIBBLE_0: //address byte 4addressASCII.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 typerecord_state = RECORD_TYPE_NIBBLE_1;break;case RECORD_TYPE_NIBBLE_1: //record type byte 1recordTypeASCII.v[1] = *p_file_data++;//move to the next state of the typerecord_state = RECORD_TYPE_NIBBLE_0;break;case RECORD_TYPE_NIBBLE_0: //record type byte 2recordTypeASCII.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 staterecord_state = RECORD_DATA;}break;case RECORD_DATA: //dataif(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 stateif(recordDataCounter == current_record.RecordLength){record_state = RECORD_CHECKSUM_NIBBLE_1;}break;case RECORD_CHECKSUM_NIBBLE_1: //checksum byte 1checksumASCII.v[1] = *p_file_data++;//move to the next state of the checksumrecord_state = RECORD_CHECKSUM_NIBBLE_0;break;case RECORD_CHECKSUM_NIBBLE_0: //checksum byte 2checksumASCII.v[0] = *p_file_data++;current_record.Checksum = AsciiToHexByte(checksumASCII.v[1],checksumASCII.v[0]);numRecordsProcessed++;//Calculate the checksum of the datacalculated_checksum =   current_record.RecordLength +(current_record.LoadOffset&0xFF) +((current_record.LoadOffset>>8)&0xFF) +current_record.RecordType;for(i=0;i<current_record.RecordLength;i++){calculated_checksum += current_record.data[i];}//take the 2s compliment of the resultcalculated_checksum ^= 0xFF;calculated_checksum += 1;if(calculated_checksum != current_record.Checksum){//The calculated checksum of the data didn't match the//  value of the checksum held in the data record.printf("Calculated checksum didn't match the hex record checksum.\r\n" );return 1;}switch(current_record.RecordType){case RECORD_TYPE_DATA_RECORD://check the address heretotalAddress.word.HW = extendedAddress.Val;totalAddress.word.LW = current_record.LoadOffset;//Program the current data record into program memoryif(totalAddress.Val >= bin_start_address){   if(ProgramHexRecord(¤t_record, totalAddress.Val-bin_start_address)){printf("USB:There was an error programming the data\r\n");//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!\r\n", 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.\r\n" );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]\r\n");return 1;}   // get bin file namebin_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\r\n");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]\r\n");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!\r\n", HEX_FILE_NAME);free(bin_file_name);return 1;}    // convertbin_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!\r\n");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 fileif((fp_bin=fopen(bin_file_name, "wb"))==NULL){printf("Cannot open %s!\r\n", bin_file_name);fclose(fp_hex);free(bin_file_name);return 1;}bin_len = bin_size;DBG_MSG("%s\r\n", bin_file_name);DBG_MSG("start:\t0x%lx\r\n", bin_start_address);DBG_MSG("end:\t0x%lx\r\n", bin_size);DBG_MSG("length:\t0x%lx, %ldK\r\n", bin_len, bin_len/1024);if(fwrite(&bin_buffer[0], 1, bin_len, fp_bin) != bin_len){printf("Write %s failed!\r\n", 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"\hex2bin\hex2bin.exe mcu123.hex D000 2A800
pause

hex2bin附源代码相关推荐

  1. matlab车牌识别课程设计,matlab车牌识别课程设计报告模板(附源代码).doc

    您所在位置:网站首页 > 海量文档 &nbsp>&nbsp计算机&nbsp>&nbspmatlab matlab车牌识别课程设计报告模板(附源代码). ...

  2. 效率最高的Excel数据导入---(c#调用SSIS Package将数据库数据导入到Excel文件中【附源代码下载】)...

     本文目录: (一)背景 (二)数据库数据导入到Excel的方法比较    (三)SSIS的简介    (四)数据库中存储过程示例(SSIS应用需要) (五)Excel模板的制作(这步这么简单,稍微介 ...

  3. Silverlight 2 数据绑定演示程序(附源代码下载)

    Silverlight 2 数据绑定演示程序(附源代码下载) 数据绑定(Data Binding)是用户界面UI和业务对象或其它数据提供者(data provider)的连接.用户界面对象称为目标,数 ...

  4. 无卷积骨干网络:金字塔Transformer,提升目标检测/分割等任务精度(附源代码)

    论文地址:https://arxiv.org/pdf/2102.12122.pdf 源代码地址:https://github.com/whai362/PVT 具有自注意力的Transformer引发了 ...

  5. 详解python实现FP-TREE进行关联规则挖掘(带有FP树显示功能)附源代码下载(3)

    详解python实现FP-TREE进行关联规则挖掘(带有FP树显示功能)附源代码下载(3) 上一节简单讲了下FP树的生成,在这一节我将描述FP树的挖掘过程. 首先我们回顾一下要挖掘的特征项及样本空间: ...

  6. 神经网络 | BP神经网络-数字识别(附源代码)

    ===================================================== github:https://github.com/MichaelBeechan CSDN: ...

  7. C语言二叉树实验报告流程图,二叉树的建立与遍历实验报告(c语言编写,附源代码).doc...

    二叉树的建立与遍历实验报告(c语言编写,附源代码).doc 第 1 页,共 9 页二叉树的建立与遍历实验报告级 班 年 月 日 姓名 学号_ 1实验题目建立一棵二叉树,并对其进行遍历(先序.中序.后序 ...

  8. c#ovalshape_【原创】C# 实现拖拉控件改变位置与大小(SamWang)(附源代码下载)

    前言: 很多时候我们需要在运行时,动态地改变控件的位置以及大小,以获得更好的布局.比如说实际项目中的可自定义的报表.可自定义的单据等诸如此类.它们有个特点就是允许客户或者二次开发人员设计它们需要的界面 ...

  9. WCF技术剖析之二十八:自己动手获取元数据[附源代码下载]

    WCF技术剖析之二十八:自己动手获取元数据[附源代码下载] 原文:WCF技术剖析之二十八:自己动手获取元数据[附源代码下载] 元数据的发布方式决定了元数据的获取行为,WCF服务元数据架构体系通过Ser ...

  10. java闹钟程序设计_JAVA课程设计_闹钟的设计与实现项目-报告_附源代码.doc

    JAVA课程设计_闹钟的设计与实现项目-报告_附源代码 第2章 MACROBUTTON AcceptAllChangesInDoc [双击此处键入1级标题] PAGE 2 - PAGE 1 - .. ...

最新文章

  1. 俄罗斯方块新增行算法:不拘一格编程序之二
  2. Codeforces 610C:Harmony Analysis(构造)
  3. Learn About Bundles and the Request Lifecycle——未完待续
  4. 数据产品经理:埋点的设计、管理与应用
  5. Ansible script模块使用示例
  6. 10个最佳jQuery Lightbox效果插件收集
  7. 人工智能+眼科疾病辅助诊断(相关信息搜集)
  8. cadnaa噪声分析测试软件,Cadna/A软件介绍
  9. 软件著作权申请流程(自助申请免费登记)
  10. java万年历有农历_家庭农民历五行曰历,日历为什么叫“万年历”
  11. Linux树莓派怎么查看ntp服务,树莓派实现NTP服务器
  12. wxpython收费吗_使用wxPython开发一个简单GUI应用
  13. 个人手机网站接入支付宝在线收款功能
  14. CS231n课程笔记翻译9:卷积神经网络笔记
  15. 手把手教你音乐服务器搭建
  16. matlab rtdemo怎么生成,simulink——RTW自动代码生成简介
  17. unimrcp 实现阿里云的plugin
  18. python处理teradata数据库_【Python连接数据库】Python连接Teradata数据库-ODBC方式(pyodbc包和teradata包)...
  19. ChatGPT版必应被华人小哥攻破,一句话「催眠」问出所有Prompt
  20. SRT上传文件下载文件

热门文章

  1. 慕课java工程师2020版_2020年Java工程师就业前景怎么样?
  2. python 可视化设计_可视化Python设计工具
  3. 苹果手机怎么在照片上添加文字_不管用什么手机,这样操作一下,就能直接给照片添加文字...
  4. linux 进程 堆大小,Linux进程的默认分配堆大小
  5. Django 千锋培训的学习笔记
  6. HTTP代理服务器 - CONNECT SSL/TLS 原理
  7. Voip中的音频Codec技术
  8. 为什么不能cout一个string?
  9. could not find or load the Qt platform plugin windows的解决方法
  10. c++动态联编与静态联编