mirror of https://github.com/rusefi/openblt.git
Refs #226. Refactored the TFirmwareData class such that it can be used in Lazarus as well.
git-svn-id: https://svn.code.sf.net/p/openblt/code/trunk@200 5dc33758-31d5-4daf-9ae8-b24bf3d40d73
This commit is contained in:
parent
f7f8c387ba
commit
d312562e40
|
@ -29,6 +29,10 @@ unit FirmwareData;
|
||||||
// should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy.
|
// should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy.
|
||||||
//
|
//
|
||||||
//***************************************************************************************
|
//***************************************************************************************
|
||||||
|
{$IFDEF FPC}
|
||||||
|
{$mode objfpc}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,7 +40,7 @@ interface
|
||||||
// Includes
|
// Includes
|
||||||
//***************************************************************************************
|
//***************************************************************************************
|
||||||
uses
|
uses
|
||||||
Windows, Messages, SysUtils, Classes, Math, Generics.Collections, Generics.Defaults;
|
SysUtils, Classes;
|
||||||
|
|
||||||
|
|
||||||
//***************************************************************************************
|
//***************************************************************************************
|
||||||
|
@ -69,6 +73,21 @@ type
|
||||||
property LastAddress: Longword read GetLastAddress;
|
property LastAddress: Longword read GetLastAddress;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
//---------------------------------- TDataSegmentList ---------------------------------
|
||||||
|
TDataSegmentList=class(TList)
|
||||||
|
private
|
||||||
|
function Get(Index: Integer): TDataSegment;
|
||||||
|
protected
|
||||||
|
{ Protected declarations }
|
||||||
|
public
|
||||||
|
{ Public declarations }
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
function Add(segment: TDataSegment): Integer;
|
||||||
|
procedure Delete(Index: Integer);
|
||||||
|
property Items[Index: Integer]: TDataSegment read Get; default;
|
||||||
|
end;
|
||||||
|
|
||||||
//---------------------------------- TFirmwareFileType --------------------------------
|
//---------------------------------- TFirmwareFileType --------------------------------
|
||||||
TFirmwareFileType =
|
TFirmwareFileType =
|
||||||
(
|
(
|
||||||
|
@ -88,7 +107,7 @@ type
|
||||||
public
|
public
|
||||||
constructor Create; virtual;
|
constructor Create; virtual;
|
||||||
function Load(firmwareFile: String): Boolean; virtual; abstract;
|
function Load(firmwareFile: String): Boolean; virtual; abstract;
|
||||||
function Save(firmwareFile: String; segments: TObjectList<TDataSegment>): Boolean; virtual; abstract;
|
function Save(firmwareFile: String; segments: TDataSegmentList): Boolean; virtual; abstract;
|
||||||
property OnDataRead: TFirmwareFileDataReadEvent read FOnDataRead write FOnDataRead;
|
property OnDataRead: TFirmwareFileDataReadEvent read FOnDataRead write FOnDataRead;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -104,7 +123,7 @@ type
|
||||||
public
|
public
|
||||||
constructor Create; override;
|
constructor Create; override;
|
||||||
function Load(firmwareFile: String): Boolean; override;
|
function Load(firmwareFile: String): Boolean; override;
|
||||||
function Save(firmwareFile: String; segments: TObjectList<TDataSegment>): Boolean; override;
|
function Save(firmwareFile: String; segments: TDataSegmentList): Boolean; override;
|
||||||
class function IsSRecordFile(firmwareFile: String): Boolean; static;
|
class function IsSRecordFile(firmwareFile: String): Boolean; static;
|
||||||
property DataBytesPerLineOnSave: Integer read FDataBytesPerLineOnSave write FDataBytesPerLineOnSave;
|
property DataBytesPerLineOnSave: Integer read FDataBytesPerLineOnSave write FDataBytesPerLineOnSave;
|
||||||
end;
|
end;
|
||||||
|
@ -115,14 +134,14 @@ type
|
||||||
public
|
public
|
||||||
constructor Create; override;
|
constructor Create; override;
|
||||||
function Load(firmwareFile: String): Boolean; override;
|
function Load(firmwareFile: String): Boolean; override;
|
||||||
function Save(firmwareFile: String; segments: TObjectList<TDataSegment>): Boolean; override;
|
function Save(firmwareFile: String; segments: TDataSegmentList): Boolean; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//---------------------------------- TFirmwareData ------------------------------------
|
//---------------------------------- TFirmwareData ------------------------------------
|
||||||
TFirmwareData = class(TObject)
|
TFirmwareData = class(TObject)
|
||||||
private
|
private
|
||||||
// list with data segments of the firmware
|
// list with data segments of the firmware
|
||||||
FSegmentList: TObjectList<TDataSegment>;
|
FSegmentList: TDataSegmentList;
|
||||||
function GetSegmentCount: Integer;
|
function GetSegmentCount: Integer;
|
||||||
function GetSegment(index: Integer): TDataSegment;
|
function GetSegment(index: Integer): TDataSegment;
|
||||||
procedure SortSegments;
|
procedure SortSegments;
|
||||||
|
@ -469,9 +488,11 @@ end; //*** end of Remove ***
|
||||||
//
|
//
|
||||||
//***************************************************************************************
|
//***************************************************************************************
|
||||||
procedure TDataSegment.Dump;
|
procedure TDataSegment.Dump;
|
||||||
|
{$IFDEF DEBUG}
|
||||||
var
|
var
|
||||||
line: String;
|
line: String;
|
||||||
byteCnt: Integer;
|
byteCnt: Integer;
|
||||||
|
{$ENDIF}
|
||||||
begin
|
begin
|
||||||
{$IFDEF DEBUG}
|
{$IFDEF DEBUG}
|
||||||
// output address and size
|
// output address and size
|
||||||
|
@ -494,6 +515,98 @@ begin
|
||||||
end; //*** end of Dump
|
end; //*** end of Dump
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//-------------------------------- TDataSegmentList -------------------------------------
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//***************************************************************************************
|
||||||
|
// NAME: Create
|
||||||
|
// PARAMETER: none
|
||||||
|
// RETURN VALUE: none
|
||||||
|
// DESCRIPTION: Object constructor. Calls TObject's constructor and initializes
|
||||||
|
// the private property variables to their default values.
|
||||||
|
//
|
||||||
|
//***************************************************************************************
|
||||||
|
constructor TDataSegmentList.Create;
|
||||||
|
begin
|
||||||
|
// call inherited constructor
|
||||||
|
inherited Create;
|
||||||
|
end; //*** end of Create ***
|
||||||
|
|
||||||
|
|
||||||
|
//***************************************************************************************
|
||||||
|
// NAME: Destroy
|
||||||
|
// PARAMETER: none
|
||||||
|
// RETURN VALUE: none
|
||||||
|
// DESCRIPTION: Component destructor.
|
||||||
|
//
|
||||||
|
//***************************************************************************************
|
||||||
|
destructor TDataSegmentList.Destroy;
|
||||||
|
var
|
||||||
|
idx: Integer;
|
||||||
|
begin
|
||||||
|
// release allocated heap memory
|
||||||
|
for idx := 0 to Count - 1 do
|
||||||
|
TDataSegment(Items[idx]).Free;
|
||||||
|
inherited;
|
||||||
|
end; //*** end of Destroy ***
|
||||||
|
|
||||||
|
|
||||||
|
//***************************************************************************************
|
||||||
|
// NAME: Get
|
||||||
|
// PARAMETER: Index Index in the list
|
||||||
|
// RETURN VALUE: List item.
|
||||||
|
// DESCRIPTION: Obtains an element from the list.
|
||||||
|
//
|
||||||
|
//***************************************************************************************
|
||||||
|
function TDataSegmentList.Get(Index: Integer): TDataSegment;
|
||||||
|
begin
|
||||||
|
Result := TDataSegment(inherited Get(Index));
|
||||||
|
end; //*** end of Get ***
|
||||||
|
|
||||||
|
|
||||||
|
//***************************************************************************************
|
||||||
|
// NAME: Add
|
||||||
|
// PARAMETER: segment The data segment to add.
|
||||||
|
// RETURN VALUE: Index of the newly added segment in the list if successful, -1
|
||||||
|
// otherwise.
|
||||||
|
// DESCRIPTION: Adds an element to the list.
|
||||||
|
//
|
||||||
|
//***************************************************************************************
|
||||||
|
function TDataSegmentList.Add(segment: TDataSegment): Integer;
|
||||||
|
begin
|
||||||
|
// add the entry to the list
|
||||||
|
Result := inherited Add(segment);
|
||||||
|
// set correct value for error situation
|
||||||
|
if Result < 0 then
|
||||||
|
Result := -1;
|
||||||
|
end; //*** end of Add ***
|
||||||
|
|
||||||
|
|
||||||
|
//***************************************************************************************
|
||||||
|
// NAME: Delete
|
||||||
|
// PARAMETER: Index Index in the list.
|
||||||
|
// RETURN VALUE: none
|
||||||
|
// DESCRIPTION: Remove an element to the list as the specified index. It is automa-
|
||||||
|
// tically freed as well.
|
||||||
|
//
|
||||||
|
//***************************************************************************************
|
||||||
|
procedure TDataSegmentList.Delete(Index: Integer);
|
||||||
|
var
|
||||||
|
segment: TDataSegment;
|
||||||
|
begin
|
||||||
|
// only continue if the index is valid
|
||||||
|
if (Index >= 0) and (Index < Count) then
|
||||||
|
begin
|
||||||
|
// obtain object first so we can free it afterwards
|
||||||
|
segment := Get(Index);
|
||||||
|
// delete it from the list
|
||||||
|
inherited Delete(Index);
|
||||||
|
// now free it
|
||||||
|
segment.Free
|
||||||
|
end;
|
||||||
|
end; //*** end of Delete ***
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
//-------------------------------- TFirmwareFileHandler ---------------------------------
|
//-------------------------------- TFirmwareFileHandler ---------------------------------
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
|
@ -598,7 +711,7 @@ end; //*** end of Load ***
|
||||||
// DESCRIPTION: Saves the firmware data to the specified firmware file.
|
// DESCRIPTION: Saves the firmware data to the specified firmware file.
|
||||||
//
|
//
|
||||||
//***************************************************************************************
|
//***************************************************************************************
|
||||||
function TSRecordFileHandler.Save(firmwareFile: String; segments: TObjectList<TDataSegment>): Boolean;
|
function TSRecordFileHandler.Save(firmwareFile: String; segments: TDataSegmentList): Boolean;
|
||||||
var
|
var
|
||||||
srecordFile: TextFile;
|
srecordFile: TextFile;
|
||||||
segmentIdx: Integer;
|
segmentIdx: Integer;
|
||||||
|
@ -611,6 +724,7 @@ var
|
||||||
headerByteCount: Integer;
|
headerByteCount: Integer;
|
||||||
checksumCalc: Byte;
|
checksumCalc: Byte;
|
||||||
addrByteCnt: Integer;
|
addrByteCnt: Integer;
|
||||||
|
charIdx: Integer;
|
||||||
begin
|
begin
|
||||||
// init result
|
// init result
|
||||||
Result := True;
|
Result := True;
|
||||||
|
@ -628,7 +742,9 @@ begin
|
||||||
ReWrite(srecordFile);
|
ReWrite(srecordFile);
|
||||||
|
|
||||||
// ---- add the S0 header line that contains the filename ----
|
// ---- add the S0 header line that contains the filename ----
|
||||||
firmwareFileBytes := TEncoding.UTF8.GetBytes(firmwareFile);
|
SetLength(firmwareFileBytes, Length(firmwareFile));
|
||||||
|
for charIdx := 1 to Length(firmwareFile) do
|
||||||
|
firmwareFileBytes[charIdx - 1] := Ord(firmwareFile[charIdx]);
|
||||||
headerByteCount := 3 + Length(firmwareFileBytes);
|
headerByteCount := 3 + Length(firmwareFileBytes);
|
||||||
line := 'S0' + Format('%.2X', [headerByteCount]) + '0000';
|
line := 'S0' + Format('%.2X', [headerByteCount]) + '0000';
|
||||||
for byteIdx := 0 to (Length(firmwareFileBytes) - 1) do
|
for byteIdx := 0 to (Length(firmwareFileBytes) - 1) do
|
||||||
|
@ -984,7 +1100,7 @@ end; //*** end of Load ***
|
||||||
// DESCRIPTION: Saves the firmware data to the specified firmware file.
|
// DESCRIPTION: Saves the firmware data to the specified firmware file.
|
||||||
//
|
//
|
||||||
//***************************************************************************************
|
//***************************************************************************************
|
||||||
function TBinaryFileHandler.Save(firmwareFile: String; segments: TObjectList<TDataSegment>): Boolean;
|
function TBinaryFileHandler.Save(firmwareFile: String; segments: TDataSegmentList): Boolean;
|
||||||
var
|
var
|
||||||
startAddr: Longword;
|
startAddr: Longword;
|
||||||
endAddr: Longword;
|
endAddr: Longword;
|
||||||
|
@ -1064,9 +1180,8 @@ constructor TFirmwareData.Create;
|
||||||
begin
|
begin
|
||||||
// call inherited constructor
|
// call inherited constructor
|
||||||
inherited Create;
|
inherited Create;
|
||||||
// create empty data segments list and set it to own the segments for automatic freeing
|
// create empty data segments list
|
||||||
FSegmentList := TObjectList<TDataSegment>.Create();
|
FSegmentList := TDataSegmentList.Create();
|
||||||
FSegmentList.OwnsObjects := True;
|
|
||||||
end; //*** end of Create ***
|
end; //*** end of Create ***
|
||||||
|
|
||||||
|
|
||||||
|
@ -1114,6 +1229,21 @@ begin
|
||||||
end; //*** end of GetSegment ***
|
end; //*** end of GetSegment ***
|
||||||
|
|
||||||
|
|
||||||
|
//***************************************************************************************
|
||||||
|
// NAME: FirmwareDataCompareSegments
|
||||||
|
// PARAMETER: Item1 First item for the comparison.
|
||||||
|
// Item2 Second item for the comparison.
|
||||||
|
// RETURN VALUE: 1 if Item1's identifier is larger, -1 if Item1's identifier is
|
||||||
|
// smaller, 0 if the identifiers are equal.
|
||||||
|
// DESCRIPTION: Custom sorting routine for the entries in filter.
|
||||||
|
//
|
||||||
|
//***************************************************************************************
|
||||||
|
function FirmwareDataCompareSegments(Item1, Item2: Pointer): Integer;
|
||||||
|
begin
|
||||||
|
Result := TDataSegment(Item1).BaseAddress - TDataSegment(Item2).BaseAddress;
|
||||||
|
end; //*** end of FirmwareDataCompareSegments ***
|
||||||
|
|
||||||
|
|
||||||
//***************************************************************************************
|
//***************************************************************************************
|
||||||
// NAME: SortSegments
|
// NAME: SortSegments
|
||||||
// PARAMETER: none
|
// PARAMETER: none
|
||||||
|
@ -1123,12 +1253,7 @@ end; //*** end of GetSegment ***
|
||||||
//***************************************************************************************
|
//***************************************************************************************
|
||||||
procedure TFirmwareData.SortSegments;
|
procedure TFirmwareData.SortSegments;
|
||||||
begin
|
begin
|
||||||
FSegmentList.Sort(TComparer<TDataSegment>.Construct(
|
FSegmentList.Sort(@FirmwareDataCompareSegments);
|
||||||
function (const L, R: TDataSegment): integer
|
|
||||||
begin
|
|
||||||
result := L.BaseAddress - R.BaseAddress;
|
|
||||||
end
|
|
||||||
));
|
|
||||||
end; //*** end of SortSegments ***
|
end; //*** end of SortSegments ***
|
||||||
|
|
||||||
|
|
||||||
|
@ -1574,7 +1699,11 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// set onload handler which does the actual data processing
|
// set onload handler which does the actual data processing
|
||||||
|
{$IFDEF FPC}
|
||||||
|
firmwareFileHandler.OnDataRead := @FirmwareFileDataRead;
|
||||||
|
{$ELSE}
|
||||||
firmwareFileHandler.OnDataRead := FirmwareFileDataRead;
|
firmwareFileHandler.OnDataRead := FirmwareFileDataRead;
|
||||||
|
{$ENDIF}
|
||||||
// load data from the file
|
// load data from the file
|
||||||
Result := firmwareFileHandler.Load(firmwareFile);
|
Result := firmwareFileHandler.Load(firmwareFile);
|
||||||
|
|
||||||
|
@ -1631,8 +1760,10 @@ end; //*** end of SaveToFile ***
|
||||||
//
|
//
|
||||||
//***************************************************************************************
|
//***************************************************************************************
|
||||||
procedure TFirmwareData.Dump;
|
procedure TFirmwareData.Dump;
|
||||||
|
{$IFDEF DEBUG}
|
||||||
var
|
var
|
||||||
segmentIdx: Integer;
|
segmentIdx: Integer;
|
||||||
|
{$ENDIF}
|
||||||
begin
|
begin
|
||||||
{$IFDEF DEBUG}
|
{$IFDEF DEBUG}
|
||||||
for segmentIdx := 0 to (SegmentCount - 1) do
|
for segmentIdx := 0 to (SegmentCount - 1) do
|
||||||
|
|
Loading…
Reference in New Issue