In Character Device schreiben

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
Felix
Beiträge: 453
Registriert: 17.02.2003 10:26:57
Lizenz eigener Beiträge: MIT Lizenz

In Character Device schreiben

Beitrag von Felix » 04.07.2008 14:57:55

Hallo,

ich habe mal eine ganz einfache Frage zur Programmiersprache C. Ich habe ein Kernelmodul für ein eigenes Character Device geschrieben. Dieses Characterdevice legt eine eigene Geraetedatei an etc.Wenn ich auf der Konsole mit dem Echo Befehl reinschreibe:

Code: Alles auswählen

echo 0 > /dev/pc2rc1
funktioniert das hervoragend. Die write-Funktion von meinem Modul wird nun mit dem entsprechenden Asciicode aufgerufen. Soweit so gut. Aber nun wollte ich im Userspace eine passende Anwendung für diesen Treiber schreiben. Allerdings wird hier beim Schreiben niemals die write-Funktion aufgerufen. Ich zweifel schon langsam an mir selbst. Hier mein Code:

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>

int main()
{
        char c;
        int i;
        FILE *channel1 = fopen("/dev/pc2rc1", "rw");

        if(channel1 == NULL)
        {
                printf("Kann Geraetedatei nicht oeffnen!\n");
                exit(1);
        }

        for (i = 0; i < 100; i++)
        {
                // read Channel 1 Input
                c = fgetc(channel1);

                // set Channel 1 Output to the Inputvalue
                fputc(c, channel1);

                // print the Channel 1 Value on the console
                printf("%i\n", c);

                // wait 10 ms
                usleep(100000);
        }
}
Das einlesen von dem Characterdevice ist kein Problem. Die Werte werden richtig angezeigt, aber das Auslesen funktioniert ums Verrecken nicht. Was mach ich falsch? Ich habs schon mit einem fflush hinter jedem fputc versucht, aber das hat nichts geholfen.

Gruß, Felix

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Re: In Character Device schreiben

Beitrag von cosmac » 04.07.2008 16:33:01

hi,

das "rw" beim fopen sieht zwar schön aus, wird aber wohl
nur als "r" interpretiert. Probier' mal "r+" oder "w+".
Beware of programmers who carry screwdrivers.

Benutzeravatar
Felix
Beiträge: 453
Registriert: 17.02.2003 10:26:57
Lizenz eigener Beiträge: MIT Lizenz

Re: In Character Device schreiben

Beitrag von Felix » 04.07.2008 17:22:10

Boah ... son blöder Fehler. Das hätte man aber auch mal intuitiver implementieren können. Na wie auch immer. Die write-Funktion meines Moduls wird jetzt endlich aufgerufen und alles funktioniert. Vielen dank für den Hinweiss, da hätte ich wohl noch ein paar Stunden gesucht. Naja, hab scheinbar vorher noch nie ne Datei zum gleichzeitigen lesen und schreiben mit C geöffnet. Man lernt halt nie aus.

Gruß, Felix

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Re: In Character Device schreiben

Beitrag von gms » 06.07.2008 19:27:19

Felix hat geschrieben:Vielen dank für den Hinweiss, da hätte ich wohl noch ein paar Stunden gesucht.
mit einer korrekten Fehlerbehandlung sind solche Fehler sicherlich schneller gefunden :wink:

zB:

Code: Alles auswählen

                if ( EOF==fputc(c, channel1)) {
                        perror("fputc failed");
                        break;
                }
edit: hätte ich fast vergessen zu erwähnen: es ist eher unüblich ein Device über einen Stream zu öffnen. Welche Vorteile erwartest du dir dadurch ?


Gruß
gms

Benutzeravatar
Felix
Beiträge: 453
Registriert: 17.02.2003 10:26:57
Lizenz eigener Beiträge: MIT Lizenz

Re: In Character Device schreiben

Beitrag von Felix » 06.07.2008 20:16:07

Fehlerbehandlung:

Ja, da hast du vollkommen recht. Allerdings hatte ich diese Beispielanwendung nur schnell hingetippt um alles zu testen, ohne Anspruch auf irgendwas. Bei dem Fehler bin ich dann nichmal darauf gekommen, dass es daran liegen könnte. Naja, Schlampigkeit eben, ich nehme da jede Schuld auf mich :oops: .

Stream:

Hmm, also ich bin mir nicht ganz sicher worauf deine Frage hinausläuft. Daher antworte ich einfach etwas ausführlicher. Ich muss an dieser Stelle auch noch zugeben, dass ich kein alteingesessener C-Hacker bin und Treiberprogrammierung für mich absolutes Neuland ist. Ich bin bei meinem Projekt einfach folgendermaßen vorgegangen:

