Refs #190. Improved S-record parsing by integrating the TFirmwareData class into Microboot's communication interface DLLs.

git-svn-id: https://svn.code.sf.net/p/openblt/code/trunk@201 5dc33758-31d5-4daf-9ae8-b24bf3d40d73
This commit is contained in:
Frank Voorburg 2017-01-09 09:24:36 +00:00
parent d312562e40
commit 403597afb1
17 changed files with 220 additions and 962 deletions

View File

@ -1,644 +0,0 @@
unit SRecReader;
//***************************************************************************************
// Project Name: Motorola S-Record Reader
// Description: Class used to read S-Record files. Supports both S19 and S28 records.
// File Name: SRecReader.pas
//
//---------------------------------------------------------------------------------------
// C O P Y R I G H T
//---------------------------------------------------------------------------------------
// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved
//
// This software has been carefully tested, but is not guaranteed for any particular
// purpose. The author does not offer any warranties and does not guarantee the accuracy,
// adequacy, or completeness of the software and is not responsible for any errors or
// omissions or the results obtained from use of the software.
//
//---------------------------------------------------------------------------------------
// L I C E N S E
//---------------------------------------------------------------------------------------
// This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option) any later
// version.
//
// OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.
//
// You have received a copy of the GNU General Public License along with OpenBLT. It
// should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy.
//
//***************************************************************************************
interface
//***************************************************************************************
// Includes
//***************************************************************************************
uses
Windows, Messages, SysUtils, Classes, Forms;
//***************************************************************************************
// Type Definitions
//***************************************************************************************
type
PByte = ^Byte;
TSRecLineType = (ltInvalid, ltS0, ltS1, ltS2, ltS3, ltS7, ltS8, ltS9);
TSRecType = (tpS1, tpS2, tpS3, tpMixed);
type
TSRecData = record
val : Byte;
addr : LongWord;
end;
type
PRegion = ^TRegion;
TRegion = record
addr : LongWord;
size : LongWord;
end;
type
TSRecReader = class(TObject)
private
FFileName : String;
FDataSize : Longword;
FFirstAddr : LongWord;
FLastAddr : LongWord;
FFileType : TSRecType;
FRegions : TList;
FRegionsCnt : Word;
function GetLineType(line: String) : TSRecLineType;
function GetLineSize(line: String; var size: Word) : Boolean;
function GetLineData(line: String; index: Word; var data: TSRecData) : Boolean;
function GetLineAddress(line: String; var address: LongWord) : Boolean;
procedure UpdateRegions(addr: LongWord; size: Word);
public
constructor Create;
destructor Destroy; override;
function SetFileName(fileName : String) : Boolean;
function GetFileName : String;
function GetDataSize : Longword;
function GetFirstAddress : Longword;
function GetLastAddress : Longword;
function GetRegionCount : Word;
procedure GetRegion(index : Word; var addr : Longword; var length : Longword);
procedure GetData(var buffer : array of Byte; addr : Longword; length : Longword);
function GetFileType : TSRecType;
function BlankCheck(addr : Longword; length : Longword) : Boolean;
end;
implementation
//***************************************************************************************
// NAME: Create
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Class constructore
//
//***************************************************************************************
constructor TSRecReader.Create;
begin
inherited Create;
FRegions := TList.Create;
end; //*** end of Create ***
//***************************************************************************************
// NAME: Destroy
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Class destructor
//
//***************************************************************************************
destructor TSRecReader.Destroy;
var
index : Word;
region: PRegion;
begin
if FRegions.Count > 0 then
begin
for index := 0 to FRegions.Count-1 do
begin
region := FRegions.Items[index];
Dispose(region);
end;
end;
FRegions.Free;
inherited;
end; //*** end of Destroy ***
//***************************************************************************************
// NAME: UpdateRegions
// PARAMETER: addr: start address of data
// size: length of data
// RETURN VALUE: none
// DESCRIPTION: Processes the data by categorizing it into a region.
//
//***************************************************************************************
procedure TSRecReader.UpdateRegions(addr: LongWord; size: Word);
var
index : Word;
added : Boolean;
region: PRegion;
begin
added := False;
if FRegions.Count > 0 then
begin
// loop through all existing regions
for index := 0 to FRegions.Count-1 do
begin
// set pointer to this region
region := FRegions.Items[index];
// does data fit at the end?
if (region^.addr+region^.size) = addr then
begin
// add at the end of this region
region^.size := region^.size + size;
added := True;
end
// does data fit at the start?
else if region^.addr = (addr+size) then
begin
// add at the start of this region
region^.addr := region^.addr - size;
added := True;
end;
// was data added to a region?
if added then
begin
Break; // no need to continue loop
end;
end;
end;
// data couldn't be added to an existing region?
if not added then
begin
// create a new region and add the data there
New(region);
region^.addr := addr;
region^.size := size;
FRegions.Add(region);
end;
end; //*** end of UpdateRegions ***
//***************************************************************************************
// NAME: GetLineType
// PARAMETER: Line from S-Record
// RETURN VALUE: line type
// DESCRIPTION: Determines what type of S-Record line we're dealing with.
//
//***************************************************************************************
function TSRecReader.GetLineType(line: String) : TSRecLineType;
begin
Result := ltInvalid;
if Pos('S0', UpperCase(line)) > 0 then Result := ltS0;
if Pos('S1', UpperCase(line)) > 0 then Result := ltS1;
if Pos('S2', UpperCase(line)) > 0 then Result := ltS2;
if Pos('S3', UpperCase(line)) > 0 then Result := ltS3;
if Pos('S7', UpperCase(line)) > 0 then Result := ltS7;
if Pos('S8', UpperCase(line)) > 0 then Result := ltS8;
if Pos('S9', UpperCase(line)) > 0 then Result := ltS9;
end; //*** end of GetLineType ***
//***************************************************************************************
// NAME: GetLineSize
// PARAMETER: Line from S-Record
// RETURN VALUE: Number of data bytes
// DESCRIPTION: Obtains the number of databytes in the specified S-Record line.
//
//***************************************************************************************
function TSRecReader.GetLineSize(line: String; var size: Word) : Boolean;
var
unusedBytes : Byte;
begin
Result := false; // init
if GetLineType(line) = ltS1 then
unusedBytes := 3 // 2 for address and 1 for checksum
else if GetLineType(line) = ltS2 then
unusedBytes := 4 // 3 for address and 1 for checksum
else if GetLineType(line) = ltS3 then
unusedBytes := 5 // 4 for address and 1 for checksum
else
Exit; // not a S1 or S2 line
size := StrToInt('$' + Copy(line, 3, 2)) - unusedBytes;
Result := true;
end; //*** end of GetLineSize ***
//***************************************************************************************
// NAME: GetLineData
// PARAMETER: Line from S-Record
// RETURN VALUE: data at a specific index (starts at 0)
// DESCRIPTION: Obtains the data at a specific index in the specified S-Record line.
//
//***************************************************************************************
function TSRecReader.GetLineData(line: String; index: Word; var data: TSRecData) : Boolean;
var
dataOffset : Byte;
lineSize : Word;
lineAddr : LongWord;
begin
Result := false; // init
if GetLineType(line) = ltS1 then
dataOffset := 9 // characters untill we reach actual data
else if GetLineType(line) = ltS2 then
dataOffset := 11 // characters untill we reach actual data
else if GetLineType(line) = ltS3 then
dataOffset := 13 // characters untill we reach actual data
else
Exit; // not a S1, S2 or S3 line
// make sure index parameter is valid
if not GetLineSize(line, lineSize) then
Exit
else
if index > (lineSize-1) then Exit;
// obtain the start address of the line
if not GetLineAddress(line, lineAddr) then
Exit;
data.val := StrToInt('$' + Copy(line, dataOffset+(index*2), 2));
data.addr := lineAddr + index;
Result := true;
end; //*** end of GetLineData ***
//***************************************************************************************
// NAME: GetLineAddress
// PARAMETER: Line from S-Record
// RETURN VALUE: Start address
// DESCRIPTION: Obtains the start address as specified in the S-Record line.
//
//***************************************************************************************
function TSRecReader.GetLineAddress(line: String; var address: LongWord) : Boolean;
var
addrLength : Byte;
begin
Result := false; // init
if GetLineType(line) = ltS1 then
addrLength := 4 // 2 byte address
else if GetLineType(line) = ltS2 then
addrLength := 6 // 3 byte address
else if GetLineType(line) = ltS3 then
addrLength := 8 // 4 byte address
else
Exit; // not a S1, S2 or S3 line
address := StrToInt('$' + Copy(line, 5, addrLength));
Result := true;
end; //*** end of GetLineAddress ***
//***************************************************************************************
// NAME: SetFileName
// PARAMETER: Filename with full path
// RETURN VALUE: True when the S-Record was valid and could be loaded, otherwise False.
// DESCRIPTION: Function verifies that the file is actually a S-Record. If so, then
// the most class properties are set based on the info in the S-Record.
//
//***************************************************************************************
function TSRecReader.SetFileName(fileName : String) : Boolean;
var
SRecFile : TextFile;
Line : string;
ValidSRec : Boolean;
LineSize : Word;
LineAddr : LongWord;
S1RecFound : Boolean;
S2RecFound : Boolean;
S3RecFound : Boolean;
begin
// first reset all the internal properties
FFileName := '';
FDataSize := 0;
FFirstAddr := $ffffffff;
FLastAddr := 0;
FFileType := tpS1;
FRegionsCnt := 0;
FRegions.Clear;
// init locals
S1RecFound := false;
S2RecFound := false;
S3RecFound := false;
Result := false;
ValidSRec := false;
// 1. Verify if file exists
if not FileExists(fileName) then Exit;
// 2. Verify if file contains S-Records
AssignFile(SRecFile, fileName); // get file handle
Reset(SRecFile); // go to start of file
while not Eof(SRecFile) do
begin
ReadLn(SRecFile, Line); // read line from file
if (GetLineType(Line) = ltS1) or (GetLineType(Line) = ltS2) or
(GetLineType(Line) = ltS3) then
begin
ValidSRec := true;
Break; // valid S-Record
end;
end;
CloseFile(SRecFile); // release file
if not ValidSRec then Exit;
// 3. Calculate datasize, first address and last address
AssignFile(SRecFile, fileName); // get file handle
Reset(SRecFile); // go to start of file
while not Eof(SRecFile) do
begin
ReadLn(SRecFile, Line); // read line from file
LineSize := 0; // init
if GetLineSize(Line, LineSize) then
FDataSize := FDataSize + LineSize; // add to previous value
if GetLineAddress(Line, LineAddr) then
begin
if LineAddr < FFirstAddr then
FFirstAddr := LineAddr;
if LineAddr > FLastAddr then
FLastAddr := LineAddr + LineSize -1;
end;
// check line type
if GetLineType(line) = ltS1 then
S1RecFound := true;
if GetLineType(line) = ltS2 then
S2RecFound := true;
if GetLineType(line) = ltS3 then
S3RecFound := true;
end;
CloseFile(SRecFile); // release file
// set file type
if (S1RecFound) and (not S2RecFound) and (not S3RecFound) then
FFileType := tpS1
else if (S2RecFound) and (not S1RecFound) and (not S3RecFound) then
FFileType := tpS2
else if (not S2RecFound) and (not S1RecFound) and (S3RecFound) then
FFileType := tpS3
else
FFileType := tpMixed;
// 4. Determine regions
AssignFile(SRecFile, fileName); // get file handle
Reset(SRecFile); // go to start of file
while not Eof(SRecFile) do
begin
ReadLn(SRecFile, Line); // read line from file
LineSize := 0; // init
if GetLineAddress(Line, LineAddr) then
begin
if GetLineSize(Line, LineSize) then
begin
UpdateRegions(LineAddr, LineSize);
end;
end;
end;
CloseFile(SRecFile); // release file
// set region count
FRegionsCnt := FRegions.Count;
// 5. Verify properties and if ok, set the FFilename property
if (FDataSize <> 0) and (FFirstAddr <> $ffffffff) and (FLastAddr <> 0) then
begin
FFileName := fileName; // set the filename property
Result := true;
end;
end; //*** end of SetFileName ***
//***************************************************************************************
// NAME: GetFileName
// PARAMETER: none
// RETURN VALUE: Filename with full path or '' when invalid.
// DESCRIPTION: S-Record filename that is configured to be read be this class.
//
//***************************************************************************************
function TSRecReader.GetFileName : String;
begin
Result := FFileName;
end; //*** end of GetFileName ***
//***************************************************************************************
// NAME: GetDataSize
// PARAMETER: none
// RETURN VALUE: Size of data.
// DESCRIPTION: Obtains the number of databytes in the S-Record. 0xFF values are
// not included.
//
//***************************************************************************************
function TSRecReader.GetDataSize : Longword;
begin
Result := FDataSize;
end; //*** end of GetDataSize ***
//***************************************************************************************
// NAME: GetFirstAddress
// PARAMETER: none
// RETURN VALUE: First address in S-Record.
// DESCRIPTION: Obtains the first memory address with data in the S-Record.
//
//***************************************************************************************
function TSRecReader.GetFirstAddress : Longword;
begin
Result := FFirstAddr;
end; //*** end of GetFirstAddress ***
//***************************************************************************************
// NAME: GetLastAddress
// PARAMETER: none
// RETURN VALUE: Last address in S-Record.
// DESCRIPTION: Obtains the last memory address with data in the S-Record.
//
//***************************************************************************************
function TSRecReader.GetLastAddress : Longword;
begin
Result := FLastAddr;
end; //*** end of GetLastAddress ***
//***************************************************************************************
// NAME: GetRegionCount
// PARAMETER: none
// RETURN VALUE: Number of address regions
// DESCRIPTION: Obtains the number of address regions found in the S-record.
//
//***************************************************************************************
function TSRecReader.GetRegionCount : Word;
begin
Result := FRegionsCnt;
end; //*** end of GetRegionCount ***
//***************************************************************************************
// NAME: GetRegion
// PARAMETER: index: region index to retrieve info from
// addr: destination for region's start address
// length: destination for region's length
// RETURN VALUE: none
// DESCRIPTION: Obtains the address region info.
//
//***************************************************************************************
procedure TSRecReader.GetRegion(index : Word; var addr : Longword; var length : Longword);
var
region: PRegion;
begin
// initialize return values
addr := 0;
length := 0;
if FRegions.Count > 0 then
begin
if index < FRegions.Count then
begin
// set pointer to this region
region := FRegions.Items[index];
// obtain region info
addr := region^.addr;
length := region^.size;
end;
end;
end; //*** end of GetRegion ***
//***************************************************************************************
// NAME: GetData
// PARAMETER: buffer is a pointer to a byte buffer where the data will be written
// to from memory address addr to addr+length.
// RETURN VALUE: none
// DESCRIPTION: Obtains the data in the S-Record for a memory block that starts at
// addr and goes until addr+length and stores the data in buffer. empty
// data will be filled with 0xFF.
//
//***************************************************************************************
procedure TSRecReader.GetData(var buffer : array of Byte; addr : Longword; length : Longword);
var
data : TSRecData;
line : string;
lineAddr : LongWord;
lineSize : Word;
SRecFile : TextFile;
cnt : Word;
ok2Continue : boolean;
begin
// check parameters
if length = 0 then Exit;
// first init entire buffer to 0xff
for cnt := 0 to length-1 do
begin
buffer[cnt] := $ff;
end;
// go through each line to see if it has data for us
AssignFile(SRecFile, FFileName); // get file handle
Reset(SRecFile); // go to start of file
while not Eof(SRecFile) do
begin
// this can take a while so process messages to not stall the parent app
Application.ProcessMessages;
ReadLn(SRecFile, line); // read line from file
ok2Continue := true; // init
// obtain line properties
if not GetLineAddress(line, lineAddr) then ok2Continue := false;
if not GetLineSize(line, lineSize) then ok2Continue := false;
if ok2Continue then
begin
// process all data on the line
for cnt := 0 to lineSize-1 do
begin
// read data info
if not GetLineData(line, cnt, data) then ok2Continue := false;
if ok2Continue then
begin
// is this one for us?
if (data.addr >= addr) and (data.addr <= (addr+length-1)) then
begin
// store it in the memory buffer
buffer[data.addr-addr] := data.val;
end;
end;
end;
end;
end;
CloseFile(SRecFile); // release file
end; //*** end of GetData ***
//***************************************************************************************
// NAME: GetFileType
// PARAMETER: none
// RETURN VALUE: S-Record file type
// DESCRIPTION: Determines is the file contains just S1 data lines, just S2 data
// lines. or a combination of these two.
//
//***************************************************************************************
function TSRecReader.GetFileType : TSRecType;
begin
Result := FFileType;
end; //*** end of GetFileType ***
//***************************************************************************************
// NAME: BlankCheck
// PARAMETER: checks from addr to addr+length-1.
// RETURN VALUE: true if all bytes are 0xff, false otherwise
// DESCRIPTION: Checks if a memory range in the S-Record file is empty (0xff) or not.
//
//***************************************************************************************
function TSRecReader.BlankCheck(addr : Longword; length : Longword) : Boolean;
var
buffer : array of Byte;
cnt : LongWord;
begin
Result := true;
SetLength(buffer, length); // init size of the dynamic array
GetData(buffer, addr, length); // fill it with the data contents from the S-Record
for cnt := 0 to length-1 do
begin
if buffer[cnt] <> $ff then
begin
Result := false; // memory range is not blank
Break; // no need to continue loop
end;
end;
end; //*** end of BlankCheck ***
end.
//******************************** end of SRecReader.pas ********************************

View File

@ -1,214 +0,0 @@
unit XcpDataFile;
//***************************************************************************************
// Description: XCP data file interface.
// File Name: XcpDataFile.pas
//
//---------------------------------------------------------------------------------------
// C O P Y R I G H T
//---------------------------------------------------------------------------------------
// Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved
//
// This software has been carefully tested, but is not guaranteed for any particular
// purpose. The author does not offer any warranties and does not guarantee the accuracy,
// adequacy, or completeness of the software and is not responsible for any errors or
// omissions or the results obtained from use of the software.
//
//---------------------------------------------------------------------------------------
// L I C E N S E
//---------------------------------------------------------------------------------------
// This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option) any later
// version.
//
// OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.
//
// You have received a copy of the GNU General Public License along with OpenBLT. It
// should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy.
//
//***************************************************************************************
interface
//***************************************************************************************
// Includes
//***************************************************************************************
uses
Windows, Messages, SysUtils, Classes, Forms, SRecReader;
//***************************************************************************************
// Type Definitions
//***************************************************************************************
type
TXcpDataFile = class(TObject)
private
FDataFileReady : Boolean;
FRegionCount : Word;
FDataFile : TSRecReader;
public
constructor Create(dataFile: string);
destructor Destroy; override;
function GetDataCnt : LongWord;
function GetRegionCnt : Word;
procedure GetRegionInfo(region : Word; var addr : Longword; var len : Longword);
function GetRegionData(region : Word; var data : array of Byte) : LongWord;
end;
implementation
//***************************************************************************************
// NAME: Create
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Class constructor
//
//***************************************************************************************
constructor TXcpDataFile.Create(dataFile: string);
begin
// call inherited constructor
inherited Create;
// instantiate S-Record reader object
FDataFile := TSRecReader.Create;
// reset data file ready flag
FDataFileReady := false;
// reset the region count
FRegionCount := 0;
// open the data file as an S-Record file
if FDataFile.SetFileName(dataFile) then
begin
// set data file ready flag
FDataFileReady := true;
// obtain the number of data regions
FRegionCount := FDataFile.GetRegionCount;
end;
end; //*** end of Create ***
//***************************************************************************************
// NAME: Destroy
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Class destructor
//
//***************************************************************************************
destructor TXcpDataFile.Destroy;
begin
// release S-Record reader object
FDataFile.Free;
// call inherited destructor
inherited;
end; //*** end of Destroy ***
//***************************************************************************************
// NAME: GetDataCnt
// PARAMETER: none
// RETURN VALUE: number of data bytes
// DESCRIPTION: Returns the number of data bytes in the data file
//
//***************************************************************************************
function TXcpDataFile.GetDataCnt : LongWord;
begin
// init return value
result := 0;
// verify data file state
if not FDataFileReady then Exit;
// return the number of data bytes in the data file
result := FDataFile.GetDataSize;
end; //*** end of GetDataCnt ***
//***************************************************************************************
// NAME: GetRegionCnt
// PARAMETER: none
// RETURN VALUE: number of data regions
// DESCRIPTION: Returns the number of data regions in the data file
//
//***************************************************************************************
function TXcpDataFile.GetRegionCnt : Word;
begin
// init return value
result := 0;
// verify data file state
if not FDataFileReady then Exit;
// return the number of data regions
result := FRegionCount;
end; //*** end of GetRegionCnt ***
//***************************************************************************************
// NAME: GetRegionInfo
// PARAMETER: region index and parameters where to store the region start address
// and length info.
// RETURN VALUE: none
// DESCRIPTION: Returns the number of data bytes in the specified region and its
// start address.
//
//***************************************************************************************
procedure TXcpDataFile.GetRegionInfo(region : Word; var addr : Longword; var len : Longword);
begin
// init return parameters
addr := 0;
len := 0;
// verify data file state
if not FDataFileReady then Exit;
// validate input parameter
if region > FRegionCount-1 then Exit;
// obtain the region information
FDataFile.GetRegion(region, addr, len);
end; //*** end of GetRegionInfo ***
//***************************************************************************************
// NAME: GetRegionData
// PARAMETER: region index and a pointer to the data buffer where the data will be
// stored.
// RETURN VALUE: Number of data bytes stored in the data buffer
// DESCRIPTION: Reads the data from a specific region into the specified data buffer.
//
//***************************************************************************************
function TXcpDataFile.GetRegionData(region : Word; var data : array of Byte) : LongWord;
var
addr : LongWord;
len : LongWord;
begin
// init return value
result := 0;
// verify data file state
if not FDataFileReady then Exit;
// validate input parameter
if region > FRegionCount-1 then Exit;
// obtain region info
FDataFile.GetRegion(region, addr, len);
// obtain the region data
FDataFile.GetData(data, addr, len);
// return the number of data bytes stored in the data buffer
result := len;
end; //*** end of GetRegionData ***
end.
//******************************** end of XcpDataFile.pas *******************************

View File

@ -46,11 +46,10 @@ uses
Classes, Classes,
Extctrls, Extctrls,
XcpProtection in '..\..\XcpProtection.pas', XcpProtection in '..\..\XcpProtection.pas',
SRecReader in '..\..\SRecReader.pas',
XcpDataFile in '..\..\XcpDataFile.pas',
XcpLoader in '..\..\XcpLoader.pas', XcpLoader in '..\..\XcpLoader.pas',
XcpTransport in 'XcpTransport.pas', XcpTransport in 'XcpTransport.pas',
XcpSettings in 'XcpSettings.pas' {XcpSettingsForm}; XcpSettings in 'XcpSettings.pas' {XcpSettingsForm},
FirmwareData in '..\..\..\..\Library\FirmwareData\pas\FirmwareData.pas';
//*************************************************************************************** //***************************************************************************************
// Global Constants // Global Constants
@ -90,7 +89,7 @@ var
timer : TTimer; timer : TTimer;
events : TEventHandlers; events : TEventHandlers;
loader : TXcpLoader; loader : TXcpLoader;
datafile : TXcpDataFile; datafile : TFirmwareData;
progdata : array of Byte; progdata : array of Byte;
progfile : string; progfile : string;
stopRequest : boolean; stopRequest : boolean;
@ -244,13 +243,15 @@ procedure TEventHandlers.OnTimeout(Sender: TObject);
var var
errorInfo : string; errorInfo : string;
progress : longword; progress : longword;
regionCnt : longword; segmentCnt : longword;
byteCnt : longword;
currentWriteCnt : word; currentWriteCnt : word;
sessionStartResult : byte; sessionStartResult : byte;
bufferOffset : longword; bufferOffset : longword;
addr : longword; addr : longword;
len : longword; len : longword;
dataSizeKB : real; dataSizeKB : real;
dataSizeBytes : integer;
begin begin
timer.Enabled := False; timer.Enabled := False;
@ -338,25 +339,41 @@ begin
// still here so programming session was started // still here so programming session was started
MbiCallbackOnLog('Programming session started. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session started. t='+ShortString(TimeToStr(Time)));
// create the datafile object // read the firmware file
datafile := TXcpDataFile.Create(progfile); MbiCallbackOnInfo('Reading firmware file.');
MbiCallbackOnLog('Reading firmware file. t='+ShortString(TimeToStr(Time)));
// create the datafile object and load the file contents
datafile := TFirmwareData.Create;
if not datafile.LoadFromFile(progfile, False) then
begin
MbiCallbackOnLog('Could not read firmware file (' + ShortString(ExtractFilename(progfile)) +'). t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Could not read firmware file (' + ShortString(ExtractFilename(progfile)) +').');
datafile.Free;
Exit;
end;
// compute the size in kbytes // compute the size in kbytes
dataSizeKB := datafile.GetDataCnt / 1024; dataSizeBytes := 0;
// loop through all segment to get the total byte count
for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin
dataSizeBytes := dataSizeBytes + datafile.Segment[segmentCnt].Size;
end;
// convert bytes to kilobytes
dataSizeKB := dataSizeBytes / 1024;
// Call application callback when we start the actual download // Call application callback when we start the actual download
MbiCallbackOnStarted(datafile.GetDataCnt); MbiCallbackOnStarted(dataSizeBytes);
// Init progress to 0 progress // Init progress to 0 progress
progress := 0; progress := 0;
MbiCallbackOnProgress(progress); MbiCallbackOnProgress(progress);
//---------------- next clear the memory regions -------------------------------------- //---------------- next clear the memory regions --------------------------------------
// update the user info // update the user info
MbiCallbackOnInfo('Erasing memory...'); MbiCallbackOnInfo('Erasing memory...');
for regionCnt := 0 to datafile.GetRegionCnt-1 do for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin begin
// check if the user cancelled // check if the user cancelled
if stopRequest then if stopRequest then
@ -366,11 +383,13 @@ begin
loader.Disconnect; loader.Disconnect;
MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Programming session cancelled by user.'); MbiCallbackOnError('Programming session cancelled by user.');
datafile.Free;
Exit; Exit;
end; end;
// obtain the region info // obtain the region info
datafile.GetRegionInfo(regionCnt, addr, len); addr := datafile.Segment[segmentCnt].BaseAddress;
len := datafile.Segment[segmentCnt].Size;
// erase the memory // erase the memory
MbiCallbackOnLog('Clearing Memory '+ShortString(Format('addr:0x%x,len:0x%x',[addr,len]))+'. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Clearing Memory '+ShortString(Format('addr:0x%x,len:0x%x',[addr,len]))+'. t='+ShortString(TimeToStr(Time)));
@ -386,17 +405,19 @@ begin
end; end;
//---------------- next program the memory regions ------------------------------------ //---------------- next program the memory regions ------------------------------------
for regionCnt := 0 to datafile.GetRegionCnt-1 do for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin begin
// update the user info // update the user info
MbiCallbackOnInfo('Reading file...'); MbiCallbackOnInfo('Reading file...');
// obtain the region info // obtain the region info
datafile.GetRegionInfo(regionCnt, addr, len); addr := datafile.Segment[segmentCnt].BaseAddress;
// dynamically allocated buffer memory len := datafile.Segment[segmentCnt].Size;
SetLength(progdata, len); SetLength(progdata, len);
// obtain the regiond data for byteCnt := 0 to (len - 1) do
datafile.GetRegionData(regionCnt, progdata); begin
progdata[byteCnt] := datafile.Segment[segmentCnt].Data[byteCnt];
end;
bufferOffset := 0; bufferOffset := 0;
while len > 0 do while len > 0 do
@ -409,6 +430,7 @@ begin
loader.Disconnect; loader.Disconnect;
MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Programming session cancelled by user.'); MbiCallbackOnError('Programming session cancelled by user.');
datafile.Free;
Exit; Exit;
end; end;
@ -458,7 +480,7 @@ begin
MbiCallbackOnLog('Programming session stopped. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session stopped. t='+ShortString(TimeToStr(Time)));
// all done so set progress to 100% and finish up // all done so set progress to 100% and finish up
progress := datafile.GetDataCnt; progress := dataSizeBytes;
datafile.Free; datafile.Free;
MbiCallbackOnProgress(progress); MbiCallbackOnProgress(progress);
MbiCallbackOnLog('File successfully downloaded t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('File successfully downloaded t='+ShortString(TimeToStr(Time)));
@ -607,7 +629,7 @@ end; //*** end of MbiDescription ***
//*************************************************************************************** //***************************************************************************************
function MbiVersion : Longword; stdcall; function MbiVersion : Longword; stdcall;
begin begin
Result := 10000; // v1.00.00 Result := 10100; // v1.01.00
end; //*** end of MbiVersion *** end; //*** end of MbiVersion ***

View File

@ -70,6 +70,8 @@
<DCC_Optimize>false</DCC_Optimize> <DCC_Optimize>false</DCC_Optimize>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''"> <PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.1.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.1.0.0;Comments=</VerInfo_Keys>
<VerInfo_MinorVer>1</VerInfo_MinorVer>
<Debugger_HostApplication>C:\Work\software\OpenBLT\Host\MicroBoot.exe</Debugger_HostApplication> <Debugger_HostApplication>C:\Work\software\OpenBLT\Host\MicroBoot.exe</Debugger_HostApplication>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<Manifest_File>(None)</Manifest_File> <Manifest_File>(None)</Manifest_File>
@ -80,13 +82,12 @@
<MainSource>MainSource</MainSource> <MainSource>MainSource</MainSource>
</DelphiCompile> </DelphiCompile>
<DCCReference Include="..\..\XcpProtection.pas"/> <DCCReference Include="..\..\XcpProtection.pas"/>
<DCCReference Include="..\..\SRecReader.pas"/>
<DCCReference Include="..\..\XcpDataFile.pas"/>
<DCCReference Include="..\..\XcpLoader.pas"/> <DCCReference Include="..\..\XcpLoader.pas"/>
<DCCReference Include="XcpTransport.pas"/> <DCCReference Include="XcpTransport.pas"/>
<DCCReference Include="XcpSettings.pas"> <DCCReference Include="XcpSettings.pas">
<Form>XcpSettingsForm</Form> <Form>XcpSettingsForm</Form>
</DCCReference> </DCCReference>
<DCCReference Include="..\..\..\..\Library\FirmwareData\pas\FirmwareData.pas"/>
<BuildConfiguration Include="Debug"> <BuildConfiguration Include="Debug">
<Key>Cfg_2</Key> <Key>Cfg_2</Key>
<CfgParent>Base</CfgParent> <CfgParent>Base</CfgParent>

View File

@ -46,12 +46,11 @@ uses
Classes, Classes,
Extctrls, Extctrls,
XcpProtection in '..\..\XcpProtection.pas', XcpProtection in '..\..\XcpProtection.pas',
SRecReader in '..\..\SRecReader.pas',
XcpDataFile in '..\..\XcpDataFile.pas',
XcpLoader in '..\..\XcpLoader.pas', XcpLoader in '..\..\XcpLoader.pas',
XcpTransport in 'XcpTransport.pas', XcpTransport in 'XcpTransport.pas',
XcpSettings in 'XcpSettings.pas' {XcpSettingsForm}, XcpSettings in 'XcpSettings.pas' {XcpSettingsForm},
PCANBasic in 'PCANBasic.pas'; PCANBasic in 'PCANBasic.pas',
FirmwareData in '..\..\..\..\Library\FirmwareData\pas\FirmwareData.pas';
//*************************************************************************************** //***************************************************************************************
// Global Constants // Global Constants
@ -91,7 +90,7 @@ var
timer : TTimer; timer : TTimer;
events : TEventHandlers; events : TEventHandlers;
loader : TXcpLoader; loader : TXcpLoader;
datafile : TXcpDataFile; datafile : TFirmwareData;
progdata : array of Byte; progdata : array of Byte;
progfile : string; progfile : string;
stopRequest : boolean; stopRequest : boolean;
@ -245,13 +244,15 @@ procedure TEventHandlers.OnTimeout(Sender: TObject);
var var
errorInfo : string; errorInfo : string;
progress : longword; progress : longword;
regionCnt : longword; segmentCnt : longword;
byteCnt : longword;
currentWriteCnt : word; currentWriteCnt : word;
sessionStartResult : byte; sessionStartResult : byte;
bufferOffset : longword; bufferOffset : longword;
addr : longword; addr : longword;
len : longword; len : longword;
dataSizeKB : real; dataSizeKB : real;
dataSizeBytes : integer;
begin begin
timer.Enabled := False; timer.Enabled := False;
@ -339,25 +340,41 @@ begin
// still here so programming session was started // still here so programming session was started
MbiCallbackOnLog('Programming session started. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session started. t='+ShortString(TimeToStr(Time)));
// create the datafile object // read the firmware file
datafile := TXcpDataFile.Create(progfile); MbiCallbackOnInfo('Reading firmware file.');
MbiCallbackOnLog('Reading firmware file. t='+ShortString(TimeToStr(Time)));
// create the datafile object and load the file contents
datafile := TFirmwareData.Create;
if not datafile.LoadFromFile(progfile, False) then
begin
MbiCallbackOnLog('Could not read firmware file (' + ShortString(ExtractFilename(progfile)) +'). t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Could not read firmware file (' + ShortString(ExtractFilename(progfile)) +').');
datafile.Free;
Exit;
end;
// compute the size in kbytes // compute the size in kbytes
dataSizeKB := datafile.GetDataCnt / 1024; dataSizeBytes := 0;
// loop through all segment to get the total byte count
for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin
dataSizeBytes := dataSizeBytes + datafile.Segment[segmentCnt].Size;
end;
// convert bytes to kilobytes
dataSizeKB := dataSizeBytes / 1024;
// Call application callback when we start the actual download // Call application callback when we start the actual download
MbiCallbackOnStarted(datafile.GetDataCnt); MbiCallbackOnStarted(dataSizeBytes);
// Init progress to 0 progress // Init progress to 0 progress
progress := 0; progress := 0;
MbiCallbackOnProgress(progress); MbiCallbackOnProgress(progress);
//---------------- next clear the memory regions -------------------------------------- //---------------- next clear the memory regions --------------------------------------
// update the user info // update the user info
MbiCallbackOnInfo('Erasing memory...'); MbiCallbackOnInfo('Erasing memory...');
for regionCnt := 0 to datafile.GetRegionCnt-1 do for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin begin
// check if the user cancelled // check if the user cancelled
if stopRequest then if stopRequest then
@ -367,11 +384,13 @@ begin
loader.Disconnect; loader.Disconnect;
MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Programming session cancelled by user.'); MbiCallbackOnError('Programming session cancelled by user.');
datafile.Free;
Exit; Exit;
end; end;
// obtain the region info // obtain the region info
datafile.GetRegionInfo(regionCnt, addr, len); addr := datafile.Segment[segmentCnt].BaseAddress;
len := datafile.Segment[segmentCnt].Size;
// erase the memory // erase the memory
MbiCallbackOnLog('Clearing Memory '+ShortString(Format('addr:0x%x,len:0x%x',[addr,len]))+'. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Clearing Memory '+ShortString(Format('addr:0x%x,len:0x%x',[addr,len]))+'. t='+ShortString(TimeToStr(Time)));
@ -387,17 +406,19 @@ begin
end; end;
//---------------- next program the memory regions ------------------------------------ //---------------- next program the memory regions ------------------------------------
for regionCnt := 0 to datafile.GetRegionCnt-1 do for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin begin
// update the user info // update the user info
MbiCallbackOnInfo('Reading file...'); MbiCallbackOnInfo('Reading file...');
// obtain the region info // obtain the region info
datafile.GetRegionInfo(regionCnt, addr, len); addr := datafile.Segment[segmentCnt].BaseAddress;
// dynamically allocated buffer memory len := datafile.Segment[segmentCnt].Size;
SetLength(progdata, len); SetLength(progdata, len);
// obtain the regiond data for byteCnt := 0 to (len - 1) do
datafile.GetRegionData(regionCnt, progdata); begin
progdata[byteCnt] := datafile.Segment[segmentCnt].Data[byteCnt];
end;
bufferOffset := 0; bufferOffset := 0;
while len > 0 do while len > 0 do
@ -410,6 +431,7 @@ begin
loader.Disconnect; loader.Disconnect;
MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Programming session cancelled by user.'); MbiCallbackOnError('Programming session cancelled by user.');
datafile.Free;
Exit; Exit;
end; end;
@ -459,7 +481,7 @@ begin
MbiCallbackOnLog('Programming session stopped. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session stopped. t='+ShortString(TimeToStr(Time)));
// all done so set progress to 100% and finish up // all done so set progress to 100% and finish up
progress := datafile.GetDataCnt; progress := dataSizeBytes;
datafile.Free; datafile.Free;
MbiCallbackOnProgress(progress); MbiCallbackOnProgress(progress);
MbiCallbackOnLog('File successfully downloaded t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('File successfully downloaded t='+ShortString(TimeToStr(Time)));
@ -608,7 +630,7 @@ end; //*** end of MbiDescription ***
//*************************************************************************************** //***************************************************************************************
function MbiVersion : Longword; stdcall; function MbiVersion : Longword; stdcall;
begin begin
Result := 10000; // v1.00.00 Result := 10100; // v1.01.00
end; //*** end of MbiVersion *** end; //*** end of MbiVersion ***

View File

@ -70,6 +70,8 @@
<DCC_Optimize>false</DCC_Optimize> <DCC_Optimize>false</DCC_Optimize>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''"> <PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.1.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.1.0.0;Comments=</VerInfo_Keys>
<VerInfo_MinorVer>1</VerInfo_MinorVer>
<Debugger_HostApplication>C:\Work\software\OpenBLT\Host\MicroBoot.exe</Debugger_HostApplication> <Debugger_HostApplication>C:\Work\software\OpenBLT\Host\MicroBoot.exe</Debugger_HostApplication>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<Manifest_File>(None)</Manifest_File> <Manifest_File>(None)</Manifest_File>
@ -80,14 +82,13 @@
<MainSource>MainSource</MainSource> <MainSource>MainSource</MainSource>
</DelphiCompile> </DelphiCompile>
<DCCReference Include="..\..\XcpProtection.pas"/> <DCCReference Include="..\..\XcpProtection.pas"/>
<DCCReference Include="..\..\SRecReader.pas"/>
<DCCReference Include="..\..\XcpDataFile.pas"/>
<DCCReference Include="..\..\XcpLoader.pas"/> <DCCReference Include="..\..\XcpLoader.pas"/>
<DCCReference Include="XcpTransport.pas"/> <DCCReference Include="XcpTransport.pas"/>
<DCCReference Include="XcpSettings.pas"> <DCCReference Include="XcpSettings.pas">
<Form>XcpSettingsForm</Form> <Form>XcpSettingsForm</Form>
</DCCReference> </DCCReference>
<DCCReference Include="PCANBasic.pas"/> <DCCReference Include="PCANBasic.pas"/>
<DCCReference Include="..\..\..\..\Library\FirmwareData\pas\FirmwareData.pas"/>
<BuildConfiguration Include="Debug"> <BuildConfiguration Include="Debug">
<Key>Cfg_2</Key> <Key>Cfg_2</Key>
<CfgParent>Base</CfgParent> <CfgParent>Base</CfgParent>

View File

@ -46,13 +46,11 @@ uses
Classes, Classes,
Extctrls, Extctrls,
XcpProtection in '..\XcpProtection.pas', XcpProtection in '..\XcpProtection.pas',
SRecReader in '..\SRecReader.pas',
XcpDataFile in '..\XcpDataFile.pas',
XcpLoader in '..\XcpLoader.pas', XcpLoader in '..\XcpLoader.pas',
XcpTransport in 'XcpTransport.pas', XcpTransport in 'XcpTransport.pas',
XcpSettings in 'XcpSettings.pas' {XcpSettingsForm}, XcpSettings in 'XcpSettings.pas' {XcpSettingsForm},
WSockets in 'WSockets.pas'; WSockets in 'WSockets.pas',
FirmwareData in '..\..\..\Library\FirmwareData\pas\FirmwareData.pas';
//*************************************************************************************** //***************************************************************************************
// Global Constants // Global Constants
@ -92,7 +90,7 @@ var
timer : TTimer; timer : TTimer;
events : TEventHandlers; events : TEventHandlers;
loader : TXcpLoader; loader : TXcpLoader;
datafile : TXcpDataFile; datafile : TFirmwareData;
progdata : array of Byte; progdata : array of Byte;
progfile : string; progfile : string;
stopRequest : boolean; stopRequest : boolean;
@ -246,13 +244,15 @@ procedure TEventHandlers.OnTimeout(Sender: TObject);
var var
errorInfo : string; errorInfo : string;
progress : longword; progress : longword;
regionCnt : longword; segmentCnt : longword;
byteCnt : longword;
currentWriteCnt : word; currentWriteCnt : word;
sessionStartResult : byte; sessionStartResult : byte;
bufferOffset : longword; bufferOffset : longword;
addr : longword; addr : longword;
len : longword; len : longword;
dataSizeKB : real; dataSizeKB : real;
dataSizeBytes : integer;
begin begin
timer.Enabled := False; timer.Enabled := False;
@ -377,14 +377,31 @@ begin
// still here so programming session was started // still here so programming session was started
MbiCallbackOnLog('Programming session started. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session started. t='+ShortString(TimeToStr(Time)));
// create the datafile object // read the firmware file
datafile := TXcpDataFile.Create(progfile); MbiCallbackOnInfo('Reading firmware file.');
MbiCallbackOnLog('Reading firmware file. t='+ShortString(TimeToStr(Time)));
// create the datafile object and load the file contents
datafile := TFirmwareData.Create;
if not datafile.LoadFromFile(progfile, False) then
begin
MbiCallbackOnLog('Could not read firmware file (' + ShortString(ExtractFilename(progfile)) +'). t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Could not read firmware file (' + ShortString(ExtractFilename(progfile)) +').');
datafile.Free;
Exit;
end;
// compute the size in kbytes // compute the size in kbytes
dataSizeKB := datafile.GetDataCnt / 1024; dataSizeBytes := 0;
// loop through all segment to get the total byte count
for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin
dataSizeBytes := dataSizeBytes + datafile.Segment[segmentCnt].Size;
end;
// convert bytes to kilobytes
dataSizeKB := dataSizeBytes / 1024;
// Call application callback when we start the actual download // Call application callback when we start the actual download
MbiCallbackOnStarted(datafile.GetDataCnt); MbiCallbackOnStarted(dataSizeBytes);
// Init progress to 0 progress // Init progress to 0 progress
progress := 0; progress := 0;
@ -394,7 +411,7 @@ begin
// update the user info // update the user info
MbiCallbackOnInfo('Erasing memory...'); MbiCallbackOnInfo('Erasing memory...');
for regionCnt := 0 to datafile.GetRegionCnt-1 do for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin begin
// check if the user cancelled // check if the user cancelled
if stopRequest then if stopRequest then
@ -404,11 +421,13 @@ begin
loader.Disconnect; loader.Disconnect;
MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Programming session cancelled by user.'); MbiCallbackOnError('Programming session cancelled by user.');
datafile.Free;
Exit; Exit;
end; end;
// obtain the region info // obtain the region info
datafile.GetRegionInfo(regionCnt, addr, len); addr := datafile.Segment[segmentCnt].BaseAddress;
len := datafile.Segment[segmentCnt].Size;
// erase the memory // erase the memory
MbiCallbackOnLog('Clearing Memory '+ShortString(Format('addr:0x%x,len:0x%x',[addr,len]))+'. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Clearing Memory '+ShortString(Format('addr:0x%x,len:0x%x',[addr,len]))+'. t='+ShortString(TimeToStr(Time)));
@ -424,17 +443,19 @@ begin
end; end;
//---------------- next program the memory regions ------------------------------------ //---------------- next program the memory regions ------------------------------------
for regionCnt := 0 to datafile.GetRegionCnt-1 do for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin begin
// update the user info // update the user info
MbiCallbackOnInfo('Reading file...'); MbiCallbackOnInfo('Reading file...');
// obtain the region info // obtain the region info
datafile.GetRegionInfo(regionCnt, addr, len); addr := datafile.Segment[segmentCnt].BaseAddress;
// dynamically allocated buffer memory len := datafile.Segment[segmentCnt].Size;
SetLength(progdata, len); SetLength(progdata, len);
// obtain the regiond data for byteCnt := 0 to (len - 1) do
datafile.GetRegionData(regionCnt, progdata); begin
progdata[byteCnt] := datafile.Segment[segmentCnt].Data[byteCnt];
end;
bufferOffset := 0; bufferOffset := 0;
while len > 0 do while len > 0 do
@ -447,6 +468,7 @@ begin
loader.Disconnect; loader.Disconnect;
MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Programming session cancelled by user.'); MbiCallbackOnError('Programming session cancelled by user.');
datafile.Free;
Exit; Exit;
end; end;
@ -496,7 +518,7 @@ begin
MbiCallbackOnLog('Programming session stopped. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session stopped. t='+ShortString(TimeToStr(Time)));
// all done so set progress to 100% and finish up // all done so set progress to 100% and finish up
progress := datafile.GetDataCnt; progress := dataSizeBytes;
datafile.Free; datafile.Free;
MbiCallbackOnProgress(progress); MbiCallbackOnProgress(progress);
MbiCallbackOnLog('File successfully downloaded t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('File successfully downloaded t='+ShortString(TimeToStr(Time)));
@ -646,7 +668,7 @@ end; //*** end of MbiDescription ***
//*************************************************************************************** //***************************************************************************************
function MbiVersion : Longword; stdcall; function MbiVersion : Longword; stdcall;
begin begin
Result := 10000; // v1.00.00 Result := 10100; // v1.01.00
end; //*** end of MbiVersion *** end; //*** end of MbiVersion ***

View File

@ -70,6 +70,8 @@
<DCC_Optimize>false</DCC_Optimize> <DCC_Optimize>false</DCC_Optimize>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''"> <PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.1.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.1.0.0;Comments=</VerInfo_Keys>
<VerInfo_MinorVer>1</VerInfo_MinorVer>
<Manifest_File>(None)</Manifest_File> <Manifest_File>(None)</Manifest_File>
<VerInfo_Locale>1033</VerInfo_Locale> <VerInfo_Locale>1033</VerInfo_Locale>
<Debugger_HostApplication>C:\Work\software\OpenBLT\Host\MicroBoot.exe</Debugger_HostApplication> <Debugger_HostApplication>C:\Work\software\OpenBLT\Host\MicroBoot.exe</Debugger_HostApplication>
@ -80,14 +82,13 @@
<MainSource>MainSource</MainSource> <MainSource>MainSource</MainSource>
</DelphiCompile> </DelphiCompile>
<DCCReference Include="..\XcpProtection.pas"/> <DCCReference Include="..\XcpProtection.pas"/>
<DCCReference Include="..\SRecReader.pas"/>
<DCCReference Include="..\XcpDataFile.pas"/>
<DCCReference Include="..\XcpLoader.pas"/> <DCCReference Include="..\XcpLoader.pas"/>
<DCCReference Include="XcpTransport.pas"/> <DCCReference Include="XcpTransport.pas"/>
<DCCReference Include="XcpSettings.pas"> <DCCReference Include="XcpSettings.pas">
<Form>XcpSettingsForm</Form> <Form>XcpSettingsForm</Form>
</DCCReference> </DCCReference>
<DCCReference Include="WSockets.pas"/> <DCCReference Include="WSockets.pas"/>
<DCCReference Include="..\..\..\Library\FirmwareData\pas\FirmwareData.pas"/>
<BuildConfiguration Include="Debug"> <BuildConfiguration Include="Debug">
<Key>Cfg_2</Key> <Key>Cfg_2</Key>
<CfgParent>Base</CfgParent> <CfgParent>Base</CfgParent>

View File

@ -46,12 +46,11 @@ uses
Classes, Classes,
Extctrls, Extctrls,
XcpProtection in '..\XcpProtection.pas', XcpProtection in '..\XcpProtection.pas',
SRecReader in '..\SRecReader.pas',
XcpDataFile in '..\XcpDataFile.pas',
XcpLoader in '..\XcpLoader.pas', XcpLoader in '..\XcpLoader.pas',
XcpTransport in 'XcpTransport.pas', XcpTransport in 'XcpTransport.pas',
XcpSettings in 'XcpSettings.pas' {XcpSettingsForm}, XcpSettings in 'XcpSettings.pas' {XcpSettingsForm},
CPort in 'CPort.pas'; CPort in 'CPort.pas',
FirmwareData in '..\..\..\Library\FirmwareData\pas\FirmwareData.pas';
//*************************************************************************************** //***************************************************************************************
// Global Constants // Global Constants
@ -91,7 +90,7 @@ var
timer : TTimer; timer : TTimer;
events : TEventHandlers; events : TEventHandlers;
loader : TXcpLoader; loader : TXcpLoader;
datafile : TXcpDataFile; datafile : TFirmwareData;
progdata : array of Byte; progdata : array of Byte;
progfile : string; progfile : string;
stopRequest : boolean; stopRequest : boolean;
@ -245,13 +244,15 @@ procedure TEventHandlers.OnTimeout(Sender: TObject);
var var
errorInfo : string; errorInfo : string;
progress : longword; progress : longword;
regionCnt : longword; segmentCnt : longword;
byteCnt : longword;
currentWriteCnt : word; currentWriteCnt : word;
sessionStartResult : byte; sessionStartResult : byte;
bufferOffset : longword; bufferOffset : longword;
addr : longword; addr : longword;
len : longword; len : longword;
dataSizeKB : real; dataSizeKB : real;
dataSizeBytes : integer;
begin begin
timer.Enabled := False; timer.Enabled := False;
@ -316,14 +317,31 @@ begin
// still here so programming session was started // still here so programming session was started
MbiCallbackOnLog('Programming session started. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session started. t='+ShortString(TimeToStr(Time)));
// create the datafile object // read the firmware file
datafile := TXcpDataFile.Create(progfile); MbiCallbackOnInfo('Reading firmware file.');
MbiCallbackOnLog('Reading firmware file. t='+ShortString(TimeToStr(Time)));
// create the datafile object and load the file contents
datafile := TFirmwareData.Create;
if not datafile.LoadFromFile(progfile, False) then
begin
MbiCallbackOnLog('Could not read firmware file (' + ShortString(ExtractFilename(progfile)) +'). t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Could not read firmware file (' + ShortString(ExtractFilename(progfile)) +').');
datafile.Free;
Exit;
end;
// compute the size in kbytes // compute the size in kbytes
dataSizeKB := datafile.GetDataCnt / 1024; dataSizeBytes := 0;
// loop through all segment to get the total byte count
for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin
dataSizeBytes := dataSizeBytes + datafile.Segment[segmentCnt].Size;
end;
// convert bytes to kilobytes
dataSizeKB := dataSizeBytes / 1024;
// Call application callback when we start the actual download // Call application callback when we start the actual download
MbiCallbackOnStarted(datafile.GetDataCnt); MbiCallbackOnStarted(dataSizeBytes);
// Init progress to 0 progress // Init progress to 0 progress
progress := 0; progress := 0;
@ -333,7 +351,7 @@ begin
// update the user info // update the user info
MbiCallbackOnInfo('Erasing memory...'); MbiCallbackOnInfo('Erasing memory...');
for regionCnt := 0 to datafile.GetRegionCnt-1 do for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin begin
// check if the user cancelled // check if the user cancelled
if stopRequest then if stopRequest then
@ -343,11 +361,13 @@ begin
loader.Disconnect; loader.Disconnect;
MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Programming session cancelled by user.'); MbiCallbackOnError('Programming session cancelled by user.');
datafile.Free;
Exit; Exit;
end; end;
// obtain the region info // obtain the region info
datafile.GetRegionInfo(regionCnt, addr, len); addr := datafile.Segment[segmentCnt].BaseAddress;
len := datafile.Segment[segmentCnt].Size;
// erase the memory // erase the memory
MbiCallbackOnLog('Clearing Memory '+ShortString(Format('addr:0x%x,len:0x%x',[addr,len]))+'. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Clearing Memory '+ShortString(Format('addr:0x%x,len:0x%x',[addr,len]))+'. t='+ShortString(TimeToStr(Time)));
@ -363,17 +383,19 @@ begin
end; end;
//---------------- next program the memory regions ------------------------------------ //---------------- next program the memory regions ------------------------------------
for regionCnt := 0 to datafile.GetRegionCnt-1 do for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin begin
// update the user info // update the user info
MbiCallbackOnInfo('Reading file...'); MbiCallbackOnInfo('Reading file...');
// obtain the region info // obtain the region info
datafile.GetRegionInfo(regionCnt, addr, len); addr := datafile.Segment[segmentCnt].BaseAddress;
// dynamically allocated buffer memory len := datafile.Segment[segmentCnt].Size;
SetLength(progdata, len); SetLength(progdata, len);
// obtain the regiond data for byteCnt := 0 to (len - 1) do
datafile.GetRegionData(regionCnt, progdata); begin
progdata[byteCnt] := datafile.Segment[segmentCnt].Data[byteCnt];
end;
bufferOffset := 0; bufferOffset := 0;
while len > 0 do while len > 0 do
@ -386,6 +408,7 @@ begin
loader.Disconnect; loader.Disconnect;
MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Programming session cancelled by user.'); MbiCallbackOnError('Programming session cancelled by user.');
datafile.Free;
Exit; Exit;
end; end;
@ -435,7 +458,7 @@ begin
MbiCallbackOnLog('Programming session stopped. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session stopped. t='+ShortString(TimeToStr(Time)));
// all done so set progress to 100% and finish up // all done so set progress to 100% and finish up
progress := datafile.GetDataCnt; progress := dataSizeBytes;
datafile.Free; datafile.Free;
MbiCallbackOnProgress(progress); MbiCallbackOnProgress(progress);
MbiCallbackOnLog('File successfully downloaded t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('File successfully downloaded t='+ShortString(TimeToStr(Time)));
@ -584,7 +607,7 @@ end; //*** end of MbiDescription ***
//*************************************************************************************** //***************************************************************************************
function MbiVersion : Longword; stdcall; function MbiVersion : Longword; stdcall;
begin begin
Result := 10003; // v1.00.03 Result := 10100; // v1.01.00
end; //*** end of MbiVersion *** end; //*** end of MbiVersion ***

View File

@ -70,6 +70,8 @@
<DCC_Optimize>false</DCC_Optimize> <DCC_Optimize>false</DCC_Optimize>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''"> <PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<VerInfo_MinorVer>1</VerInfo_MinorVer>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.1.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.1.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale> <VerInfo_Locale>1033</VerInfo_Locale>
<Debugger_HostApplication>C:\Work\software\OpenBLT\Host\MicroBoot.exe</Debugger_HostApplication> <Debugger_HostApplication>C:\Work\software\OpenBLT\Host\MicroBoot.exe</Debugger_HostApplication>
<Manifest_File>(None)</Manifest_File> <Manifest_File>(None)</Manifest_File>
@ -80,14 +82,13 @@
<MainSource>MainSource</MainSource> <MainSource>MainSource</MainSource>
</DelphiCompile> </DelphiCompile>
<DCCReference Include="..\XcpProtection.pas"/> <DCCReference Include="..\XcpProtection.pas"/>
<DCCReference Include="..\SRecReader.pas"/>
<DCCReference Include="..\XcpDataFile.pas"/>
<DCCReference Include="..\XcpLoader.pas"/> <DCCReference Include="..\XcpLoader.pas"/>
<DCCReference Include="XcpTransport.pas"/> <DCCReference Include="XcpTransport.pas"/>
<DCCReference Include="XcpSettings.pas"> <DCCReference Include="XcpSettings.pas">
<Form>XcpSettingsForm</Form> <Form>XcpSettingsForm</Form>
</DCCReference> </DCCReference>
<DCCReference Include="CPort.pas"/> <DCCReference Include="CPort.pas"/>
<DCCReference Include="..\..\..\Library\FirmwareData\pas\FirmwareData.pas"/>
<BuildConfiguration Include="Debug"> <BuildConfiguration Include="Debug">
<Key>Cfg_2</Key> <Key>Cfg_2</Key>
<CfgParent>Base</CfgParent> <CfgParent>Base</CfgParent>

View File

@ -46,13 +46,11 @@ uses
Classes, Classes,
Extctrls, Extctrls,
XcpProtection in '..\XcpProtection.pas', XcpProtection in '..\XcpProtection.pas',
SRecReader in '..\SRecReader.pas',
XcpDataFile in '..\XcpDataFile.pas',
XcpLoader in '..\XcpLoader.pas', XcpLoader in '..\XcpLoader.pas',
XcpTransport in 'XcpTransport.pas', XcpTransport in 'XcpTransport.pas',
XcpSettings in 'XcpSettings.pas' {XcpSettingsForm}, XcpSettings in 'XcpSettings.pas' {XcpSettingsForm},
UsbBulkLib in 'UsbBulkLib.pas'; UsbBulkLib in 'UsbBulkLib.pas',
FirmwareData in '..\..\..\Library\FirmwareData\pas\FirmwareData.pas';
//*************************************************************************************** //***************************************************************************************
// Global Constants // Global Constants
@ -92,7 +90,7 @@ var
timer : TTimer; timer : TTimer;
events : TEventHandlers; events : TEventHandlers;
loader : TXcpLoader; loader : TXcpLoader;
datafile : TXcpDataFile; datafile : TFirmwareData;
progdata : array of Byte; progdata : array of Byte;
progfile : string; progfile : string;
stopRequest : boolean; stopRequest : boolean;
@ -246,13 +244,15 @@ procedure TEventHandlers.OnTimeout(Sender: TObject);
var var
errorInfo : string; errorInfo : string;
progress : longword; progress : longword;
regionCnt : longword; segmentCnt : longword;
byteCnt : longword;
currentWriteCnt : word; currentWriteCnt : word;
sessionStartResult : byte; sessionStartResult : byte;
bufferOffset : longword; bufferOffset : longword;
addr : longword; addr : longword;
len : longword; len : longword;
dataSizeKB : real; dataSizeKB : real;
dataSizeBytes : integer;
begin begin
timer.Enabled := False; timer.Enabled := False;
@ -321,14 +321,31 @@ begin
// still here so programming session was started // still here so programming session was started
MbiCallbackOnLog('Programming session started. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session started. t='+ShortString(TimeToStr(Time)));
// create the datafile object // read the firmware file
datafile := TXcpDataFile.Create(progfile); MbiCallbackOnInfo('Reading firmware file.');
MbiCallbackOnLog('Reading firmware file. t='+ShortString(TimeToStr(Time)));
// create the datafile object and load the file contents
datafile := TFirmwareData.Create;
if not datafile.LoadFromFile(progfile, False) then
begin
MbiCallbackOnLog('Could not read firmware file (' + ShortString(ExtractFilename(progfile)) +'). t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Could not read firmware file (' + ShortString(ExtractFilename(progfile)) +').');
datafile.Free;
Exit;
end;
// compute the size in kbytes // compute the size in kbytes
dataSizeKB := datafile.GetDataCnt / 1024; dataSizeBytes := 0;
// loop through all segment to get the total byte count
for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin
dataSizeBytes := dataSizeBytes + datafile.Segment[segmentCnt].Size;
end;
// convert bytes to kilobytes
dataSizeKB := dataSizeBytes / 1024;
// Call application callback when we start the actual download // Call application callback when we start the actual download
MbiCallbackOnStarted(datafile.GetDataCnt); MbiCallbackOnStarted(dataSizeBytes);
// Init progress to 0 progress // Init progress to 0 progress
progress := 0; progress := 0;
@ -338,7 +355,7 @@ begin
// update the user info // update the user info
MbiCallbackOnInfo('Erasing memory...'); MbiCallbackOnInfo('Erasing memory...');
for regionCnt := 0 to datafile.GetRegionCnt-1 do for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin begin
// check if the user cancelled // check if the user cancelled
if stopRequest then if stopRequest then
@ -348,11 +365,13 @@ begin
loader.Disconnect; loader.Disconnect;
MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Programming session cancelled by user.'); MbiCallbackOnError('Programming session cancelled by user.');
datafile.Free;
Exit; Exit;
end; end;
// obtain the region info // obtain the region info
datafile.GetRegionInfo(regionCnt, addr, len); addr := datafile.Segment[segmentCnt].BaseAddress;
len := datafile.Segment[segmentCnt].Size;
// erase the memory // erase the memory
MbiCallbackOnLog('Clearing Memory '+ShortString(Format('addr:0x%x,len:0x%x',[addr,len]))+'. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Clearing Memory '+ShortString(Format('addr:0x%x,len:0x%x',[addr,len]))+'. t='+ShortString(TimeToStr(Time)));
@ -368,17 +387,19 @@ begin
end; end;
//---------------- next program the memory regions ------------------------------------ //---------------- next program the memory regions ------------------------------------
for regionCnt := 0 to datafile.GetRegionCnt-1 do for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin begin
// update the user info // update the user info
MbiCallbackOnInfo('Reading file...'); MbiCallbackOnInfo('Reading file...');
// obtain the region info // obtain the region info
datafile.GetRegionInfo(regionCnt, addr, len); addr := datafile.Segment[segmentCnt].BaseAddress;
// dynamically allocated buffer memory len := datafile.Segment[segmentCnt].Size;
SetLength(progdata, len); SetLength(progdata, len);
// obtain the regiond data for byteCnt := 0 to (len - 1) do
datafile.GetRegionData(regionCnt, progdata); begin
progdata[byteCnt] := datafile.Segment[segmentCnt].Data[byteCnt];
end;
bufferOffset := 0; bufferOffset := 0;
while len > 0 do while len > 0 do
@ -391,6 +412,7 @@ begin
loader.Disconnect; loader.Disconnect;
MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Programming session cancelled by user.'); MbiCallbackOnError('Programming session cancelled by user.');
datafile.Free;
Exit; Exit;
end; end;
@ -440,7 +462,7 @@ begin
MbiCallbackOnLog('Programming session stopped. t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('Programming session stopped. t='+ShortString(TimeToStr(Time)));
// all done so set progress to 100% and finish up // all done so set progress to 100% and finish up
progress := datafile.GetDataCnt; progress := dataSizeBytes;
datafile.Free; datafile.Free;
MbiCallbackOnProgress(progress); MbiCallbackOnProgress(progress);
MbiCallbackOnLog('File successfully downloaded t='+ShortString(TimeToStr(Time))); MbiCallbackOnLog('File successfully downloaded t='+ShortString(TimeToStr(Time)));
@ -589,7 +611,7 @@ end; //*** end of MbiDescription ***
//*************************************************************************************** //***************************************************************************************
function MbiVersion : Longword; stdcall; function MbiVersion : Longword; stdcall;
begin begin
Result := 10000; // v1.00.00 Result := 10100; // v1.01.00
end; //*** end of MbiVersion *** end; //*** end of MbiVersion ***

View File

@ -70,6 +70,8 @@
<DCC_Optimize>false</DCC_Optimize> <DCC_Optimize>false</DCC_Optimize>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''"> <PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<VerInfo_MinorVer>1</VerInfo_MinorVer>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.1.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.1.0.0;Comments=</VerInfo_Keys>
<Debugger_HostApplication>C:\Work\software\OpenBLT\Host\MicroBoot.exe</Debugger_HostApplication> <Debugger_HostApplication>C:\Work\software\OpenBLT\Host\MicroBoot.exe</Debugger_HostApplication>
<VerInfo_Locale>1033</VerInfo_Locale> <VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>(None)</Manifest_File> <Manifest_File>(None)</Manifest_File>
@ -80,14 +82,13 @@
<MainSource>MainSource</MainSource> <MainSource>MainSource</MainSource>
</DelphiCompile> </DelphiCompile>
<DCCReference Include="..\XcpProtection.pas"/> <DCCReference Include="..\XcpProtection.pas"/>
<DCCReference Include="..\SRecReader.pas"/>
<DCCReference Include="..\XcpDataFile.pas"/>
<DCCReference Include="..\XcpLoader.pas"/> <DCCReference Include="..\XcpLoader.pas"/>
<DCCReference Include="XcpTransport.pas"/> <DCCReference Include="XcpTransport.pas"/>
<DCCReference Include="XcpSettings.pas"> <DCCReference Include="XcpSettings.pas">
<Form>XcpSettingsForm</Form> <Form>XcpSettingsForm</Form>
</DCCReference> </DCCReference>
<DCCReference Include="UsbBulkLib.pas"/> <DCCReference Include="UsbBulkLib.pas"/>
<DCCReference Include="..\..\..\Library\FirmwareData\pas\FirmwareData.pas"/>
<BuildConfiguration Include="Debug"> <BuildConfiguration Include="Debug">
<Key>Cfg_2</Key> <Key>Cfg_2</Key>
<CfgParent>Base</CfgParent> <CfgParent>Base</CfgParent>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.