![]() |
Übersetzung von C nach Delphi (IOCTL)
Morgen zusammen,
Ich musste den folgenden C-Code nach Delphi portieren, um den GPIO-Baustein anzusprechen. C-Headerdatei:
Code:
Ich habe das so übersetzt:/* 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; Daraus ergibt sich dann in Delphi folgendes ?
Delphi-Quellcode:
Da der Zugriff (auf die GPIO-Schnittstelle) nicht funktioniert, wollte ich erstmal fragen ob meine Übersetzung stimmt??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; Ich möchte einen Pin (z.B: 1) als Ausgang konfigurieren und ihn dann setzen: Die Procedure sieht dann so aus:
Delphi-Quellcode:
Der Compiler bringt keine Fehlermeldung, aber es funktioniert nicht..
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; Danke schonmal im Voraus für die Hilfe |
AW: Übersetzung von C nach Delphi (IOCTL)
haste schonmal statt
Delphi-Quellcode:
mit
T.. = Record
Delphi-Quellcode:
probiert?
T... = packed Record
|
AW: Übersetzung von C nach Delphi (IOCTL)
Zitat:
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? |
AW: Übersetzung von C nach Delphi (IOCTL)
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. |
AW: Übersetzung von C nach Delphi (IOCTL)
Danke schonmal für die Antworten :-)
Zitat:
Zitat:
Zitat:
Zitat:
Danke. Ich probier's gleich |
AW: Übersetzung von C nach Delphi (IOCTL)
Delphi-Quellcode:
Ist dir klar, dass das Feld "Var_ConnectMode" hier das Feld "data_B" nicht komplett überdeckt?
TABC = Record
case _Pin : C_Enum of Var_Cardinal :(data_B: Cardinal); Var_GPIO :(Var_ConnectMode: _GPIO_Connect_IO_PINS_MODE); end; 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 ![]() Sonst lässt nämlich eine Zuweisung wie
Delphi-Quellcode:
ganze 3 Bytes von data_B unberührt, was durchaus Fehler verursachen kann.
Params.ABC.Var_ConnectMode := Connect_Mode_OutPut;
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz