Effizientes Design
-
Hi,
ich darf mich um ein etwas größeres "Projekt" kümmern, das ich mal schnell beschreibe:
4 ADCs werden der Reihe nach von einem FPGA abgefragt und die Werte werden über die PCIe Schnittstelle an ein Linux System weitergereicht.
Mein Job ist es einen Treiber und eine GUI zu schreiben und beim Design stoße ich jetzt an meine Wissensgrenzen Den Treiber will ich interruptgesteuert aufbauen, schließlich bekomme ich mit den neuen Werten welche. Das ist nicht mein Problem. Problematisch wird für mich eher die andere Seite. Irgendwer soll die Werte ja auslesen und weiterverarbeiten. Dafür wollte ich mir einen Daemon bauen, der die Daten dann auch über's Netz schicken kann und hier zwickt's jetzt. Würde ich einen Mikrocontroller programmieren, sähe dessen Pseudocode folgendermaßen aus:
void main() { initsachen(); while(1) { daten_auslesen(); daten_verarbeiten(); } }
Sprich beim Mikrocontroller bediene ich mich einfach einer Endlosschleife. Das führt dann natürlich zu einer 100%igen CPU Auslastung, die beim Mikrocontroller nicht stört, bei einem Betriebssystem jedoch schon. Ich bin dann mittlerweile über
int nanosleep(const struct timespec *req, struct timespec *rem);
gestolpert, womit sich die Auslastung gehörig drosseln lässt, aber das ist noch nicht das was ich eigentlich will. Am liebsten wäre es mir, wenn ich dem Daemon iwie von außen sagen könnte, "hey es sind neue Daten da, schau mal nach". Ich denke mal das Stichwort ist Signale, aber bei denen steig ich noch nicht so recht durch. Hätte da vllt wer was für mich?
Danke,
schotter
-
Eine Möglichkeit wäre netlink.
Eine andere wäre blockierende IO, also dein Treiber registriert einen Device, der Daemon macht das Device auf und liest Daten, und wenn keine verfügbar sind, blockiert der Treiber eben, bis welche da sind.
Gibt sicher noch tausend andere Möglichkeiten.
-
schotter schrieb:
Mein Job ist es einen Treiber und eine GUI zu schreiben und beim Design stoße ich jetzt an meine Wissensgrenzen Den Treiber will ich interruptgesteuert aufbauen, schließlich bekomme ich mit den neuen Werten welche. Das ist nicht mein Problem. Problematisch wird für mich eher die andere Seite. Irgendwer soll die Werte ja auslesen und weiterverarbeiten. Dafür wollte ich mir einen Daemon bauen, der die Daten dann auch über's Netz schicken kann und hier zwickt's jetzt.
wo liest du denn die Daten, die du weiterschicken sollst? In einem Kernel-Modul oder als normales Programm?
Wenn du ein Kernel-Modul machen willst, kommst du nicht drum rum dir ein Kernel-Modul-Tutorial durchzulesen. Da steht wie die System-Treiber mit dem Userspace kommunizieren.
Der Netzwerkdaemon läuft im Userspace üblicherweise in einer Endlosschleife, genau wie auf deinem Microcontroller.
-
Marsi Motolami schrieb:
wo liest du denn die Daten, die du weiterschicken sollst? In einem Kernel-Modul oder als normales Programm?
Die Daten hole ich mir über ein Kernel-Modul von der PCIe Schnittstelle. Wie das genau abläuft habe ich noch nicht rausgefunden, aber das wird schon. Aktuell lese ich mich in das Thema ein und ich finde dieses Buch ganz gut. Wobei ich hier in Papierform die 3. Auflage zur Verfügung habe.
Mechanics schrieb:
Eine andere wäre blockierende IO, also dein Treiber registriert einen Device, der Daemon macht das Device auf und liest Daten, und wenn keine verfügbar sind, blockiert der Treiber eben, bis welche da sind.
So habe ich es letztlich vor.
Marsi Motolami schrieb:
Der Netzwerkdaemon läuft im Userspace üblicherweise in einer Endlosschleife, genau wie auf deinem Microcontroller.
Das mit der Endlosschleife war mir schon klar, nur wollte ich eben kein Programm, das meine CPU zu 100% auslastet bzw. das ich ineffizient mit nanosleep() o.ä. schlafen lege. Da ich die ganze Kommunikation mittels sockets mache, bin ich ganz glücklich drüber, dass select() den Daemon so lange schlafen legt, bis es eben was zu tun gibt.