Reading Intel Hex file
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:
<=We use this 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 :
:88
^----------- use for calculate check sum ----------^^^
|_|
Check sum__|
= 0x10 = 16
= 0x05AA
= 00
= 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;
|