⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hex2bin.c

📁 at51系列单片机编程源码
💻 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 + -