Here is the routine for read one line of Intel Hex file (file format for the Intel 8-bit only)
General Intel HEX format (8 bit)
Each record begins with a RECORD MARK field containing 03AH, the ASCII code for the colon (’ : ’) character.
Each record has a RECLEN field which specifies the number of bytes of information or data which follows the RECTYP field of the record. Note that one data byte is represented by two ASCII characters. The maximum value of the RECLEN field is hexadecimal ’FF’ or 255.
Each record has a LOAD OFFSET or ADDRESS field which specifies the 16-bit starting load offset of the data bytes, therefore this field is only used for Data Records. In other records where this field is not used, it should be coded as four ASCII zero characters (’0000’ or 03030303OH).
Each record has a RECTYP field which specifies the record type of this record. The RECTYP field is used to interpret the remaining information within the record. The encoding for all the current record types are:
’00’ Data Record <=We use this record
’01’ End of File Record <=We use this record
’02’ Extended Segment Address Record
’03’ Start Segment Address Record
’04’ Extended Linear Address Record
’05’ Start Linear Address Record
Each record has a variable length INFO/DATA field, it consists of zero or more bytes encoded as pairs of hexadecimal digits. The interpretation of this field depends on the RECTYP field.
Each record ends with a CHKSUM field that contains the ASCII hexadecimal representation of the two’s complement of the 8-bit bytes that result from converting each pair of ASCII hexadecimal digits to one byte of binary, from the RECLEN field to the last byte of the INFO/DATA field. Therefore, the sum of all the ASCII pairs in a record after converting to binary, form the RECLEN field to and including the CHKSUM field, is zero.
Example :
:1005AA00000102030405060708090A0B0C0D0E0F88
^----------- use for calculate check sum ----------^^^
|_|
Check sum__|
RECLEN = 0x10 = 16
ADDRESS = 0x05AA
RECTYPE = 00
DATA = 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
CHKSUM = 0x88 = 256 -sum(0x00+..+0x0F)= 256- 0x78
To use this routine
Here is an example demonstration how to use the above readline routine
General Intel HEX format (8 bit)
Each record begins with a RECORD MARK field containing 03AH, the ASCII code for the colon (’ : ’) character.
Each record has a RECLEN field which specifies the number of bytes of information or data which follows the RECTYP field of the record. Note that one data byte is represented by two ASCII characters. The maximum value of the RECLEN field is hexadecimal ’FF’ or 255.
Each record has a LOAD OFFSET or ADDRESS field which specifies the 16-bit starting load offset of the data bytes, therefore this field is only used for Data Records. In other records where this field is not used, it should be coded as four ASCII zero characters (’0000’ or 03030303OH).
Each record has a RECTYP field which specifies the record type of this record. The RECTYP field is used to interpret the remaining information within the record. The encoding for all the current record types are:
’00’ Data Record <=We use this record
’01’ End of File Record <=We use this record
’02’ Extended Segment Address Record
’03’ Start Segment Address Record
’04’ Extended Linear Address Record
’05’ Start Linear Address Record
Each record has a variable length INFO/DATA field, it consists of zero or more bytes encoded as pairs of hexadecimal digits. The interpretation of this field depends on the RECTYP field.
Each record ends with a CHKSUM field that contains the ASCII hexadecimal representation of the two’s complement of the 8-bit bytes that result from converting each pair of ASCII hexadecimal digits to one byte of binary, from the RECLEN field to the last byte of the INFO/DATA field. Therefore, the sum of all the ASCII pairs in a record after converting to binary, form the RECLEN field to and including the CHKSUM field, is zero.
Example :
:1005AA00000102030405060708090A0B0C0D0E0F88
RECLEN = 0x10 = 16
ADDRESS = 0x05AA
RECTYPE = 00
DATA = 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
CHKSUM = 0x88 = 256 -sum(0x00+..+0x0F)= 256- 0x78
type buffer=array of byte; //assign as Dynamic array
var HexBuf:buffer;
function readline(HexLine:string; var Buf:buffer):integer;
var ADDR,count:integer;
CHKSUM,SUMLINE,RECLEN,RECTYPE,DATA:byte;
t:shortstring;
begin
// Array length may be change, here is 100,000
SetLength(HexBuf,100000);
if HexLine[1]=':' then begin
t:='$'+copy(HexLine,2,2); // get length
RECLEN:=strtoint(t);
CHKSUM:=0;
CHKSUM:=CHKSUM+RECLEN;
t:='$'+copy(HexLine,4,4); // get address
ADDR:=strtoint(t);
CHKSUM:=CHKSUM+lo(ADDR)+hi(ADDR);
t:='$'+copy(HexLine,8,2);
RECTYPE:=strtoint(t);
CHKSUM:=CHKSUM+RECTYPE;
case RECTYPE of
0:begin // datablock
count:=0;
while (count < RECLEN) do begin
t:='$'+copy(HexLine,10+2*count,2);
DATA:=strtoint(t);
CHKSUM:=CHKSUM+DATA;
Buf[ADDR+count]:=DATA;
inc(count);
end;
t:='$'+copy(HexLine,10+2*count,2);
SUMLINE:=strtoint(t);
end;
1:begin // end of file
t:='$'+copy(HexLine,10,2);
SUMLINE:=strtoint(t);
result:=1;
end;
else
begin
result := -2; // invalid record type
exit;
end;
end; //case
// test checksum
DATA:=SUMLINE+CHKSUM;
if (DATA<>0) then result:=-3; // checksum error
end
else result:=-1; // no record
end;
To use this routine
Here is an example demonstration how to use the above readline routine
procedure TForm1.Button1Click(Sender: TObject);
var Fname,line:string;
Fp : textfile;
ErrorCode:integer;
begin
Fname:='test.hex';
AssignFile(Fp,Fname); { File selected in dialog }
Reset(Fp);
while not eof(Fp) do
begin
Readln(Fp, line);{ Read first line of file }
ErrorCode := readline(line,HexBuf);
if (ErrorCode=0) then
begin
// Do some thing if read one line OK
// such send data to serial port,parallel port etc.
end
else
begin
// Error handle here
// 0 = No error
// -1 = File not Intel Hex format
// -2 = Invalid record type
// -3 = Checksum error
break; // exit while loop
end;
end;
CloseFile(Fp);
end;
No comments:
Post a Comment