📄 hex2bin.c
字号:
/* ---------------------------------------------------------------------------- * hex2bin.c * this module contains stuff for converting intel hex file to binary format * * Copyright 2003/2004 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ----------------------------------------------------------------------------*/#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include "isp-at89.h"#define H2B_IS_BINARYFILE 3#define H2B_IS_INTELHEXFILE 2#define H2B_IS_INTELHEXLINE 1#define H2B_OKAY 0#define H2B_NOT_A_NULLPOINTER -1#define H2B_FILE_NOT_FOUND -2#define H2B_FILE_NOT_VALID -3#define H2B_NOT_A_VALID_LINE -4#define H2B_FEOF -5#define H2B_MISSING_COLON -6#define H2B_RECORDTYP_IS_UNKOWN -7#define H2B_RECORDTYP_END -8#define H2B_CHECKSUM_ERROR -9#define H2B_CRITICAL_ERROR -10#define H2B_NO_MEMORY -11#define H2B_NOT_A_VALID_CHAR -12#define H2B_DUMMY -100typedef struct { unsigned char numb; unsigned short int address; unsigned char typ; unsigned char data[256]; unsigned char checksum;} IntelHexLine;/* internal function prototypes */unsigned char *readIntelHexline (unsigned char *data, unsigned char *blen, IntelHexLine *ihl);int checkPtr (unsigned char *a, unsigned char *b);unsigned char *copyIhl2Buffer (struct MemChunk *Buffer, unsigned char *wrdata, IntelHexLine *ihl);#ifdef DEBUGint MyDumpChunks (struct MemChunk *Buffer,int l);#endif/* for debuging purpose */static int h2b_error=0;/*************************************************************************** Copy four bytes of a a string and interpret the character as a* hexadezimal number** -> s : buffer which contains the character* usi : Pointer to an unsigned short int** <- OK : The characters are converted to a byte* ERROR : Illegal charakters found in the string and could not be* converted to byte** 05.01.2004 (ALPHA)**************************************************************************/int hex2int (char *s, unsigned short int *usi) { char str[5]; unsigned int t; strncpy (str,s,4); str[4]=0; if (sscanf (str,"%4X",&t) ==1) { *usi = (unsigned short int)(t); return (OK); } return (ERROR);}/*************************************************************************** Copy two bytes of a a string and interpret the character as a* hexadezimal number** -> s : buffer which contains the character* uc : Pointer to an unsigned character** <- OK : The characters are converted to a byte* ERROR : Illegal charakters found in the string and could not be* converted to byte** 05.01.2004 (ALPHA)**************************************************************************/int hex2byte (char *s, unsigned char *uc) { char str[3]; unsigned int t; strncpy (str,s,2); str[2]=0; if (sscanf (str,"%2X",&t) ==1) { *uc = (unsigned char)(t); return (OK); } return (ERROR);}/*************************************************************************** Calculate the checksum on an intel hex record** The calculated checksum will be compare with the stored checksum in the* intel hex record.** -> ihl : pointer to a intel hex record** <- OK : The calculated checksum is equal to the stored* checksum* H2B_CHECKSUM_ERROR : The two checksums are not equal** 28.12.2003 (ALPHA)**************************************************************************/int calculateChecksum (IntelHexLine *ihl) { unsigned char chksum; unsigned int i; chksum = ihl->numb; chksum += ihl->address/0x100; chksum += ihl->address%0x100; chksum += ihl->typ; for (i=0; i<ihl->numb; i++) chksum += ihl->data[i]; /* finish the calculating from checksum */ chksum=(1 + ~chksum) & 0xFF; if (chksum == ihl->checksum) return (OK); else { h2b_error = H2B_CHECKSUM_ERROR; return (ERROR); }}/*************************************************************************** Convert the buffer which contain data in intelhex format in a binary* format** If the buffer contain already a binary format it will be unchanged. if* an error in the format will be detected the return of the function is* ERROR.** -> struct MemChunk *Buffer : a pointer to a valid MemChunk struct.** <- ERROR : An error in the intel hex was detected. The contents of the* buffer is no longer valid* OK : The contens of the buffer is fully converted from intel hex* file format to the binary format with memory chunks** 05.01.2003 [ao]**************************************************************************/int hex2bin (struct MemChunk *Buffer) { unsigned char *data = NULL; unsigned char *blen; unsigned char *wrdata; struct MemChunkHeader *nmch = NULL; int firsttime=1; IntelHexLine ihl;#ifdef DEBUG int l = Buffer->header.length;#endif /* is the pointer valid? */ if (Buffer==NULL) return (ERROR); /* initalize the pointer */ data = Buffer->data; wrdata = data; blen = data + (Buffer->header.length); while (data < blen) { data = readIntelHexline (data, blen, &ihl); if (data == NULL) { if (firsttime) { /* a binary file */ return (OK); } /* an error occured */ else return (ERROR); } else if (data == blen) { /* success we are ready, stop reading */ /* we have to write the last MemChunk */ nmch = (struct MemChunkHeader *)(wrdata); nmch->address = 0; nmch->length = 0; } else if (data > blen) { /* Fatal error develop better !! */ fprintf (stderr,"Fatal error develop better !!\n"); return (ERROR); } else { /* one intel hex line was read */ /* put the data of ihl to the buffer */ if (firsttime) { Buffer->header.address = ihl.address; Buffer->header.length = 0; firsttime=0; } wrdata = copyIhl2Buffer (Buffer,wrdata,&ihl); } } /* write the last chunk and leave the function */#ifdef DEBUG MyDumpChunks (Buffer,l);#endif return (OK);}/*************************************************************************** Try to read intel hex line from buffer** -> unsigned char *data : pointer to actual read position in the buffer* unsigned char *blen : pointer to the end of the buffer* IntelHexLine *ihl : pointer to a intel hex line were the datas will* be stored** <- unsigned char * : NULL an error occured. If the return value not* equal NULL the presents the next read position in* the buffer***************************************************************************/unsigned char *readIntelHexline (unsigned char *data, unsigned char *blen, IntelHexLine *ihl){ int i; /* check the argument for the function */ if (data == NULL || blen == NULL || ihl == NULL) { ihl = NULL; return (NULL); } /* each line starts with a colon */ if (checkPtr (data+1, blen)) { /* reading is posible */ if (*data != ':') { h2b_error = H2B_MISSING_COLON; ihl = NULL; return (NULL); } data++; } else return (NULL); /* read the number of bytes */ if (checkPtr (data+2,blen)) { if (hex2byte(data,&ihl->numb) == ERROR) { return (NULL); } data+=2; } else return (NULL); /* read the address*/ if (checkPtr (data+4,blen)) { if (hex2int(data,&ihl->address) == ERROR) { return (NULL); } data+=4; } else return (NULL); /* read the type of record */ if (checkPtr (data+2,blen)) { if (hex2byte(data,&ihl->typ) == ERROR) { return (NULL); } data+=2; } else return (NULL); switch (ihl->typ) { case 0: /* records contain data bytes */ /* Read the data bytes and store them in binary array */ for (i=0; i<ihl->numb; i++) { if (checkPtr (data+2,blen)) { if (hex2byte(data,&ihl->data[i]) == ERROR) { h2b_error = H2B_NOT_A_VALID_CHAR; return (NULL); } data+=2; } else return (NULL); } break; case 1: /* last record in file */ /* read the checksum of record */ if (checkPtr (data+2,blen)) { if (hex2byte(data,&ihl->checksum) == ERROR) { return (NULL); } data+=2; } else return (NULL); /* Calculate and compare the checksum. If the checksums */ /* are equal we exit at this point. */ if (calculateChecksum (ihl)==OK) { return (blen); } else { h2b_error = H2B_CHECKSUM_ERROR; return (NULL); } break; case 2: /* Segment offset, not implemented yet */ break; default: { /* type of record is unkown */ h2b_error = H2B_RECORDTYP_IS_UNKOWN; ihl = NULL; return (NULL); } } /* read the checksum of record */ if (checkPtr (data+2,blen)) { if (hex2byte(data,&ihl->checksum) == ERROR) { return (NULL); } data+=2; } else return (NULL); /* Calculate and compare the checksum */ if (calculateChecksum (ihl)==ERROR) { ihl = NULL; return (NULL); } /* check for CR and/or LF */ for (i=0; i<2; i++) { if (checkPtr (data+1,blen)) { if (*data == ':') return (data); if (*data == '\n' || *data == '\r') data++; } } /* if we reach this line there in an error in the buffer */ return(NULL);}/*************************************************************************** Compare the pointer a and b* Pointer 'a' must be less as pointer 'b'**************************************************************************/int checkPtr (unsigned char *a, unsigned char *b) { if (a<b) return (READY); else return (ERROR);}/*************************************************************************** Put the data content of the struct IHL in the binary buffer** Before storing the datas the function check if a new chunk is necessary**************************************************************************/unsigned char *copyIhl2Buffer (struct MemChunk *Buffer, unsigned char *wrdata, IntelHexLine *ihl){ struct MemChunkHeader *nmch; static struct MemChunk *oldbuffer = NULL; int i; /* save the MemChunk */ if (oldbuffer == NULL) oldbuffer = Buffer; /* detect if we can lengthen the actual chunk */ if (oldbuffer->header.address + oldbuffer->header.length == ihl->address) { /* yes we can therefore do only a copy */ for (i=0; i<ihl->numb; i++) *wrdata++ = ihl->data[i]; oldbuffer->header.length += ihl->numb; } else { /* we need a new chunk in the binary buffer */ nmch = (struct MemChunkHeader *)(wrdata); wrdata += sizeof (struct MemChunkHeader); /* copy the data bytes */ for (i=0; i<ihl->numb; i++) *wrdata++ = ihl->data[i]; /* and set correct address and length */ nmch->address = ihl->address; nmch->length = ihl->numb; /* store the actual chunk */ oldbuffer = (struct MemChunk *)(nmch); } return (wrdata);}/*************************************************************************** This is a function for controlling the contents of the buffer after* converting the datas from the intel hex format to the binary format.* (only for debugging purposes!)**************************************************************************/#ifdef DEBUGint MyDumpChunks (struct MemChunk *Buffer,int l) { unsigned char *uc =(unsigned char *)(Buffer) + 4; struct MemChunkHeader *mch = (struct MemChunkHeader *)(Buffer); int i; FILE *f = fopen ("output_hex2bin.chunk","w"); for(;;) { fprintf (f,"Adresse: 0x%04X ",mch->address); fprintf (f,"Laenge [Dez]: %04i\n",mch->length); for (i=0; i<mch->length; i++) { fprintf (f,"0x%02X ",*uc); } fprintf (f,"\n"); mch = (struct MemChunkHeader *)(uc); uc+=4; if (mch->address == 0 && mch->length == 0) break; } fclose (f); return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -