cucuruzel

AVRootloader.dll

1 post in this topic

Hello

I need a starting point to use AVRootloader.dll to access the bootloader of a microcontroller.

The DLL can not be registered as a COM ( regsvr32 ), and I don't know de CLSID and IID to use ObjCreate.

I was unable to use DllCall as the definiton of return values and parameters are beyond my programming skills in Autoit.

this is what I have so far, I am stuck at DllCall...

;const
; IApplication.Output() Code
  global const $ocInfo              = 0x10000000;
  global const $ocError             = 0x11000000;
  global const $ocOthers            = 0x12000000;
; RetCode Flags
  global const $msCrypt             = 0x01;
  global const $msCryptFlash        = 0x02;
  global const $msCryptEeprom       = 0x04;
  global const $msVersioning        = 0x08;
; Return Codes of AVR Bootloader Software
  global const $SUCCESS             = 0x30;
  global const $ERRORVERIFY         = 0xC0;
  global const $ERRORCOMMAND        = 0xC1;
  global const $ERRORCRC            = 0xC2;
  global const $ERRORBOUNDS         = 0xC3;
  global const $ERRORCRYPT          = 0xC4;
  global const $ERRORPROG           = 0xC5;
  global const $ERRORVERSION        = 0xC6;
  global const $ERRORUNKNOWN        = 0xCF;

  global const $RETMASK             = 0xF0;

; IDevice.Support Flags
  global const $sfCrypt             = 0x0001;  ; Cryptography supported
  global const $sfCryptFlash        = 0x0002;  ; FLASH Write must be encrypted, unencrypted FLASH write not supported
  global const $sfCryptEeprom       = 0x0004;  ; EEPROM Write must be encrypted, unencrypted EEPROM write not supported
  global const $sfVersioning        = 0x0008;  ; Versioning supported
  global const $sfReadEeprom        = 0x0100;  ; command EEPROM Read supported, examined at runtime
  global const $sfWriteEeprom       = 0x0200;  ; command EEPROM Write supported, examined at runtime
  global const $sfReadRam           = 0x0400;  ; command RAM Read supported, examined at runtime
  global const $sfVerifyFlash       = 0x0800;  ; command Verify FLASH supported, examined at runtime

   global Const $tagTTimeouts = "struct;" & _
   "int Baudrate;" & _
   "int Connect;" & _
   "int Base;" & _
   "int Erase;" & _
   "int Flash;" & _
   "int Eeprom;" & _
   "int Buffer;" & _
   "int AppCmd;" & _
   "int KeepAlive;" & _
   "int RTSPulse;" & _
   "int RTSInterval;" & _
   "int ConnectTrials;" & _
   "int MaxPacketSize;" & _
   "int Options;" & _
   "endstruct"

    global $tTTimeouts = DllStructCreate($tagTTimeouts) 
    
    Local $hCBProcessMessages = DllCallbackRegister("ProcessMessages", "bool","wstr")
    Local $hCBOutput = DllCallbackRegister("Output", "none","wstr;int")
    Local $hCBChanged = DllCallbackRegister("Changed", "none","")

    $sDll = @ScriptDir & "\AVRootloader.dll" 
    $hDll = DllOpen($sDll) 
    if $hdll = -1 then MsgBox(0, "", "DLL error" )
    $do = DllCall($hDLL, ?????, "OpenCOM", "?????,"COM1", ?????, ?????)
    ConsoleWrite(@CR&"!"&$do)

    DllCallbackFree($hCBProcessMessages)
    DllCallbackFree($hCBOutput)
    DllCallbackFree($hCBChanged)
    
func Output($msg, $code)
    ConsoleWrite(@CR &"callback Output("&$msg&","&$code&")")
EndFunc

func Changed()
    ConsoleWrite(@CR &"callback Changed("&""&")")

EndFunc

func ProcessMessages($flag)
    ConsoleWrite(@CR &"callback ProcessMessages("&$flag&")")
    Return
EndFunc

Delphi Interface Unit of AVRootloader.dll :

unit AVRootIntf;

interface
  
  uses Windows, Classes;
  
  const
  // IApplication.Output() Code
  ocInfo              = $10000000;
  ocError             = $11000000;
  ocOthers            = $12000000;
  // RetCode Flags
  msCrypt             = $01;
  msCryptFlash        = $02;
  msCryptEeprom       = $04;
  msVersioning        = $08;
  // Return Codes of AVR Bootloader Software
  SUCCESS             = $30;
  ERRORVERIFY         = $C0;
  ERRORCOMMAND        = $C1;
  ERRORCRC            = $C2;
  ERRORBOUNDS         = $C3;
  ERRORCRYPT          = $C4;
  ERRORPROG           = $C5;
  ERRORVERSION        = $C6;
  ERRORUNKNOWN        = $CF;
  
  RETMASK             = $F0;
  
  // IDevice.Support Flags
  sfCrypt             = $0001;  // Cryptography supported
  sfCryptFlash        = $0002;  // FLASH Write must be encrypted, unencrypted FLASH write not supported
  sfCryptEeprom       = $0004;  // EEPROM Write must be encrypted, unencrypted EEPROM write not supported
  sfVersioning        = $0008;  // Versioning supported
  sfReadEeprom        = $0100;  // command EEPROM Read supported, examined at runtime
  sfWriteEeprom       = $0200;  // command EEPROM Write supported, examined at runtime
  sfReadRam           = $0400;  // command RAM Read supported, examined at runtime
  sfVerifyFlash       = $0800;  // command Verify FLASH supported, examined at runtime
  
  type
  // RS232 encapsulation of windows COM port
  TCRCFlag  = (crcReset, crcSend);
  TCRCFlags = set of TCRCFlag;
  
  ICOM = interface
  procedure Flush; stdcall;
  procedure Purge; stdcall;
  
  procedure SetTimeout(Value: Cardinal; const ProcName: WideString = ''); stdcall;
  procedure SetParams(Baudrate: Cardinal; Parity: Byte = NOPARITY; Databits: Byte = 8; Stopbits: Byte = ONESTOPBIT; const ProcName: WideString = ''); stdcall;
  procedure SetEchoMode(Value: Bool); stdcall;
  function  EchoMode: Bool; stdcall;
  
  procedure SetDTR(Value: Bool); stdcall;
  procedure SetRTS(Value: Bool); stdcall;
  procedure WriteData(Buffer: Pointer; Size: Integer; Flags: TCRCFlags = []; const ProcName: WideString = ''); stdcall;
  procedure WriteByte(Value: Byte; Flags: TCRCFlags = []; const ProcName: WideString = ''); stdcall;
  procedure WriteChar(Value: Char; Flags: TCRCFlags = []; const ProcName: WideString = ''); stdcall;
  procedure WriteWord(Value: Word; Flags: TCRCFlags = []; const ProcName: WideString = ''); stdcall;
  procedure WriteLong(Value: Cardinal; Flags: TCRCFlags = []; const ProcName: WideString = ''); stdcall;
  procedure WriteCRC(const ProcName: WideString = ''); stdcall;
  procedure ResetCRC; stdcall;
  
  procedure ReadData(Buffer: Pointer; Size: Integer; Flags: TCRCFlags = []; const ProcName: WideString = ''); stdcall;
  function  ReadByte(Flags: TCRCFlags = []; const ProcName: WideString = ''): Byte; stdcall;
  function  ReadChar(Flags: TCRCFlags = []; const ProcName: WideString = ''): Char; stdcall;
  function  ReadWord(Flags: TCRCFlags = []; const ProcName: WideString = ''): Word; stdcall;
  function  ReadLong(Flags: TCRCFlags = []; const ProcName: WideString = ''): Cardinal; stdcall;
  function  ReadCRC(const ProcName: WideString = ''): Bool; stdcall;
  end;
  
  // Timeout Record for IApplication
  TTimeouts = packed record
  Baudrate: Integer;
  Connect: Integer;
  Base: Integer;
  Erase: Integer;
  Flash: Integer;
  Eeprom: Integer;
  Buffer: Integer;
  AppCmd: Integer;
  KeepAlive: Integer;
  RTSPulse: Integer;
  RTSInterval: Integer;
  ConnectTrials: Integer;
  MaxPacketSize: Integer;
  Options: Integer;
  end;
  
  // Application Callback Interface, must be provided to OpenAVRootloader()
  IApplication = interface
  ['{62DEB67D-8AB2-476E-9CB6-F582A508B1F7}']
  function ProcessMessages: Bool; stdcall;
  procedure Changed; stdcall;
  procedure Output(const Msg: WideString; Code: Integer); stdcall;
  
  function GetFLASHFileName: WideString; stdcall;
  function GetEEPROMFileName: WideString; stdcall;
  function GetACYFileName: WideString; stdcall;
  function GetPassword: WideString; stdcall;
  function GetBootSign: WideString; stdcall;
  function GetTimeouts: TTimeouts; stdcall;
  function GetAppCmd: WideString; stdcall;
  function GetAppCmdResponse: WideString; stdcall;
  function GetAppVersion(Masked: Bool = False): Integer; stdcall;
  function GetACYInfo: WideString; stdcall;
  
  function OpenCommunication(Index: Integer): ICOM; stdcall;
  end;
  
  // individual Commands to send to AVR Bootloader software, part of IAVRootloader
  ICommandSet = interface
  ['{E9C64A3F-306C-4694-B250-FC57D2CB2DEB}']
  function SetAddr(Address: Integer): Bool; stdcall;
  function SetBuffer(Buffer: Pointer; Size: Integer; Code: Byte = 0): Bool; stdcall;
  function Run(Code: Byte = 1): Bool; stdcall;
  function EraseFlash(Pages: Byte = 1): Bool; stdcall;
  function VerifyFlash(Pages: Byte = 1): Bool; stdcall;
  function WriteFlash(Pages: Byte = 1): Bool; stdcall;
  function WriteEeprom(Size: Integer; Pages: Byte = 1): Bool; stdcall;
  function ReadEeprom(Buffer: Pointer; Size: Integer; Address: Integer = 0): Bool; stdcall;
  function ReadRam(Buffer: Pointer; Size: Integer; Address: Integer = 0): Bool; stdcall;
  end;
  
  // connected Device Information, part of IAVRootloader
  IDevice = interface
  ['{9EC8A92B-F6BB-47F3-A9C9-DF8F4F481F49}']
  function Signature: Integer; stdcall;
  function Name: WideString; stdcall;
  function Info: WideString; stdcall;
  function FlashSize: Integer; stdcall;
  function AppFlashSize: Integer; stdcall;
  function AppVersion: Integer; stdcall;
  function AppVersionString: WideString; stdcall;
  function EepromSize: Integer; stdcall;
  function RamSize: Integer; stdcall;
  function RamStartAddress: Integer; stdcall;
  function PageSize: Integer; stdcall;
  function BufferSize: Integer; stdcall;
  function Version: Integer; stdcall;
  function UseBootSection: Bool; stdcall;
  function RetCode: Byte; stdcall;
  function Support: Integer; stdcall;
  function XMLFileName: WideString; stdcall;
  end;
  
  TMode = (moDisconnected, moConnecting, moConnected, moWorking, moTimer, moAbort);
  
  // Bootloader Interface
  IAVRootloader = interface
  ['{3A2E99C2-CE9E-407B-8943-A6D5EB1F6B7A}']
  function  Mode: TMode; stdcall;
  
  function  DoConnect(Working: Bool = False): Bool; stdcall;
  procedure DoDisconnect; stdcall;
  procedure DoAbort; stdcall;
  
  function  DoProgram(EraseFlash: Bool; VerifyFlash: Bool): Bool; stdcall;
  function  DoCompile(EraseFlash: Bool; VerifyFlash: Bool): Bool; stdcall;
  function  DoVerifyFlash: Bool; stdcall;
  function  DoEraseFlash: Bool; stdcall;
  function  DoEraseEeprom: Bool; stdcall;
  
  function  COM: ICOM; stdcall;
  function  Device: IDevice; stdcall;
  function  Command: ICommandSet; stdcall;
  end;
  
  
  function OpenCOM(const Port: WideString; const Application: IApplication): ICOM; stdcall; external 'AVRootloader.dll';
  function OpenAVRootloader(const Application: IApplication): IAVRootloader; stdcall; external 'AVRootloader.dll';
  
  implementation
  
end.

Example of DLL usage in Pascal(?):

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, AVRootIntf,
  StdCtrls;

type
  TForm1 = class(TForm, IApplication)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private
    { Private-Deklarationen }
    FLoader: IAVRootloader;
    FMode: TMode;
    FCompile: Boolean;
  protected
    { implements IApplication Interface}
    procedure ProcessMessages; stdcall;
    procedure Changed; stdcall;
    procedure Output(const Msg: WideString; Code: Integer); stdcall;

    function GetFLASHFileName: WideString; stdcall;
    function GetEEPROMFileName: WideString; stdcall;
    function GetACYFileName: WideString; stdcall;
    function GetPassword: WideString; stdcall;
    function GetBootSign: WideString; stdcall;
    function GetTimeouts: TTimeouts; stdcall;

    function OpenCommunication: ICOM; stdcall;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}
procedure TForm1.ProcessMessages;
begin
  Application.ProcessMessages;
end;

procedure TForm1.Changed;
const
  sYesNo: array[Boolean] of String = ('No', 'Yes');
  sWire: array[Boolean] of String = ('2-Wire', '1-Wire');
begin
  if FMode <> FLoader.Mode then
  begin
    if not (FMode in [moConnected, moWorking]) and (FLoader.Mode in [moConnected, moWorking]) then
      with FLoader.Device do
      begin
        Memo1.Clear;
        Memo1.Lines.Add(Format('Connection                     : %6s', [sWire[FLoader.COM.EchoMode]]));
        Memo1.Lines.Add(Format('Device name                    : %s', [Name]));
        Memo1.Lines.Add(Format('Device signature               : %0.6x', [Signature]));
        Memo1.Lines.Add(Format('SRAM size                      : %6d Byte', [RamSize]));
        Memo1.Lines.Add(Format('EEPROM size                    : %6d Byte', [EepromSize]));
        Memo1.Lines.Add(Format('FLASH size                     : %6d Byte', [FlashSize]));
        Memo1.Lines.Add(Format('FLASH size for application     : %6d Byte', [AppFlashSize]));
        Memo1.Lines.Add(Format('FLASH pagesize                 : %6d Byte', [PageSize]));
        Memo1.Lines.Add(Format('Bootloader size                : %6d Byte', [FlashSize - AppFlashSize]));
        Memo1.Lines.Add(Format('Buffersize for data            : %6d Byte', [RamSize - PageSize + 24]));
        Memo1.Lines.Add(Format('SRAM start address             : %6d', [RamStartAddress]));
        Memo1.Lines.Add(Format('Bootloader version             : %6d', [Version]));
        Memo1.Lines.Add(Format('Use bootsection                : %6s', [sYesNo[UseBootSection]]));
        Memo1.Lines.Add(Format('Cryptography supported         : %6s', [sYesNo[Support and sfCrypt <> 0]]));
        if Support and sfCrypt <> 0 then
        begin
          Memo1.Lines.Add(Format('FLASH data must be encrypted   : %6s', [sYesNo[Support and sfCryptFlash <> 0]]));
          Memo1.Lines.Add(Format('EEPROM data must be encrypted  : %6s', [sYesNo[Support and sfCryptEeprom <> 0]]));
        end;
        if Info <> '' then
          Memo1.Lines.Add(Format('Info                           : %s', [Info]));
      end;

    FMode := FLoader.Mode;

    Button1.Enabled := FMode in [moDisconnected, moConnected];
    Button2.Enabled := FMode in [moDisconnected, moConnected];
    Button3.Enabled := FMode in [moDisconnected, moConnected];
    Button4.Enabled := FMode <> moWorking;
    case FMode of
      moDisconnected: Button4.Caption := 'Connect';
      moConnected: Button4.Caption := 'Disconnect';
      moConnecting: Button4.Caption := 'Abort connecting...';
      moWorking: Button4.Caption := 'Working..';
    end;
  end;
