Verwendung von GPIO Ports unter Windows 11
-
Hallo,
ich bin relativ neu in der C++ Welt (komme von Java).
Ich versuche nun seit 3 Tagen die GPIO's zu verwenden und scheitere kläglich. Vielleicht könnt ihr mir helfen.Der Hersteller des PC's hat mir ein Beispiel-Programm zur verfügung gestellt wo ich aber immer über die Meldung stolpere:
"Failed to initialize WinIo."Hir einmal der Quellcode:
// DEMO.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung. // // demo.cpp : Diese Datei enthält die Hauptfunktion. Hier wird die Programmausführung gestartet und beendet. // #include <iostream> #include <tchar.h> #include <Windows.h> typedef bool(_stdcall* INITIALIZEWINIO)(void); typedef void(_stdcall* SHUTDOWNWINIO)(void); typedef bool(_stdcall* GETPORTVAL)(WORD, PDWORD, BYTE); typedef bool(_stdcall* SETPORTVAL)(WORD, DWORD, BYTE); SHUTDOWNWINIO ShutdownWinIo; GETPORTVAL GetPortVal; SETPORTVAL SetPortVal; INITIALIZEWINIO InitializeWinIo; VOID SafeGetNativeSystemInfo(__out LPSYSTEM_INFO lpSystemInfo) { if (NULL == lpSystemInfo) return; typedef VOID(WINAPI* LPFN_GetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo); LPFN_GetNativeSystemInfo fnGetNativeSystemInfo = (LPFN_GetNativeSystemInfo)GetProcAddress(GetModuleHandle(_T("kernel32")), "GetNativeSystemInfo"); if (NULL != fnGetNativeSystemInfo) { fnGetNativeSystemInfo(lpSystemInfo); } else { GetSystemInfo(lpSystemInfo); } } int GetSystemBits() { SYSTEM_INFO si; SafeGetNativeSystemInfo(&si); if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) { return 64; } return 32; } #define GETPROC(n, d) \ n = (d) GetProcAddress(lib, #n); \ if (!n) { \ fprintf(stderr, "Failed to load " #n " function.\n"); \ return 1; \ } //==========================================================WatchDogTimer=========================================================// #define SIO_CONFIG_INDEX 0x2E #define SIO_CONFIG_DATA 0x2F void WatchDogTimer(WORD TimerValue) // 1 < TimerValue < 65535 , Unit = Second { // Enter Configuration Mode. SetPortVal(SIO_CONFIG_INDEX, 0x87, 1); SetPortVal(SIO_CONFIG_INDEX, 0x01, 1); SetPortVal(SIO_CONFIG_INDEX, 0x55, 1); SetPortVal(SIO_CONFIG_INDEX, 0x55, 1); //=====================LDN 07====================================// SetPortVal(SIO_CONFIG_INDEX, 0x07, 1); SetPortVal(SIO_CONFIG_DATA, 0x07, 1); //=====================WDT====================================// SetPortVal(SIO_CONFIG_INDEX, 0x72, 1); SetPortVal(SIO_CONFIG_DATA, 0x90, 1); //Enable WDT SetPortVal(SIO_CONFIG_INDEX, 0x74, 1); SetPortVal(SIO_CONFIG_DATA, (BYTE)((TimerValue & 0xFF00) >> 8), 1); //MSB SetPortVal(SIO_CONFIG_INDEX, 0x73, 1); SetPortVal(SIO_CONFIG_DATA, (BYTE)(TimerValue & 0x00FF), 1); //LSB } void DisableWdt() { // Enter Configuration Mode. SetPortVal(SIO_CONFIG_INDEX, 0x87, 1); SetPortVal(SIO_CONFIG_INDEX, 0x01, 1); SetPortVal(SIO_CONFIG_INDEX, 0x55, 1); SetPortVal(SIO_CONFIG_INDEX, 0x55, 1); //=====================LDN 07====================================// SetPortVal(SIO_CONFIG_INDEX, 0x07, 1); SetPortVal(SIO_CONFIG_DATA, 0x07, 1); //=====================WDT====================================// SetPortVal(SIO_CONFIG_INDEX, 0x72, 1); SetPortVal(SIO_CONFIG_DATA, 0x00, 1); //Disable WDT SetPortVal(SIO_CONFIG_INDEX, 0x74, 1); SetPortVal(SIO_CONFIG_DATA, 0x00, 1); //MSB SetPortVal(SIO_CONFIG_INDEX, 0x73, 1); SetPortVal(SIO_CONFIG_DATA, 0x00, 1); //LSB } //================================================================================================================================// //GPIO0 Input------------------0xA06.bit0 int IsGpio0Set() { DWORD PortValue; GetPortVal(0xA06, &PortValue, 1); if (PortValue & 0x01) return 1; else return 0; } //GPIO1 Input------------------0xA06.bit1 int IsGpio1Set() { DWORD PortValue; GetPortVal(0xA06, &PortValue, 1); if (PortValue & 0x02) return 1; else return 0; } //GPIO1 Output------------------0xA06.bit1 void Gpio1Set(int outputvalue) { DWORD PortValue; GetPortVal(0xA06, &PortValue, 1); if (outputvalue == 0) SetPortVal(0xA06, (PortValue & 0xFD | 0x00), 1); else SetPortVal(0xA06, (PortValue & 0xFD | 0x02), 1); } int main() { HMODULE lib = NULL; DWORD PortValue; std::cout << "Hier läuft ein: " << GetSystemBits() << "-Bit System" << std::endl; // 32-Bit System if (GetSystemBits() == 32) { lib = LoadLibrary(TEXT("WinIo32.dll")); } // 64-Bit System else if (GetSystemBits() == 64) { //lib = LoadLibrary(_T("C:\\\\Users\\\\LokalAdmin\\\\Downloads\\\\H6 GPIO\\\\Windows\\\\WinIo64.dll")); lib = LoadLibraryA("C:\\\\Users\\\\LokalAdmin\\\\Downloads\\\\H6 GPIO\\\\Windows\\\\WinIo64.dll"); } GETPROC(InitializeWinIo, INITIALIZEWINIO); GETPROC(ShutdownWinIo, SHUTDOWNWINIO); GETPROC(GetPortVal, GETPORTVAL); GETPROC(SetPortVal, SETPORTVAL); if (!InitializeWinIo()) { std::cout << "Failed to initialize WinIo.\n"; return 0; } else { std::cout << "Initialize WinIo OK.\n"; //WatchDogTimer(50); // Füttern Sie den Hund 50 Sekunden lang if (IsGpio1Set()) { //GPIO1 Eingang = TRUE } else { //GPIO1 EINGANG = FALSE } Gpio1Set(1);// GPIO1 Ausgabe TRUE Gpio1Set(0);// GPIO1 AUSGABE FALSE } // Wenn das Programm beendet wird, führen Sie diese Funktion aus ShutdownWinIo(); }
Ich habe die restlichen GPIO'S mal rausgelöscht da es immer das selbe ist und so der Code um einiges kürzer wird.
-
@Knausbär sagte in Verwendung von GPIO Ports unter Windows 11:
Failed to initialize WinIo.
Hast du die Anwendung auch als Administrator gestartet?
-
Hallo,
ja ich habe VisualStudio als Administrator gestartet und ebenfalls unter Windows folgenden Befehl ausgeführt (und neu gestartet): bcdedit.exe /set testsigning on
Alles ohne Erfolg...
-
Wenn du die genaue interne Funktion herausfinden möchtest, warum
InitializeWinIo()
fehlschlägt, könntest du dir die Sourcen unter WinIO dazu ziehen und selber ein Testprogramm aufsetzen, das direkt diese Sourcen einbindet undInitializeWinIo()
aufruft (und dann mittels Breakpoint in der Funktion step-by-step den Code durchdebuggen).Laut Source von InitializeWinIo() gibt es mehrere Codestellen, an denen
false
zurückgegeben wird.
-
Wie gesagt ich bin relativ frisch in C++.
Mit den Brakpoints bekomme ich hin aber ich kann nichts mit WinIO und InitializeWinIo() anfangen.Wäre über jede Hilfe dankbar
-
Du verstehst schon, daß die Fehlermeldung durch den Aufruf von
InitializeWinIo()
in deinem gezeigten Code in den Zeilen 160 - 162 kommt, oder?Und diese Funktion (wenn du auf diesen Link InitializeWinIo() klickst, um die Sourcen davon zu sehen) ruft intern 4 weitere Funktionen auf, die eben fehlschlagen können und alle geben dann
false
zurück (leider weiß man daher nur bei Auswertung des Rückgabewertes eben nicht, was genau die korrekte Initialisierung verhindert).Ziehe dir daher den Source Code unter WinIo 3.0. Die Samples sind leider für C#/.NET und helfen dabei nicht weiter.
Erstelle daher im Visual Studio eine neue Solution (auf deutsch: Projektmappe) und füge dann das Projekt WinIo.vcproj hinzu (also das bei dir dann lokal abgelegte Projekt aus dem WinIO Source Code).
Nun fügst du ein weiteres C++ Konsolenprojekt zu dieser Projektmappe hinzu mit folgendem Code:#include "../WinIO/Source/Dll/winio.h" // <- hier mußt du evtl. den Pfad auf die Headerdatei noch anpassen! int main() { if (!InitializeWinIo()) { std::cout << "Failed to initialize WinIo.\n"; return -1; } else { std::cout << "Initialize WinIo OK.\n"; } return 0; }
Als letztes muß noch die lokale WinIO-Lib in den Linkeroptionen angegeben werden (evtl. recherchieren bzw. nachfragen).
Dann die gesamte Projektmappe bauen (kompilieren). Achte darauf, daß als Konfiguration "Debug" in der oberen ComboBox ausgewählt ist!
Nun setzt du 2 Breakpunkte in dem Konsolenprojekt beim Aufruf vonInitializeWinIo()
als auch im WinIO-Projekt in der Datei "Source/Dll/WinIo.cpp" in der FunktionInitializeWinIo()
selbst.
Wenn du dann das Programm im VS startest, dann sollte es beim ersten Breakpoint halten und du kannst dann mit der Taste F11 in die Funktion springen und dann mit F10 jeweils die einzelnen Codezeilen durchgehen, solange bis einer der internen Funktionen fehlschlägt und eines derreturn false
-Zeilen ausgeführt wird. Nun weißt du welche der 4 Funktionen dadrin fehlgeschlägt.PS: Was dein gezeigter Code etwas komplizierter macht, ist, daß je nach Rechnerarchitektur entweder die WinIO-DLL für 32 oder 64bit dynamisch geladen wird.
Was wird denn für dich bei dem Testprogramm ausgegeben:"Hier läuft ein: " ??? "-Bit System"
.
Ich nehme mal an, du hast ein 64bit Windows und es wird64
ausgegeben!?