Hi, ich bin derzeit dabei einen Analyseserver auf einem STM32F103ZE aufzusetzen der Daten vom CAN-Bus lesen soll. Als Betriebssystem dient uCLinux(2.6.x). Hierfür benötige ich bekanntlich einen Treiber, damit ich den CAN-Bus richtig nutzen kann als Device (also zb als /dev/can1 ). Zunächst wie es bisher ist: Derzeit ist es so, dass ich die Standardlibrary von ST genommen habe, in meine Anwendung eingebunden haben und es nach einigen Änderungen geschafft habe den CAN-Bus darüber in meiner Anwendung zu nutzen. Das blöde dabei ist, dass es nicht dem Standard entspricht, da einfach ein paar .h eingebunden sind und dann am Ende alles zusammengelinkt wird. Was ich möchte: Ich hätte es nun gerne so, dass ich Device im dev Verzeichnis habe, beispielsweise "/dev/can1" das ich dann ganz normal per open(/dev/can1) ansprechen kann und direkt darüber schreiben und lesen kann. Ich habe mir bereits angesehen wie das mit den simple-gpio's gereglt ist (für die die es nicht direkt kennen: es gibt eine Beispielanwendung von ST "Led_Show" die diesen Treiber benutzt und wo über open(), write(), read() die einzelnen LEDs angesprochen werden können). Grundsätzlich habe ich auch kein Problem damit das zu verstehen und könnte den Treiber selbst, wohl auch schreiben. Nun das Problem: Unter Linux werden, wie o.g., Device-Nodes im dev Verzeichnis erstellt um diese dann anzusprechen. Damit eine solche Device-Node auch weiß, was es denn überhaupt ist und welchen Treiber es benutzen soll, gibt es die MAJOR und MINOR Nummern in Linux. Und hier geht das Problem los. Ich glaube verstanden zu haben, dass jeder Treiber eine eindeutige MAJOR Nummer und jedes Gerät eine eindeutige MINOR Nummer, damit der Treiber beim verwalten von mehreren Devices diese auseinanderhalten kann. Was aber nirgendwo erklärt ist und auch nirgendwo im uCLinux (Beispiel-)Code zu finden ist, ist "wie" setze ich die MAJOR und MINOR Nummer. In den beiliegenden Beispielen scheint es so zu sein, dass diese automatisch vergeben werden über die Funktion "platform_register_driver()". Interessanterweise ist es aber dann so, dass z.B. die schon oben erwähnte gpio-Treiber immer die MAJOR Nr. 253 hat. Dies scheint aber nirgendwo vermerkt zu sein. Und dadurch kann ich meinem Devise, das ich anlege, nicht sagen welchen Treiber es benutzen soll, da man dafür diese Nummer wissen muss, die man nebenbei auch nirgendwo nachsehen kann. Meine Frage(n) nun: Weiß irgendjemand wie man die MAJOR Nr. setzen kann? Wenn ja, woher weißt du/er/sie das? Gibt es ein entsprechenden Beispiel o.ä.? Wenn ihr weitere Infos, wie Sourcen oder sowas benötigt, dann einfach bescheid sagen. Danke schonmal und hoffe mir kann jemand helfen Christopher
Hi, mal eingeworfen, ein paar Ideen zu dem Thema: http://www.kernel.org/doc/Documentation/devices.txt Eine gute Stelle für Dokumentationen zum Linux-Kernel findet man je nach Installation eines Standard-Linux Systems unter /usr/src/linux/Documentation oder unter dem Link oben. Die Kernel Sourcen beinhalten diese Infos zum großen Teil. Documentation/driver-model/platform.txt bzw die anderen Dateien in dem Ordner sind vielleicht auch informativ. Ich habe selbst noch nicht unter ucLinux entwickelt, gehe aber davon aus das der Grundkernel sich wenig verändert hat und auch das Treiber-Modell ähnlich aufgebaut ist. Daher hilft vielleicht ein Blick ins LDD, http://lwn.net/Kernel/LDD3/ oder unter http://www.makelinux.net/ldd3/chp-3-sect-2.shtml Ich würde an deiner Stelle im Linux Kernel Source etwas wühlen und mir Beispielcode anschauen. Unter drivers/char/cs5535_gpio.c ist ein Beispiel, wo die major number per Modulparameter übergeben werden kann. register_chrdev_region alloc_chrdev_region MKDEV(... sind Suchbegriffe die helfen könnten. drivers/char/vt.c scheint auch ein gutes Beispiel zu sein. Ich kann dir aber leider nicht sagen, inwieweit der ucLinux Kernel vom normalen Linux-Kernel abweicht. Aber selbst dann mein Tipp: andere Treibersourcen anschauen. Bis denn Björn
Christopher Biel schrieb: > Hi, > ich bin derzeit dabei einen Analyseserver auf einem STM32F103ZE > aufzusetzen der Daten vom CAN-Bus lesen soll. Als Betriebssystem dient > uCLinux(2.6.x). Hierfür benötige ich bekanntlich einen Treiber, damit > ich den CAN-Bus richtig nutzen kann als Device (also zb als /dev/can1 ). > Okay das ist dein Vorhaben die Buzzwords Hierzu sind CANopen und Can4Linux, bin mir im Augenblick nicht sicher was besser geeignet ist, allerdings würde ich hier mal einen Blick drauf Werfen bevor du das Rad neu erfindest. Das hätte dann auch denn Vorteil das deine Analyseserver Hardware unabhängig wäre weil die beiden genannten Frameworks von der realen Hardware abstrahieren. > Zunächst wie es bisher ist: > Derzeit ist es so, dass ich die Standardlibrary von ST genommen habe, in > meine Anwendung eingebunden haben und es nach einigen Änderungen > geschafft habe den CAN-Bus darüber in meiner Anwendung zu nutzen. Das > blöde dabei ist, dass es nicht dem Standard entspricht, da einfach ein > paar .h eingebunden sind und dann am Ende alles zusammengelinkt wird. > das ist doch garnicht so schlecht, auch wenn ich stark den verdacht habe das es nur läuft weil du ein NOMMU System hast ( µClinux ist nommu, auch wenn der Prozessor eine hat) und dir aus denn grund Wahrscheinlich keiner auf die Finger Klopft wenn du Hard auf igendwelche Adressen zugreifst. > Was ich möchte: > Ich hätte es nun gerne so, dass ich Device im dev Verzeichnis habe, > beispielsweise "/dev/can1" das ich dann ganz normal per open(/dev/can1) > ansprechen kann und direkt darüber schreiben und lesen kann. guter Plan wenn das mit den OpenCAN und CAN4Linux nichts wird mach hier weiter ;-) > Ich habe mir bereits angesehen wie das mit den simple-gpio's gereglt ist > (für die die es nicht direkt kennen: es gibt eine Beispielanwendung von > ST "Led_Show" die diesen Treiber benutzt und wo über open(), write(), > read() die einzelnen LEDs angesprochen werden können). argg der simple-gpio Treiber dnen du ansprichst ist nur in µClinux vorhanden, recht eigenwillig entwickelt und wird hoffentlich bald entsorgt. Solltest denn also nicht unbedingt als Vorlage nutzen. > Grundsätzlich habe ich auch kein Problem damit das zu verstehen und > könnte den Treiber selbst, wohl auch schreiben. > > Nun das Problem: > Unter Linux werden, wie o.g., Device-Nodes im dev Verzeichnis erstellt > um diese dann anzusprechen. Damit eine solche Device-Node auch weiß, was > es denn überhaupt ist und welchen Treiber es benutzen soll, gibt es die > MAJOR und MINOR Nummern in Linux. > Und hier geht das Problem los. Ich glaube verstanden zu haben, dass > jeder Treiber eine eindeutige MAJOR Nummer und jedes Gerät eine > eindeutige MINOR Nummer, damit der Treiber beim verwalten von mehreren > Devices diese auseinanderhalten kann. das ist nur noch bedingt so, da die Kernelentwickler das Problem sehen das, die Major Nummern ausgehen könnten. Werden moderne Treiber so entwickelt das sie diese Nummern Dynamisch erhalten und nicht mehr vorgeben werden. Stichwort platformdevice. um das anlegen des Device node unter /dev kümmert sich dann ein Dämon wie udev oder mdev ( wobei es meisten udev ist) > Was aber nirgendwo erklärt ist und auch nirgendwo im uCLinux > (Beispiel-)Code zu finden ist, ist "wie" setze ich die MAJOR und MINOR > Nummer. stimmt die sind ja auch an aussterben. Ein wenig Information zu den Thema findet sich in der Datei Documentation/devices.txt dort erfährst du zum Beispiel das der Major bereich 91 bei char devices für CAN Reserviert ist und die Minor Nummer die Can devices Hoch zählt also /dev/can0 hat Major =91 und Minor=0; /dev/can1 Major=91, Minor= 1 etc. Zum setzen der Node gibt es das Makkro MKDEV, such dir einfach einen Treiber unter device/char/* als Beispiel und versuche zu verstehen was dort gemacht wird. drivers/input/joydev.c ist zum Beispiel so ein Treiber. > In den beiliegenden Beispielen scheint es so zu sein, dass diese > automatisch vergeben werden über die Funktion > "platform_register_driver()". Interessanterweise ist es aber dann so, > dass z.B. die schon oben erwähnte gpio-Treiber immer die MAJOR Nr. 253 > hat. Dies scheint aber nirgendwo vermerkt zu sein. Das kann sich aber ändern, ich denke du hast nur den Vorteil das dein System beim Starten wenig Fluktuation hat weswegen es zufällig stabil ist. Wie gesagt für das anlegen der passenden devicenode unter /dev gibt es ein Dämon, welcher das ist, wird denn Kernel über /proc/sys/kernel/hotplug mitgeteilt, dieser wird dann getriggert wenn ein Device geladen oder entladen wird, der kümmert sich um dann um den passenden /dev Eintrag. > Und dadurch kann ich > meinem Devise, das ich anlege, nicht sagen welchen Treiber es benutzen > soll, da man dafür diese Nummer wissen muss, die man nebenbei auch > nirgendwo nachsehen kann. falsch entweder du schriebst ein Treiber wo du explizit die Major und Minor Nummer setzt dann kannst du das device statisch mit
1 | mknod name c Major Minor |
als root anlegen. oder du nutz die Dynamisch Vergabe der Node über die informiert dich dein Kernel über die Datei /proc/devices wo er dir sagt welche Major Nummer welches Device bekommen hat. > Meine Frage(n) nun: > Weiß irgendjemand wie man die MAJOR Nr. setzen kann? ja sie oben > Wenn ja, woher weißt du/er/sie das? aus denn Buch Linux Device Driver und der täglichen Erfahrung. :-) > Gibt es ein entsprechenden Beispiel o.ä.? siehe dir die Treiber an, welche bei ein linux dabei sind, such nach Begriffen wie CAN4LINUX, SocketCAN µCLinux und wenn das nichts hilft stick deine eigene lösung such dir ein Char device unter /device/char in dein Kernel Code und klaue von dort, Ausserdem solltest du dir das Verzeichnis Dokumentation ansehen, das Oben genannte Buch in der 3 Ausgabe (davor ist zu alt) ist auch nicht schlecht sind die Webseite Kernelnewbie und das µClinux Forum. > Wenn ihr weitere Infos, wie Sourcen oder sowas benötigt, dann einfach > bescheid sagen. > oder and > Danke schonmal und hoffe mir kann jemand helfen > Christopher
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.