Es kann jeder hier mitdiskutieren, wenn auch die Betatester natuerlich im Vorteil sind, da sie die Sourcen haben.
Bei guten Vorschlaegen aendern oder ergaenzen wird das 2.0 API gerne.
Gerade ist die Entscheidung gefallen das das alte API in einer Version 1.5 und das neue API 2.0 in einer DLL leben werden.
Ein Programm kann nur das eine oder das andere API verwenden. Gleichzeitig geht nicht.
Die Aenderungen von 1.4 zu 1.5 sind nur geringfuegig und beziehen sich auf einige Feinheiten des 2.0 APIs. Z. B. werden intern nun 128 Reports gepuffert statt der 8 des 1.4 APIs.
Das 1.5 API wird binaerkompatibel zum 1.4 API sein, d. h. die bisherigen Programme werden nach Tausch der DLL weiterhin funktionieren.
Es werden gerne weitere Betatester aufgenommen, besonders um das 1.5 API auf Kompatibilitaet zu testen.
Nun aber zum 2.0 API. Hier ein Ausschnitt der entscheidenden Teile des APIs.
Code: Select all
// This is a max report which can hold any IO-Warrior report
typedef struct _IOWKIT2_REPORT
{
UCHAR ReportID;
UCHAR Bytes[IOWKIT2_REPORT_PAYLOAD_SIZE];
}
IOWKIT2_REPORT, *PIOWKIT2_REPORT;
typedef BOOL (IOWKIT2_API *IOWKIT2_DATA_EVENT)(IOWKIT2_HANDLE devHandle, ULONG numPipe, PIOWKIT2_REPORT report,
ULONG size, ULONG Context);
typedef void (IOWKIT2_API *IOWKIT2_DEVICECHANGE_EVENT)(ULONG action, IOWKIT2_HANDLE devHandle, ULONG Context);
DWORD IOWKIT2_API IowKit2Initialize(IOWKIT2_DEVICECHANGE_EVENT Event, ULONG Context);
void IOWKIT2_API IowKit2Finalize(void);
ULONG IOWKIT2_API IowKit2Write(IOWKIT2_HANDLE devHandle, ULONG numPipe, PIOWKIT2_REPORT report);
int IOWKIT2_API IowKit2Read(IOWKIT2_HANDLE devHandle, ULONG numPipe, PIOWKIT2_REPORT report);
int IOWKIT2_API IowKit2ReadImmediate(IOWKIT2_HANDLE devHandle, ULONG numPipe, PIOWKIT2_REPORT report);
ULONG IOWKIT2_API IowKit2GetNumDevs(void);
ULONG IOWKIT2_API IowKit2GetProductId(IOWKIT2_HANDLE iowHandle);
ULONG IOWKIT2_API IowKit2GetRevision(IOWKIT2_HANDLE iowHandle);
HANDLE IOWKIT2_API IowKit2GetThreadHandle(IOWKIT2_HANDLE iowHandle, ULONG numPipe);
ULONG IOWKIT2_API IowKit2GetSerialNumber(IOWKIT2_HANDLE iowHandle);
BOOL IOWKIT2_API IowKit2SetTimeout(IOWKIT2_HANDLE devHandle, ULONG timeout);
BOOL IOWKIT2_API IowKit2SetWriteTimeout(IOWKIT2_HANDLE devHandle, ULONG timeout);
PCHAR IOWKIT2_API IowKit2Version(void);
BOOL IOWKIT2_API IowKit2Register(IOWKIT2_HANDLE devHandle, ULONG numPipe, IOWKIT2_DATA_EVENT Event, ULONG Context);
BOOL IOWKIT2_API IowKit2GetDeviceUse(IOWKIT2_HANDLE devHandle);
BOOL IOWKIT2_API IowKit2SetDeviceUse(IOWKIT2_HANDLE devHandle, BOOL Use);
void IOWKIT2_API IowKit2Enumerate(void);
int IOWKIT2_API IowKit2PendingReports(IOWKIT2_HANDLE devHandle, ULONG numPipe);
Das erste neue Konzept sind Callbacks. Diese sind noetig, da die IO-Warrior nun dynamisch verwaltet werden, sprich die DLL bekommt mit ob ein IO-Warrior an- oder abgesteckt wird.
Die neue Initialisierungsfunktion IowKit2Initialize() hat deshalb den Funktions-Parameter Event. Jedes Mal wenn ein IO-Warrior an- oder abgesteckt wird, wird diese Event-Funktion aufgerufen. Fuer alle IO-Warrior, die beim Aufruf von IowKit2Initialize() bereits angesteckt sind, wird einfach ein Anstecken simuliert.
Das naechste neue Konzept ist das man einen IO-Warrior in Benutzung nehmen muss bevor man ihn zugreifen kann.
IowKit2SetDeviceUse() ist dafuer zustaendig. Der Grund dafuer ist das An- und Abstecken. Die interne Datenstruktur die einen IO-Warrior repraesentiert (IOWKIT2_HANDLE) darf ja nicht einfach geloescht werden, wenn der zugehoerige IO-Warrior abgesteckt wird. Es kann ja sein das der IO-Warrior vom Programm benutzt wird.
Bei unbenutzten IO-Warriors wird die Datenstruktur geloescht, waehrend sie bei benutzten IO-Warriors als Zombie-Struktur erhalten wird bis sie mit IowKit2SetDeviceUse() als unbenutzt gekennzeichnet wird.
Das bietet auch den Vorteil das bis zu 128 bereits gelesene und gecachte Reports auch nach dem Abstecken noch gelesen werden koennen.
IowKit2PendingReports() ist zum API dazugekommen um die Anzahl gerade gecachter Reports abzufragen. Es laesst sich nun mit IowKitReadImmediate() dieser Cache leerlesen, da man ja nun weiss wieviele Reports aus dem Cache erhaeltlich sind.
Der zweite Callback erlaubt es die Reports statt ueber IowKit2Read() oder IowKit2ReadImmediate() ueber einen Callback zu erhalten.
IowKit2Register() ist dafuer zustaendig. Es laufen nun auf allen Pipes interne Lesethreads, die die Report-Caches fuettern.
Bevor ein Report in den Cache eingefuegt wird, wird er per Callback gemeldet. Der Callback kann nun den Report begutachten und per Rueckgabewert bestimmen ob der Report in den Cache soll oder nicht.
Mit dieser Herangehensweise kann man nun verschiedene Strategien der Reportverarbeitung implementieren.
Man kann alle Reports im Callback verarbeiten und IowKit2Read() und IowKit2ReadImmediate() komplett unbenutzt lassen.
Man kann nur einige Reports im Callback ausfiltern und den Rest mit IowKit2Read() oder IowKit2ReadImmediate() wie bisher lesen.
Man kann wie bisher IowKit2Read() und IowKit2ReadImmediate() nutzen und keinen Callback verwenden.
Der Rest des APIs ist nur maessig veraendert. Es wurden einige Vereinfachungen vorgenommen. IowKit2Write() z. B. braucht keine Groessenangabe fuer den Report mehr.
Die Reportstruktur ist nun gross genug um jeden IO-Warrior-Report aufnehmen zu koennen. Beim Schreiben an einen bestimmten IO-Warrior ist ja klar welchen Report er erwartet und es kann intern entschieden werden wieviele Bytes zu schreiben sind.
Einige andere weniger augenfaellige Einschraenkungen des APIs wurden durch die Vereinfachungen ebenfalls aufgehoben. Mehr will ich dazu nicht sagen, da es sich auf zukuenftige Produkte bezieht.
Das 2.0 API hat nur eine kleine Einschraenkung in der Anwendbarkeit under Windows.
Es wird intern ein Fenster erstellt, da Windows das An- und Abstecken von Geraeten mit Messages signalisiert. Verarbeitet und verteilt nun das Traegerprogramm der DLL keine Messages, so bekommt die DLL nichts von den Geraeteaenderungen mit und kann nicht funktionieren.
Dies sollte allerdings nur reine Konsolenanwendungen betreffen. Java-Programme sind zwar erst mal Konsolenanwendungen, aber die Java-VM betreibt Messageverarbeitung was das Problem loest.