end;

procedure TForm1.Output(const Msg: WideString; Code: Integer);
begin
  Memo1.Lines.Add(Msg);
end;

function TForm1.GetFLASHFileName: WideString;
// wenn wir eine HEX/EPP Datei für den Endkunden verschlüsseln gebe den Pfad zur HEX datei zurück
// ansonsten wollen wir den AVR mit einer verschlüsselten ACY Datei programmieren
begin
  if FCompile then Result := ExtractFilePath(ParamStr(0)) + 'test.hex'
    else Result := GetACYFilename;
end;

function TForm1.GetEEPROMFileName: WideString;
begin
  Result := '';//ExtractFilePath(ParamStr(0)) + 'test.epp';
end;

function TForm1.GetACYFileName: WideString;
begin
  Result := ExtractFilePath(ParamStr(0)) + 'test.acy';
end;

function TForm1.GetPassword: WideString;
// Zur Vereinfachung mal das nötige Passwort als Defaul Wert.
// Das muß natürlich bei der fertigen Version auf '' gesetzt werden !!
begin
  Result := InputBox('Password required', 'Password', '1470A1B30573D7DCE92F506A64CD6BBA');
end;

function TForm1.GetBootSign: WideString;
begin
  Result := 'BOOT';
end;

function TForm1.GetTimeouts: TTimeouts;
begin
  Result.Base := 50;
  Result.Erase := 20;
  Result.Flash := 25;
  Result.Eeprom := 20;
  Result.Buffer := 1;
  Result.RTSPulse := 0;
  Result.RTSInterval := 0;
end;

function TForm1.OpenCommunication: ICOM;
// hier könnte ein eigenes ICOM Interface erzeugt werden mit dem
// der Bootlaoder dann arbeitet. Dieses eigene Interface kann dann auf beliebige
// Hardware zugreifen, zb. USB Geräte etc.ppp.
begin
  Result := AVRootIntf.OpenCOM('\\.\COM2', Self);
// setze Baudrate
  Result.SetParams(115200);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  FCompile := True;
  try
    FLoader.DoCompile(True, True);
  finally
    FCompile := False;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  FLoader.DoProgram(True, True);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  FLoader.DoEraseFlash;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  case FLoader.Mode of
    moDisconnected: FLoader.DoConnect;
    moConnected: FLoader.DoDisconnect;
  else
    FLoader.DoAbort;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FLoader := AVRootIntf.OpenAVRootloader(Self);
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := FLoader.Mode = moDisconnected;
  if not CanClose then
    FLoader.DoDisconnect;
end;

end.

thank's in advance

AVRootloader.dll

Share this post


Link to post
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now