STM-Link mit CubeProgrammer_API.dll unter Delphi ansprechen

OP #7411008
Lesenswert?

Hallo,

ich möchte aus einer Delphiapplikation den STM32-Link ansprechen und versuche auf die CubeProgrammer_API.dll zuzugreifen:

1
const
2

3
DLL_NAME = 'C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\api\lib\CubeProgrammer_API.dll';
4

5
function LoadCubeProgrammerApi: Cardinal;
6
begin
7
  hDll := LoadLibrary(DLL_NAME);
8
  Result := GetLastError();
9
end;

Als last error kommt immer 193 zurück. Google sagt dass das passiert wenn man eine 32-Bit DLL aus einer 64-Bit Anwendung aufruft und umgekehrt. Der Fehler kommt aber bei beiden Targets (64 und 32 Bit). Weiß jemand wie das klappen könnte?

Gruß Stefan

#7411422
Lesenswert?

Stefan S. schrieb:

Als last error kommt immer 193 zurück. Google sagt dass das passiert wenn man eine 32-Bit DLL aus einer 64-Bit Anwendung aufruft und umgekehrt.

Ja, das ist ERROR_BAD_EXE_FORMAT und in diesen beiden Fällen kommt das tatsächlich. Aber auch noch in vielen anderen...

Der Fehler kommt aber bei beiden Targets (64 und 32 Bit).

Damit habe ich keine Erfahrung, obwohl ich weit über ein Jahrzeht mit Delphi programmiert habe. Damals(TM) konnte Delphi aber noch keine 64Bit-Anwendungen erstellen.

Weiß jemand wie das klappen könnte?

Kompiliere deine (Test-)Anwendung für 64Bit, lege sie in das Verzeichnis, in der auch die DLL liegt und starte sie dort. Geht's dann?

Noch ein kleiner Hinweis: Die DLL hat ihrerseits wiederum etliche Abhängigkeiten, die im gleichen Verzeichnis liegen, in dem auch die DLL liegt.

OP #7411630
Lesenswert?

Kompiliere deine (Test-)Anwendung für 64Bit, lege sie in das Verzeichnis, in der auch die DLL liegt und starte sie dort. Geht's dann?

Treffer! Dann funktioniert LoadLibrary schonmal, jetzt muss ich nur noch schauen wie ich das hinbiege; die Exe beim Zielsystem ins STM Cube Verzeichnis zu kopieren ist eher unschön.

Gruß & Dank Stefan

#7411635
Lesenswert?

Stefan S. schrieb:

Dann funktioniert LoadLibrary schonmal, jetzt muss ich nur noch schauen wie ich das hinbiege; die Exe beim Zielsystem ins STM Cube Verzeichnis zu kopieren ist eher unschön.

Daß LoadLibrary nicht mit dem absoluten Pfad zurechtkommt, verwundert. Du könntest vor dem Aufruf von LoadLibrary ein SetDllDirectory in das betreffende Verzeichnis ausführen.

Siehe https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya und https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setdlldirectorya

OP #7414012
Lesenswert?

...so halb zumindest...

Aufruf von getStLinkList liefert wunderbar Ergebnise zurück, aber connectStLink scheppert eine Accessviolation:

Project CubeProgrammer.exe raised exception class EAccessViolation with message 'Access violation at address 0000000000000000. Execution of address 0000000000000000'.

1
{$MINENUMSIZE 4}
2
TDebugConnectParameters = record
3
    dbgPort: TDebugPort;                        // < Select the type of debug interface #debugPort.
4
    index: Integer;                             // < Select one of the debug ports connected.
5
    serialNumber: array[0..32] of AnsiChar;     // < ST-LINK serial number.
6
    firmwareVersion: array[0..19] of AnsiChar;  // < Firmware version.
7
    targetVoltage: array[0..4] of AnsiChar;     // < Operate voltage.
8
    accessPortNumber: Integer;                  // < Number of available access port.
9
    accessPort: Integer;                        // < Select access port controller.
10
    debugConnectMode: TDebugConnectMode;        // < Select the debug CONNECT mode #debugConnectMode. */
11
    debugResetMode: TDebugResetMode;            // < Select the debug RESET mode #debugResetMode. */
12
    isOldFirmware: Integer;                     // < Check Old ST-LINK firmware version. */
13
    freq: TFrequencies;                         // < Supported frequencies #frequencies. */
14
    frequency: Integer;                         // < Select specific frequency. */
15
    isBridge: Integer;                          // < Indicates if it's Bridge device or not. */
16
    shared: Integer;                            // < Select connection type, if it's shared, use ST-LINK Server. */
17
    board: array[0..99] of AnsiChar;            // < board Name
18
    DBG_Sleep: Integer;
19
    speed: Integer;                             // < Select speed flashing of Cortex M33 series. */}
20
  end;
21
  pDebugConnectParameters = ^TDebugConnectParameters;
22

23
function getStLinkList(var stLinkList: pDebugConnectParameters; shared: LongBool): Integer; cdecl; external DLL_NAME delayed;
24
function connectStLink(debugParameters: TDebugConnectParameters): Integer; cdecl; external DLL_NAME delayed;

Die Elemente in den Delphirecords habe ich mit alle von den Größen angesehen, das passt soweit. Die von ST mitgelieferten Beispiele in C++ lassen sich in Visual Studio bauen und ohne Fehler ausführen. Vielleicht ist ein Delphi-Guru hier der noch eine Idee hat?

OP #7414210
Lesenswert?

bist du da sicher? Kam mir auch komisch vor, sollte aber nach meinem Verständnis so richtig sein. Hier sind die Signaturen aus dem C-Header:

1
int getStLinkList(debugConnectParameters** stLinkList, int shared);
2
int connectStLink(debugConnectParameters debugParameters);

Hab's trotzdem mal als Pointer übergeben, kommt aber die gleiche Accessviolation.

Integergröße habe ich auch nochmal jeweils nachgesehen, jeweils 4 Bytes.

OP #7416693
Lesenswert?

Hab ich mal jeweils ausgeben lassen, in beiden Fällen werden 312 Bytes gemeldet. Habe auch mal Hexdumps gemacht, der Inhalt ist gleich, außer die letzten 4 Bytes (speed), da steht in Delphi 0x0D 0xF0 0xAD 0xBA und in c 0xFF 0xFF 0xFF 0xFF, das ist auffällig. Der Hexdump wird jeweils ausgegeben unittelbar bevor connectStLink aufgerufen wird.

OP #7418557
Lesenswert?

dann würde ich zum Test speed in der Delphi Version einfach mal hart auf -1 vor dem Aufruf setzen

Habe ich mal gemacht, Ergebnis bleibt leider das Gleiche.

Ich tippe eher auf falsche Aufrufkonvention Ich habe mal alle durchprobiert, aber ich habe gesehen dass es unter 64-Bit eh keine unterschiedlichen Aufrufkonventionen gibt und die Angabe für 64-Bit Targets ignoriert wird.

Gruß Stefan

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren