Die Firma Renishaw verkaufte bis 2007 ein Laserinterferometer ML10, das mit einem sogenannten DX10-Interface per USB angesteuert wird. Die mitgelieferte Software passt leider nicht für meinen Anwendungsfall. Ich möchte aus der Kommandozeile von Windows nacheinander Messungen beauftragen. Als Ergebnis erwarte ich je eine Datei mit einer langen Zahlenkolonne (zB 50000 Messwerte für 10 sec Messung bei 5 kHz Takt), die ich dann über die Kommandozeile einer weiteren Auswertung übergebe. Mit der erhältlichen SDK konnte ich nur statische Messungen (maximaler Takt 10 Hz) beauftragen. Ein selbstgeschriebener Treiber für das DX10-Interface ist das Ziel! Als Entwicklungsumgebung nutze ich MinGW, libusb-win32 als Windows-Implementation der libusb-0.1 API und libusb0.sys als Windows Kerneltreiber. Eine Portierung nach Linux sollte damit kein größeres Problem darstellen. Es wird KEINERLEI Software/DLL vom Hersteller verwendet! Insbesondere läuft der dx10server NICHT. Der Treiber ist inzwischen rudimentär funktionsfähig, und kann statische (10 Hz) und dynamische (5 kHz) Messungen durchführen! Allerdings verstehe ich den Datenverkehr noch nicht völlig und kann dementsprechend keine engen Sicherheitsabfragen einbauen. Darüber hinaus wird die Wetterstation noch nicht ausgelesen und bisher nur EIN Laser an EINEM Eingang des DX10 unterstützt. Sicherlich ist auch alles etwas umständlich programmiert, da es nur durch "trial and error" gewachsen ist. - Aber der Anfang ist gemacht! --> Erste augenscheinlich korrekte Messwerte können in beiden Betriebsarten (statisch/dynamisch) ausgegeben werden! Nun meine Fragen: - Gibt es überhaupt ein allgemeines Interesse an dem hier beschriebenen (sehr speziellen) Treiber? - Kann ich auf Hilfe beim Weiterentwickeln erhoffen? - Wenn ja, wo sollte ich meinen Treiber ins Netz stellen? (Hier?)
Dieses DX10-Interface scheint etwas sehr firmenspezifisches zu sein. Google liefert sonst nixhts brauchbares. DirectX 10 ist es wohl nicht.
Ein großes allgemeines Interesse an dem beschriebenen Treiber scheint nicht vorhanden zu sein. Doch bevor ich meine Erkenntnisse nur für mich behalte und den Treiber nur selber benutze, können vielleicht auch andere (eventuell später) davon profitieren... Das C-File ist mit MinGW einfach mit make zu übersetzten (LDFLAGS=-lusb).
Ich habe nur mal aus Neugier den Quellcode angeschaut, dabei ist nur die Funktion aufgefallen. Warum verwendest du rdtsc zum bestimmen der Zeit? Das ist meines Wissen sehr fehleranfällig wenn mehre Kerne vorhanden sind, dann jede CPU hat ihren eigenen Counter. Selbst wiki warnt davor: http://en.wikipedia.org/wiki/Time_Stamp_Counter Under Windows platforms, Microsoft strongly discourages using the TSC for high-resolution timing for exactly these reasons, providing instead the Windows APIs QueryPerformanceCounter and QueryPerformanceFrequency.[2] Under *nix, similar functionality is provided by reading the value of CLOCK_MONOTONIC clock using the POSIX clock_gettime function.
Wo das Stichwort Linux gefallen ist, es wäre natürlich schön das Ding in einen echten Treiber umzuschreiben. Dabei müssten natürlich u.a. der Haufen Funktionen die aus process.h bereit gestellt werden, durch andere ersetzt werden, da process.h doch sehr Microsoft spezifisch ist. Dann könnte man es auch in den Kernel bringen und wenn ein Nutzer dann seinen Laser anschliesst, kann Linux da einfach "out of the box" ;)
physiker schrieb: > Wo das Stichwort Linux gefallen ist, es wäre natürlich schön das Ding in > einen echten Treiber umzuschreiben. Nee, man muss nicht alles, was am USB dranhängt, unbedingt in den Kernel quetschen. Der Aufwand, das dort zu pflegen (vor allem dann plattformübergreifend) ist ungleich größer, als wenn man einen generischen Treiber und libusb benutzt. Glaub' mir, es gäbe AVRDUDE nicht für Linux, Win32, OSX, *BSD, Solaris, wenn man für jedes davon unterstützte USB-Gerät noch einen eigenen Treiber schreiben müsste. Da ist die libusb mit einem plattformübergreifend einigermaßen einheitlichen API einfach ein Segen. Performancemäßig spielt das sowieso alles keine Geige.
Interessantes Projekt! Könntest du etwas ausführen, wie du das Protokoll reverse engineered hast? Und kannst du gute Dokumentation empfehlen, um sich in die libusb einzuarbeiten?
NurEinGast schrieb: > um sich in die libusb einzuarbeiten? So viel ist das nicht. Wenn du die Grundkonzepte von USB selbst verstanden hast und ein paar libusb-Beispiele angesehen hast, dann kannst du die auch selbst benutzen. Letztlich ist das API nicht viel mehr als eine Abbildung der USB-Aktionen. (Bitte keine unsinnigen Mailadressen im Formular eintragen. Wenn du keine Mail bekommen willst, weil es dich nicht interessiert, wenn ein Beitrag gelöscht oder verschoben wird, dann lass das Feld leer.)
NurEinGast schrieb:
> Könntest du etwas ausführen, wie du das Protokoll reverse engineered hast?
Reverse Engineering ist zeitaufwändig!
Wie MAN es macht, weiß ich nicht. Ich kann nur kurz aufzeigen was ich
gemacht habe:
Zum Ansehen des USB-Protokolls habe ich usbview.exe verwendet.
Allerdings musste ich erst einmal verstehen, wo die Bytes stehen, die
das Protokoll überhaupt ausmachen und woran man erkennt, auf welche Art
sie geschickt werden. Zudem funkt das Betriebssystem auch noch
dazwischen...
Ich habe mit einem kleinen USB-Experimentier-Board angefangen. Für das
Board kannte ich das USB-Protokoll genau und ich habe versucht, in dem
Datenwust der Ausgabe von usbview.exe meine Daten wiederzufinden.
Nach ich das Verständnis für die Ausgabe von usbview.exe hatte, habe ich
mir das Zielgerät vorgenommen.
Wenn man Glück hat, ist das Protokoll selbsterklärend, doch meistens...
Einfacher wird es, wenn man in sehr kleinen Schritten vorgeht:
Ich habe zum Beispiel das DX10-Interface per USB abgestöpselt, den
Sniffer gestartet und dann nur das Interface nur angestreckt und 10 sec
gewartet. Die Idee dahinter ist, aus einem reproduzierbaren Zustand
heraus mehrfach exakt das Gleiche zu machen und sich jedesmal den
Datenverkehr anzusehen und zu vergleichen. Erstaunlich, wie
unterschiedlich man doch anscheinend Gleiches darstellen kann!
Irgendwann erkennt man doch Regelmäßigkeiten und bekommt eine Idee eines
Daten-Protokolls. Hier ist Phantasie und Kreativität notwendig.
Jetzt ist das Abtippen der Byte-Folgen angesagt: Nachstellen der 10 sec
Startprotokoll, allerdings ohne Verständnis, was im Einzelnen passiert.
Wenn die erste erwartete Antwort vom Interface kommt, ist der erste
kleine Schritt getan.
Jetzt gibt es zwei Ansatzmöglichkeiten, die ich beide abwechselnd
genutzt habe.
Zum einen versuchte ich Regelmäßigkeiten in den Byte-Folgen zu endecken
(Längen, Prüfsummen, echte Daten, ...). Zum anderen kann man am
Zielgerät je EINE neue Funktion nutzen und die Veränderung des
Protokolls herausarbeiten.
Schrittweise habe ich mein Programm angepasst und erweitert und den
selbst erzeugten Datenverkehr mit dem vorher analysierten verglichen.
Erst beim Arbeiten habe ich die libusb kennengelernt. Gute Doku kenne
ich nicht. Nur das Testen hat mir geholfen.
Peter II schrieb:
> Warum verwendest du rdtsc zum bestimmen der Zeit?
Danke für die Info zum "rdtsc".
Ich verwende den Befehl nur als Info in meinem log-File und nicht zum
Einhalten eines Timings. Daher erscheint mir mein Fehler nicht so
kritisch. Aber bei Gelegenheit werde ich es ändern.
Bitte aber mehr solcher Anmerkungen! Nur so kann der Code besser werden!
nun ich hab sowas auch schon gemacht, allerdings bin ich anders an die Sache rangegangen. Ich habe den Treiber durch einen guten Disassembler geschickt der die API Funktionsaufrufe kennt (IDA Pro) Dann habe ich den Disassembler Output kommentiert. Im nächsten Schritt habe ich dann mit dem Theycon Treiber die Kommunikation nachgebildet. USB Treiber sind in aller Regel nicht sehr groß so dass das Disassembler File übersichtlich bleibt. Trotzdem ist es ein Haufen Arbeit. Zusätzlich braucht man bei dieser Vorgehensweise Knowhow wir unter Win Treiber aufgebaut sind. Thomas
> allerdings bin ich anders an die Sache rangegangen.
Sehr gute Idee! Hätte ich auch selber darauf kommen können. Bei
Gelegenheit werde ich das mal ausprobieren.
Allerdings könnte es rechtlich ein Problem geben - was ich hier aber
nicht weiter diskutieren will!
Gibt es weitere Anmerkungen zu meinem Progrämmchen?
Hallo B. Obachter, ich benutze libusb als Treiber und bediene mich seiner Funktionen in meiner Software. Als Beispiel hier ein Auszug der Software für einen ISP-Programmer für MCS51 und AVR. Die ID's sind nicht wirklich 0, ich habe sie nur für diesen Text zu 0 gesetzt. Die Funktionsaufrufe sind den Aufrufen der Firmware im eigenentwickelten Programmiergerät angepasst, also ähnlich wie bei deinem Gerät. Programmiert ist es, als Konsolenprogramm für Win32/64, mit Visual-C++ Express. Dem Projekt wird die Bibliothek "libusb.lib" hinzugefügt. Wie man dabei vorgeht, habe ich mir aus der libusb-Doku/Software und den mitgelieferten Beispielen erarbeitet. Auszug aus meinem C++ Programm: #include "USB\\lusb0_usb.h" // für libusb #include "USB\\requests.h" // für Funktionsaufrufe #define MY_VID 0x0000 // Device vendor and product id. #define MY_PID 0x0000 #define UsbWrite (USB_TYPE_VENDOR | USB_RECIP_OTHER | USB_ENDPOINT_OUT) // Device -> Host #define UsbRead (USB_TYPE_VENDOR | USB_RECIP_OTHER | USB_ENDPOINT_IN) // Device <- Host //--- Aus einer libusb-Beispieldatei kopiert ---------- usb_dev_handle *dev = NULL; /* the device handle */ innerhalb main() //--- Aus einer libusb-Beispieldatei kopiert ---------- usb_dev_handle *open_dev(void) { struct usb_bus *bus; struct usb_device *dev; for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == MY_VID & dev->descriptor.idProduct == MY_PID) { return usb_open(dev); } } } return NULL; } //--- USB initialisieren -------------------------------- { usb_init(); /* initialize the library */ usb_find_busses(); /* find all busses */ usb_find_devices(); /* find all connected devices */ if(!(dev = open_dev())) Beenden(USBInitFehler); } //--- USB Funktionsaufruf ------------------------------- SendToDriver(UsbWrite,VRQ_ENA_PROGR,0,0,&cVar,1); // Programmer enable //--- Funktionsdefinition ------------------------------- //int SendToDriver(CMD_READ_BYTE,wWord1,0,&bVar,1); // Byte lesen int SendToDriver (BYTE bDir,WORD wCommand,WORD wWrd1,WORD wWrd2,char *cPtr,BYTE bCount) { return(usb_control_msg(dev,bDir,wCommand,wWrd1,wWrd2,cPtr,bCount, 5000)); } ************************************************************* Auszug aus lusb0_usb.h (Bestandteil libusb): int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout); ************************************************************* Auszug aus requests.h (selbstdefiniert): //---- Benutzerrequests -------------------------------------------------- #define VRQ_READWRITE 3 // Benutzer-Statusrequest lesen/schreiben #define VRQ_WRITE_BUFFER 5 // Bis 8Byte über Puffer schreiben #define VRQ_READ_BUFFER 6 // Bis 8Byte über Puffer lesen #define VRQ_SET_SPEED 7 // Geschwindigkeit für SPI-Takt ändern #define VRQ_DIS_PROGR 8 // Programmiergerät sperren #define VRQ_ENA_PROGR 9 // Programmiergerät freigeben Ich hoffe das hilft dir ein wenig weiter. Gruß. Tom
> Als Beispiel hier ein Auszug der Software für einen > ISP-Programmer für MCS51 und AVR. Mein Code sieht für die Pipe 0 fast genauso aus. Vermutlich hatten wir die gleichen Beispiele oder man macht es einfach so. Interessanter wird das Ganze bei munteren Wechsel der Pipes mit bulk-Transfer. Meine Frage nach Anmerkungen bezieht sich auch weniger auf die Low-Level-Kommunikation (die läuft ja auch bei mir anstandslos), sondern auf die Programmstrukturen darüber.
Lange Zeit ist hier nichts passiert. Ich bin immer noch an Antworten auf meine ersten Fragen interessiert. - Ich stelle zwar fest, dass das Interesse an meinem Treiber hier nicht besonders groß ist. Doch habe ich die Hoffnung nicht aufgegeben, dass sich irgendwann jemand freut, wenn er das hier findet. - Hilfe beim Weiterentwickeln ist immer noch gerne willkommen. - Ich habe auch immer noch nicht die Stelle ins Netz gefunden, an die mein Treiber besser hinpasst. Darüber hinaus gibt es Neuigkeiten von meiner Seite, die zu diesem Thread passen: Zusätzlich zum Laserinterferometer ML10 mit DX10-Interface aus 2007 habe ich jetzt das aktuelle (2015) Laserinterferometer XL-80 mit angebunden. Als Entwicklungsumgebung nutze ich weiterhin MinGW, libusb-win32 als Windows-Implementation der libusb-0.1 API und libusb0.sys als Windows Kerneltreiber. Es wird KEINERLEI Software/DLL vom Hersteller verwendet! Mit meinem Frontend lassen sich wahlweise beide Lasertypen gleichartig ansteuern, obwohl sie intern völlig anders angesteuert werden. Sogar ein Parallelbetrieb mit beiden Lasern gleichzeitig an einem PC ist möglich! Bisher ist beim XL-80 nur der 5kHz Takt freigeschaltet. Die Datenstruktur für 50kHz ist aber im Code dokumentiert. Die Struktur meines ersten hier veröffentlichten Treibers hatte mich nicht zufriedengestellt. Er funktionierte zwar, aber der Code war viel zu kompliziert, da ich versucht hatte 1:1 den Datenverkehr der Herstellersoftware nachzubilden. Inzwischen habe ich den Datenverkehr drastisch "entschlackt". Damit ist der Code sehr viel einfacher, kompakter und übersichtlicher geworden. Es gibt ein allgemeines C-File (reni_v0.77.c), das die Bedienerschnittstelle, die Mess-Schleife und die Werte-Ausgabe enthält. Zwei weitere C-Files (dx10_v0.77.c und xl80_v0.77.c) bilden die Schnittstellen zu den beiden unterstützten Lasern.
B. Obachter schrieb: > Ich stelle zwar fest, dass das Interesse an meinem Treiber hier nicht > besonders groß ist. Das ist nicht des Treibers Schuld, sondern liegt an der exotischen damit anzusteuernden Hardware. Wer, der diese Hardware nicht hat, kann etwas mit Deinem Treiber anfangen?
Sollte ich deshalb meine Ergebnisse etwa nicht posten? Wie ich direkt nach dem Zitat gesagt hatte, habe ich die Hoffnung immer noch nicht aufgegeben, dass sich irgendwann jemand freut, wenn er das hier findet. Auch ich habe mich über viele Hilfen gefreut, die mir erst ermöglicht haben einen USB-Treiber zu schreiben. Da ich mit Treibern aber keine Erfahrung habe, würde ich mir einen Austausch dazu wünschen...
B. Obachter schrieb: > Sollte ich deshalb meine Ergebnisse etwa nicht posten? Nein, das ist ein Missverständnis. Es ist gut und begrüßenswert, daß Du Deine Ergebnisse hier gepostet hast; ich hatte nur versucht, zu erklären, warum die Resonanz so gering ist. Verzeih, wenn das zu sehr wie negative Kritik geklungen haben sollte - das ist damit nicht gemeint gewesen.
Alles klar! Wenn man sich sehr über weiterhelfende Informationen im Netz freut, möchte man irgendwann auch wieder etwas zurückgeben, auch wenn es nicht der Mainstream ist.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.