AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Übersetzung von C nach Delphi (IOCTL)

Ein Thema von Rads · begonnen am 22. Dez 2015 · letzter Beitrag vom 22. Dez 2015
Antwort Antwort
Rads

Registriert seit: 31. Aug 2015
5 Beiträge
 
Delphi XE8 Professional
 
#1

Übersetzung von C nach Delphi (IOCTL)

  Alt 22. Dez 2015, 09:17
Morgen zusammen,

Ich musste den folgenden C-Code nach Delphi portieren, um den GPIO-Baustein anzusprechen.

C-Headerdatei:

Code:

/* Device type
#define GPIO_IOCTL_TYPE 0x9000

#define IOCTL_GPIO_WRITE \
    CTL_CODE( GPIO_IOCTL_TYPE, 0x901, METHOD_OUT_DIRECT , FILE_ANY_ACCESS)

#define IOCTL_GPIO_DIRECTION \
    CTL_CODE( GPIO_IOCTL_TYPE, 0x902, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)

#define ...


Typedef Enum
{
    CONNECT_MODE_INVALID = 0,
    CONNECT_MODE_INPUT,
    CONNECT_MODE_OUTPUT,
    CONNECT_MODE_MAXIMUM = CONNECT_MODE_OUTPUT
} GPIO_CONNECT_IO_PINS_MODE;


typedef struct
{
    ULONG pin;
    union
    {
        ULONG data_B;
        GPIO_CONNECT_IO_PINS_MODE ConnectMode;
    } ABC;
} GPIO_PIN_PARAMS, *PGPIO_PIN_PARAMS;
Ich habe das so übersetzt:
Daraus ergibt sich dann in Delphi folgendes ?
Delphi-Quellcode:

const
  GPIO_IOCTL_TYPE = $9000;
  GPIO_Device ='\\.\DEVICE';//Name
  IOCTL_GPIO_WRITE = DWORD((GPIO_IOCTL_TYPE shl 16) or (2 shl 14) or ($901 shl 2) or 0);
  IOCTL_GPIO_DIRECTION = DWORD((GPIO_IOCTL_TYPE shl 16) or (2 shl 14) or ($902 shl 2) or 0);
  //...

(* ----------------------------------------------------------- *)
Type // Typedef Enum
  _GPIO_Connect_IO_PINS_MODE = (
    CONNECT_MODE_INVALID = 0,
    CONNECT_MODE_INPUT,
    CONNECT_MODE_OUTPUT,
    CONNECT_MODE_MAXIMUM = CONNECT_MODE_OUTPUT
  );
  GPIO_Connect_IO_PINS_MODE = _GPIO_Connect_IO_PINS_MODE;
(* ----------------------------------------------------------- *)
Type
  C_Enum =(Var_Cardinal, Var_GPIO);
(* ----------------------------------------------------------- *)
Type
  PABC = ^TABC;
  TABC = Record
    case _Pin : C_Enum of
      Var_Cardinal :(data_B: Cardinal);
      Var_GPIO :(Var_ConnectMode: _GPIO_Connect_IO_PINS_MODE);
    end;
(* ----------------------------------------------------------- *)
Type // TypeDef struct
  PPGIO_PARAMS = ^TPGIO_PARAMS;
  TPGIO_PARAMS = record
    Pin : Cardinal;
    ABC : TABC;
  end;
Da der Zugriff (auf die GPIO-Schnittstelle) nicht funktioniert, wollte ich erstmal fragen ob meine Übersetzung stimmt??

Ich möchte einen Pin (z.B: 1) als Ausgang konfigurieren und ihn dann setzen:

Die Procedure sieht dann so aus:
Delphi-Quellcode:
var
  frmMain : TfrmMain;
  DeviceHandle : THandle;
  Params : TPGIO_PARAMS;
  nReturn : DWORD;


procedure TfrmMain.Button1Click(Sender: TObject);
begin
  DeviceHandle := CreateFile(Pchar(GPIO_Device), GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR
                  FILE_SHARE_WRITE, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL OR
                  FILE_FLAG_NO_BUFFERING, 0);

  if DeviceHandle <> INVALID_HANDLE_VALUE then
  begin
    //Konfiguration (Direction): Output
    Params.Pin := 1; //Pin 1
    Params.ABC.Var_ConnectMode := Connect_Mode_OutPut; //Pin Direction is set to Output
    DeviceIoControl(DeviceHandle, IOCTL_GPIO_DIRECTION, @Params, SizeOf(Params), Nil, 0, nReturn, nil);
    //Zugriff :Write
    Params.ABC.Data_B := 0;//255 // Hier bin ich mir nicht sicher, was ich hier eingeben muss ???
    Params.Pin := 1;
    DeviceIoControl(DeviceHandle, IOCTL_GPIO_Write, @Params, SizeOf(Params), Nil, 0, nReturn, nil);
    CloseHandle(DriveHandle);
  end
  else
  begin
    MessageDlg('Error!', mtWarning, [mbOK], 0);
  end;
end;
Der Compiler bringt keine Fehlermeldung, aber es funktioniert nicht..

Danke schonmal im Voraus für die Hilfe

Geändert von Rads (22. Dez 2015 um 09:24 Uhr)
  Mit Zitat antworten Zitat
4dk2

Registriert seit: 4. Sep 2007
176 Beiträge
 
#2

AW: Übersetzung von C nach Delphi (IOCTL)

  Alt 22. Dez 2015, 10:35
haste schonmal statt
T.. = Record mit
T... = packed Record probiert?
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: Übersetzung von C nach Delphi (IOCTL)

  Alt 22. Dez 2015, 11:02
Zitat:
Params.ABC.Data_B := 0;//255 // Hier bin ich mir nicht sicher, was ich hier eingeben muss ???
Du weißt nicht was du eingeben musst, aber du bist dir sicher dass es nicht funktioniert?
Das ist eben das Feld für die Daten die du an den Pin senden willst. Was für Daten das sind hängt wohl von der Funktion des Pins (bzw. dem was dahinter liegt) ab.
Also bist du dir sicher, dass die 0 in Data_B überhaupt etwas (merkbares/sichtbares) tut?

Oder gibt DeviceIoControl schon einen Fehlercode zurück?
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
grenni999

Registriert seit: 17. Apr 2008
7 Beiträge
 
#4

AW: Übersetzung von C nach Delphi (IOCTL)

  Alt 22. Dez 2015, 12:01
Eigentlich müsste es so sein, das Data_B ein Port ist. Auf einen Port werden meist 8 IO´s zusammengefasst.
Der Wert den du auf den Port zuweist, stellt in Binärschreibweise dann den Zustand der Pins dar.
Also wenn du dezimal 4 zuweist, ist das binär 0000 0100
und damit TRUE oder 1 an Pin 3.

Um nur einzellne Pins eines Ports unabhängig vom Zustand der restlichen Pins zu schalten, nimmt man eine Bitmaske und verknüpft den aktuellen Wert des Ports mit der Bitmaske und schreibt den Wert dann auf den Port.

Bitmaske für Pin 3 -> 0000 0100
ang. aktueller Zustand Data_B -> 1000 0011
Die beiden mit logisch ODER verknüpft ergibt 1000 0111
Und dies dann wieder auf Data_B zuweisen.
Dann ist Pin 3 gesetzt worden.
  Mit Zitat antworten Zitat
Rads

Registriert seit: 31. Aug 2015
5 Beiträge
 
Delphi XE8 Professional
 
#5

AW: Übersetzung von C nach Delphi (IOCTL)

  Alt 22. Dez 2015, 12:17
Danke schonmal für die Antworten

Zitat:
haste schonmal statt
T.. = Record mit
T... = packed Record probiert?
Ja habe ich..

Zitat:
Also bist du dir sicher, dass die 0 in Data_B überhaupt etwas (merkbares/sichtbares) tut?
...
Nein. ich habe halt probiert. (0 war nur ein Beispiel. weil ich nicht weiß was ich da eingeben muss. Ist in der Dokumentation leider nicht beschrieben.

Zitat:
Oder gibt DeviceIoControl schon einen Fehlercode zurück?
Nein. Die Funktion wird immer erfolgreich ausgeführt. Es fehlt die (richtige) Zuweisung von Pin und Data_B

Zitat:
Eigentlich müsste es so sein, das Data_B ein Port ist. Auf einen Port werden meist 8 IO´s zusammengefasst.
Der Wert den du auf den Port zuweist, stellt in Binärschreibweise dann den Zustand der Pins dar.
Also wenn du dezimal 4 zuweist, ist das binär 0000 0100
und damit TRUE oder 1 an Pin 3.

Um nur einzellne Pins eines Ports unabhängig vom Zustand der restlichen Pins zu schalten, nimmt man eine Bitmaske und verknüpft den aktuellen Wert des Ports mit der Bitmaske und schreibt den Wert dann auf den Port.

Bitmaske für Pin 3 -> 0000 0100
ang. aktueller Zustand Data_B -> 1000 0011
Die beiden mit logisch ODER verknüpft ergibt 1000 0111
Und dies dann wieder auf Data_B zuweisen.
Dann ist Pin 3 gesetzt worden.
ich finde nirgends ein Beispiel
Danke. Ich probier's gleich
  Mit Zitat antworten Zitat
SMO

Registriert seit: 20. Jul 2005
178 Beiträge
 
Delphi XE6 Professional
 
#6

AW: Übersetzung von C nach Delphi (IOCTL)

  Alt 22. Dez 2015, 14:58
Delphi-Quellcode:
  TABC = Record
    case _Pin : C_Enum of
      Var_Cardinal :(data_B: Cardinal);
      Var_GPIO :(Var_ConnectMode: _GPIO_Connect_IO_PINS_MODE);
    end;
Ist dir klar, dass das Feld "Var_ConnectMode" hier das Feld "data_B" nicht komplett überdeckt?
Das könnte dein Problem verursachen oder auch nicht, aber du solltest dir dessen in jedem Fall bewusst sein.
Standardmäßig macht Delphi Aufzählungstypen (Enumerations) so klein wie möglich (8, 16, 32 Bits), in C dagegen sind sie automatisch 32 Bits, soweit ich weiß.
Benutze die Direktive {$MINENUMSIZE 4} vor der Deklaration des ersten Aufzählungstyps, damit er auch in Delphi denselben Speicherplatz belegt.

Sonst lässt nämlich eine Zuweisung wie Params.ABC.Var_ConnectMode := Connect_Mode_OutPut; ganze 3 Bytes von data_B unberührt, was durchaus Fehler verursachen kann.

Geändert von SMO (22. Dez 2015 um 15:06 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:43 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz