Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

string to intel hex file converter

Status
Not open for further replies.

artem

Advanced Member level 4
Joined
May 22, 2003
Messages
1,347
Helped
126
Reputation
252
Reaction score
32
Trophy points
1,328
Location
Turkey
Activity points
13,451
Topic edited - file attached

I have written in few hours a small symbol to intel hex format converter. Program is just to convert symbol representation into format suitable to use when writing initial configuration into eeproms (i needed it for atmega).

It can perform conversion of symbol file like this :
"DEVICE"0x0000000000 "OPEN", "CLOSE",, 0xEF, "DEVICE1" , 0xFF, "OPEN", "CLOSE",
0@0200
"TERMINATOR", 0xDE, "OPEN", "CLOSE"
0b00000001,0b01010101,0b01011110,0b01011110,0b01011110,0b01011110,0b01011110,0b01011110,0b01011110,0b01011110,0b0101111000000001


into intel hex file like below :
:1000000044455649434500000000004F50454E43CB
:100010004C4F5345EF44455649434531FF4F5045FA
:100020004E434C4F5345000000000000000000000C
:1000300000000000000000000000000000000000C0
:1000400000000000000000000000000000000000B0
:1000500000000000000000000000000000000000A0
:100060000000000000000000000000000000000090
:100070000000000000000000000000000000000080
:100080000000000000000000000000000000000070
:100090000000000000000000000000000000000060
:1000A0000000000000000000000000000000000050
:1000B0000000000000000000000000000000000040
:1000C0000000000000000000000000000000000030
:1000D0000000000000000000000000000000000020
:1000E0000000000000000000000000000000000010
:1000F0000000000000000000000000000000000000
:1001000000000000000000000000000000000000EF
:1001100000000000000000000000000000000000DF
:1001200000000000000000000000000000000000CF
:1001300000000000000000000000000000000000BF
:1001400000000000000000000000000000000000AF
:10015000000000000000000000000000000000009F
:10016000000000000000000000000000000000008F
:10017000000000000000000000000000000000007F
:10018000000000000000000000000000000000006F
:10019000000000000000000000000000000000005F
:1001A000000000000000000000000000000000004F
:1001B000000000000000000000000000000000003F
:1001C000000000000000000000000000000000002F
:1001D000000000000000000000000000000000001F
:1001E000000000000000000000000000000000000F
:1001F00000000000000000000000000000000000FF
:100200005445524D494E41544F52DE4F50454E4396
:100210004C4F534501555E5E5E5E5E5E5E5E5E0106
:00000001FF

If you think that it is reinvented wheel - i would appreciate to get notified about original one . Your opinions are wellcome .

/*************************************************************************************************************************
* This program translates symbolic file to intel hex format file for eeprom programming .
* Part of code was taken from Charles F. Harris exehex program.
* Program is intended to be used when mcu eeprom is to be filled with initial data and facilitates
* symbolic data to hexadecimal numbers convertion .
* Symbolic file is used as input to the program . Following syntax in symbolic file is supported
* Delimiters - ',' ' ' '\r' '\n' .
* String syntax - "xxxx" where xxxx is the alphanumeric string number of characters is limited
* to constant INFILE_MAX_SIZE
* Hexadecimal number - 0xXXXX where XXXX is series of hex digitis (0123456789ABCDEF) . Number of hex digits
* after 0x prefix must be even and resulting length should not exceed INFILE_MAX_SIZE
* Binary number - 0bBBBB where BBBB is series of binary digits wehre number of bin digits must be multiple of 8
* Address constraint - 0@AAAA where AAAA is hex expressed address (0123456789ABCDEF). The constraint is resulted
* in address iterator jump to the specified address . All positions from current address
* iterator to the address to jump will be filled with zeroes . It is not permitted to
* make backward address jumps where destination address is less than current address iterator.
*
* Note: It is permitted to have string start just after binary, address constraint or hex number without any delimiter
* and vice versa.
*
*************************************************************************************************************************/
#include <stdio.h>

#define INFILE_MAX_SIZE 20000 // Maximum input file length
#define STATE_START 0 // FSM state - seeking start
#define STATE_STRING 1 // FSM state - string parsing
#define STATE_HEX 2 // FSM state - hex number parsing
#define STATE_BIN 3 // FSM state - binary number parsing
#define STATE_CHECKX 4 // FSM state - check prefix
#define STATE_ADR 5 // FSM state - addres constraint

char hex_hi_hi(unsigned n);
char hex_hi_lo(unsigned n);
char hex_lo_hi(unsigned n);
char hex_lo_lo(unsigned n);
unsigned char hi_byte (unsigned n);
unsigned char lo_byte (unsigned n);
void puthex (unsigned char type,
unsigned loadaddress,
unsigned char datalen,
unsigned char *data);

char *deffile = "input.txt";
char hexbuf[INFILE_MAX_SIZE];
FILE *fp;

/*------------------------------------------------------------------------------------------------------------*
|
| Syntax :
| Arguments :
| Return values :
| Description :
|
*------------------------------------------------------------------------------------------------------------*/
main(int argc,char **argv)
{
char *str_p; //
unsigned int i, i1, adr; //
int tchar; //
char state, cnt, tmp; //
// Select file to use
if(argc == 1) // If no file in argument list
str_p = deffile; // use default - "input.txt" file
else // Else if file specified
str_p = argv[1]; // use file from argument list
//
if((fp = fopen(str_p, "r")) == NULL) // Open file to read symbols from
{ //
printf("Failed to open file \"%s\", terminating...", str_p); //
return -1; //
} //
//
state = STATE_START; // Set parse fsm state to start state
for(i=0; (i< INFILE_MAX_SIZE)&&((tchar = fgetc(fp)) != EOF);) // Parse input file in loop
{ //
switch(state) // Branch on FSM state
{ //
/*******************************************************************
* SYMBOL START PARSING
*******************************************************************/
case STATE_START : // START - seeking for symbol start
switch(tchar) // Branch on read character
{ //
case '"' : // '"' - start of alphanumeric string
state = STATE_STRING; // start parsing string
break; //
//
case '0' : // '0' - Prefix either hex or binary number (0x or 0b)
state = STATE_CHECKX ; // goto analyse prefix
break; //
//
case ',' : // ',' Comma is delimiter - discard
case '\r': // '\r' Carrage Return is delimiter - discard
case '\n': // '\n' New Line is delimiter - discard
case ' ' : // ' ' Space is delimiter - discard
break; //
// Any other character - Error unpermitted character
default : //
printf("Error unpermitted start character %c , exiting...\n", (char)tchar);
goto end_lab; //
} //
break; //
//
/*******************************************************************
* STRING PARSING
*******************************************************************/
case STATE_STRING : // STRING - parsing string is in progress
switch(tchar) // Branch on read character
{ //
case '"' : // '"' - end of alphanumeric string
state = STATE_START; // string end found - goto seek for another symbol
break; //
//
default : // Any other character - belongs to string
hexbuf[i++]=tchar; // Store character into hex array
break; //
} //
break; //
//
/*******************************************************************
* CHECKING X PREFIX
*******************************************************************/
case STATE_CHECKX : // CHECKX - parse prefix for binary or hex number
switch(tchar) // Branch on read character
{ //
case 'x' : // 'x' - hex nuber prefix found
state = STATE_HEX; // FSM state - parse hex number
cnt = 0; // reset number of hex digitis counter
tmp = 0; // reset temporary storage for hex number
break; // goto parse hex number
//
case 'b' : // 'b' - binary string prefix found
state = STATE_BIN; // FSM state - parse binary number
cnt = 0; // reset coutner of binary numbers read
tmp = 0; // reset temporary storage for binary number
break; // goto parse binary number
//
case '@' : // '@' - Address constraint
state = STATE_ADR; //
adr = 0; //
break; //
//
default : // Any other character - error either 'b' or 'x' cold be expected
puts("Neither \'b\' nor \'x\' found after \'0\' start character, exiting ...");
goto end_lab; //
} //
break; //
//
/*******************************************************************
* HEXADECIMAL NUMBER PARSING
*******************************************************************/
case STATE_HEX : // HEX - hex number parsing in progress
switch(tchar) // Branch on read character
{ //
case '"' : // '"' - start of the string symbol found (means end of hex number)
if((cnt & 1) != 0) // If odd number of digits stored - error number of hex digits
{ // must be even to align with byte length
puts("Error - hex string contains odd number of digit, exiting ...");
goto end_lab; //
} //
state = STATE_STRING; // FSM state - start parse string
break; //
//
case '0' : //
case '1' : //
case '2' : //
case '3' : //
case '4' : //
case '5' : //
case '6' : //
case '7' : //
case '8' : //
case '9' : //
if(cnt == 0) //
{ //
tmp = (tchar - 0x30) << 4; //
cnt = 1; //
} //
else //
{ //
tmp |= (tchar - 0x30); //
hexbuf[i++] = tmp; //
cnt = 0; //
} //
break; //
case 'A' : //
case 'B' : //
case 'C' : //
case 'D' : //
case 'E' : //
case 'F' : //
if(cnt == 0) //
{ //
tmp = (tchar - 0x37) << 4; //
cnt = 1; //
} //
else //
{ //
tmp |= (tchar - 0x37); //
hexbuf[i++] = tmp; //
cnt = 0; //
} //
break; //
//
case ',' : //
case ' ' : //
case '\r': //
case '\n': //
if(cnt == 1) //
{ //
puts("Error - hex string contains odd number of digit, exiting ...");
goto end_lab; //
} //
state = STATE_START; //
break; //
//
default : //
puts("Error unpermitted characeter within hex digit, exiting...");
goto end_lab; //
} //
break; //
//
/*******************************************************************
* ADDRESS CONSTRAINT PARSING
*******************************************************************/
case STATE_ADR : // Parsing Address constraint
switch(tchar) // Branch on read character
{ //
case '"' : //
case ',' : //
case ' ' : //
case '\r': //
case '\n': //
if(adr >= i) //
{ //
for(;i != adr;i++) //
hexbuf=0x00; //
} //
else //
{ //
printf("Error - backward jump in address constraint, exiting...\n");
goto end_lab; //
} //
//
if(tchar == '"') //
state = STATE_STRING; // FSM state - start parse string
else //
state = STATE_START; //
break; //
//
case '0' : //
case '1' : //
case '2' : //
case '3' : //
case '4' : //
case '5' : //
case '6' : //
case '7' : //
case '8' : //
case '9' : //
adr = (adr << 4) + (tchar - 0x30); //
break; //
case 'A' : //
case 'B' : //
case 'C' : //
case 'D' : //
case 'E' : //
case 'F' : //
adr = (adr << 4) + (tchar - 0x37); //
break; //
//
default : //
puts("Error unpermitted characeter within hex digit, exiting...");
goto end_lab; //
} //
break; //
//
/*******************************************************************
*
*******************************************************************/
case STATE_BIN : //
switch(tchar) //
{ //
case '0' : //
case '1' : //
tmp = tmp << 1; //
if(tchar == '1') //
tmp += 1; //
if(++cnt == 8) //
{ //
hexbuf[i++] = tmp; //
tmp = 0; //
cnt = 0; //
} //
break; //
//
case ',' : //
case '\r': //
case '\n': //
case '"' : //
if(cnt != 0) //
{ //
puts("Error - bin string contains unaligned number of digits, exiting ...");
goto end_lab; //
} //
if(tchar == '"') //
state = STATE_STRING; //
else //
state = STATE_START; //
break; //
//
default : //
puts("Error while parsing file, Exiting..."); //
return -1; //
} //
break; //
//
} //
} //
for(i1 =0 ; ; i1 += 16) //
{ //
if((i1 + 15) < i) //
puthex(0, i1, 16, &hexbuf[i1]); //
else if(i1 < i) //
{ //
puthex(0, i1, i - i1, &hexbuf[i1]); //
break; //
} //
else //
break; //
} //
puts(":00000001FF"); // Put End of file record type (actually puthex could also be called)
//
end_lab : //
fclose(fp); //
return 0;
}