1. Hardware entwerfen und zusammenlöten
2. Das Buch "Linux Treiber entwickeln" lesen
3. Erste Gehversuche mit selbstgeschriebenen Linuxtreibern (Hallo World etc.)
4. Kernelmodul für die eigene Hardware schreiben
5. Beispielanwendung (das ist das hier vorgestellte Codefragment) für den Programmierer schreiben, der später mal die wirklich ernsthaften Anwendungen für dieses Gerät schreiben soll

Ich habe den Treiber als Chardevice realisiert, weil die selbstgebaute Hardware pro Kanal immer nur einen aktuellen Wert bereitstellt, es interessiert auch nicht irgendeine Reihenfolge, sondern nur der alleraktuelleste Wert (1 Byte) den dieses Gerät auf dem entsprechenden Kanal bereitstellt. Ebenfalls kann dieses Gerät einen Wert (ebenfalls 1 Byte) ausgeben. Das soll es solange tun, bis man einen anderen Wert auf diesem Kanal ausgeben will. Für die Filestreamvariante auf der Userspaceseite habe ich mich entschieden, weil alle Beispielanwendungen die ich zu diesem Thema gefunden habe, es genauso machen. Wie würde man es denn üblicherweise machen? Bin da für Verbesserungsvorschläge sehr dankbar, da dieses Feld für mich wie gesagt Neuland ist. Allerdings bin ich schon recht zufrieden mit dem Ergebnis. Momentan funktioniert alles hervorragend zufriedenstellend :) .

Gruß, Felix

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Re: In Character Device schreiben

Beitrag von gms » 06.07.2008 20:50:04

Felix hat geschrieben:Für die Filestreamvariante auf der Userspaceseite habe ich mich entschieden, weil alle Beispielanwendungen die ich zu diesem Thema gefunden habe, es genauso machen.
das müßte man sich einmal genauer anschauen, warum die das so machen.
Felix hat geschrieben: es interessiert auch nicht irgendeine Reihenfolge, sondern nur der alleraktuelleste Wert (1 Byte) den dieses Gerät auf dem entsprechenden Kanal bereitstellt. Ebenfalls kann dieses Gerät einen Wert (ebenfalls 1 Byte) ausgeben. Das soll es solange tun, bis man einen anderen Wert auf diesem Kanal ausgeben will.
eine gepufferte Ein-/Ausgabe scheint mir hier aber eher kontraproduktiv oder zumindest ein unnützer Overhead zu sein.
Daher würde ich eher ein open/close mit read/write bzw ioctl empfehlen.

Gruß
gms

Benutzeravatar
Felix
Beiträge: 453
Registriert: 17.02.2003 10:26:57
Lizenz eigener Beiträge: MIT Lizenz

Re: In Character Device schreiben

Beitrag von Felix » 06.07.2008 21:01:42

gms hat geschrieben:eine gepufferte Ein-/Ausgabe scheint mir hier aber eher kontraproduktiv oder zumindest ein unnützer Overhead zu sein. Daher würde ich eher ein open/close mit read/write bzw ioctl empfehlen.
Inwiefern wird denn dort gepuffert? Kannst du mir das mal kurz umreissen? In meinem Kernelmodul puffer ich nichts. Das gibt bei Anfrage den aktuellsten Wert zurück. Kann mir nur vorstellen, dass das Schreiben in das chardevice (vom OS) gepuffert wird. Das wäre natürlich kontraprodutiv. Ist das so, oder hast du das anders gemeint?

Gruß, Felix

P.S.: Noch andere Tipps? Das Projekt fängt an mich richtig zu begeistern.

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Re: In Character Device schreiben

Beitrag von gms » 06.07.2008 21:08:50

Felix hat geschrieben:Kann mir nur vorstellen, dass das Schreiben in das chardevice gepuffert wird. Das wäre natürlich kontraprodutiv. Ist das so, oder hast du das anders gemeint?
ja, so habe ich das gemeint.
zuerst hatte ich deinen Beitrag nur überflogen und mir keine weiteren Gedanken gemacht, dann habe ich aber das mit dem"fflush" gelesen, da hats bei mir geklingelt :D :wink:

Benutzeravatar
Felix
Beiträge: 453
Registriert: 17.02.2003 10:26:57
Lizenz eigener Beiträge: MIT Lizenz

Re: In Character Device schreiben

Beitrag von Felix » 06.07.2008 21:16:02

Ja ich seh grad, ich hatte da auch auslesen, statt ausgeben geschrieben ... Hat sicher auch zusätzlich verwirrt.

Aber der Tipp mit dem gepufferten Schreiben ist natürlich vollkommen angebracht. Habe mir darüber bisher einfach keine Gedanken gemacht. Aber ist natürlich logisch, dass das an dieser Stelle Blödsinn ist. Fällt einem nur nicht so schnell auf, wenn man von ner anderen Programmiersprache kommt und zusätzlich bisher immer nur mit Dateien und Netzwerkverbindungen im Zusammenhang mit read/write Operationen gearbeitet hat. In diesem Sinne vielen Dank für den Hinweis und noch einen schönen Abend!

Gruß, Felix

Antworten