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
^----------- 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
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