/*------------------------------------------------------------------------------------------------------------*
|
| Syntax :
| Arguments :
| Return values :
| Description :
|
*------------------------------------------------------------------------------------------------------------*/
void puthex
(
unsigned char type,
unsigned loadaddress,
unsigned char datalen,
unsigned char *data
)
{
int checksum = 0;
int i,j;

putchar(':');
putchar(hex_lo_hi(datalen));
putchar(hex_lo_lo(datalen));
checksum += datalen;

putchar(hex_hi_hi(loadaddress));
putchar(hex_hi_lo(loadaddress));
putchar(hex_lo_hi(loadaddress));
putchar(hex_lo_lo(loadaddress));
checksum += hi_byte(loadaddress);
checksum += lo_byte(loadaddress);

putchar(hex_lo_hi(type));
putchar(hex_lo_lo(type));
checksum += type;

for(i=9,j=0; j<datalen; i+=2,j++){
putchar(hex_lo_hi(data[j]));
putchar(hex_lo_lo(data[j]));
checksum += data[j];
}
checksum = -checksum;
putchar(hex_lo_hi(checksum));
putchar(hex_lo_lo(checksum));
putchar('\n');
}

static char hextable[] = "0123456789ABCDEF";

/*------------------------------------------------------------------------------------------------------------*
|
*------------------------------------------------------------------------------------------------------------*/
char hex_hi_hi(unsigned n){ return hextable[ (hi_byte(n)>>4)&0xf ]; }
/*------------------------------------------------------------------------------------------------------------*
|
*------------------------------------------------------------------------------------------------------------*/
char hex_hi_lo(unsigned n){ return hextable[ hi_byte(n)&0xf ]; }
/*------------------------------------------------------------------------------------------------------------*
|
*------------------------------------------------------------------------------------------------------------*/
char hex_lo_hi(unsigned n){ return hextable[ (lo_byte(n)>>4)&0xf ]; }
/*------------------------------------------------------------------------------------------------------------*
|
*------------------------------------------------------------------------------------------------------------*/
char hex_lo_lo(unsigned n){ return hextable[ lo_byte(n)&0xf ]; }
/*------------------------------------------------------------------------------------------------------------*
|
*------------------------------------------------------------------------------------------------------------*/
unsigned char hi_byte (unsigned n){ return ((n>>8) & 0xff); }
/*------------------------------------------------------------------------------------------------------------*
|
*------------------------------------------------------------------------------------------------------------*/
unsigned char lo_byte (unsigned n){ return (n & 0xff); }
 

you should have included the source as attachment as some characters got converted to smilies: 8 ) --> 8)
Code:
Perhaps displaying in "code mode" is also possible.  8 ) -->  8)


Mik
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top