Device Treiber, lib oder ...?



  • hallo,

    wo soll ich anfangen? ich schildere erstmal das problem.

    ich habe ein programm geschrieben, das von einem device oder einer datei daten liest. diese werden dann verarbeitet und lokal gespeichert. das programm arbeitet also vor sich hin, liest die daten, bearbeitet sie und speichert sie in strrukturen.

    das eigentliche anwendungsprogramm fragt nur nach, ob und welche daten sich geaendert haben. hat sich etwas geaendert, sollen die geaenderten daten abgerufen werden.

    soweit noch verstaendlich? im normal-fall wuerde man das programm in einige funktionen packen, von denen aus von der eigentlichen anwendung drauf zugegriffen werden kann.
    so geht es aber nicht! das programm liest permanent aus dem device und verarbeitet die daten. hierfuer ist also eine eigene task notwendig. das anwendungprogramm soll sich nur in abstaenden erkundigen, on sich etwas geaendert. wen ja, dann entsprechend lesen. nun kommt hinzu, das n > 1 anwendungsprogramme diese daten benoetigen.

    nun dachte ich mir, schreibe das programm, starte es als daemon und baue ein interface fuer anwendungen. aber wie kann nun der zugriff vom anwendungsprogramm auf diesen daemon erfolgen? ideal waere, wenn der daemon ein device erzeugen koennte, auf das die anwendungsprogramme zugreifen koennten.

    konnte ich mich verstaendlich ausdruecken?





  • Gute idee, ein Device auslesen, dann wieder in ein Device schreiben und dieses wieder auslesen... Zwischendurch das Proggi mal bis 28757868934 zählen lassen, Hauptspeicher von vorne nach hinten und wieder zurückkopieren.. gibt zwar sicher schönen code, ist aber nicht so resourcesnfreundlich 😉

    bastel den code doch einfach ins programm rein und mach was mit multithreading. Gibt auch schönen (und nebenbei auch produktiven..) code.

    -elvis



  • hi,
    erstmal danke fuer den link. leider hat das nicht so richtig weitergeholfen. irgendwie fehlen mir einige grundlagen.

    ich stelle mir das ganze jetzt wie folgt vor:
    das programm laeuft als daemon
    liest aus dem device
    parst den datenstrom und speichert die ergebnisse in variablen
    die clients werden bei aenderungen der werte informiert

    der/die clients machen folgendes

    // verbindung herstellen
    fd = open( "/mydaemon");
    
    // non blocking mode setzen
    
    if( read ( ereignis))
    {
     switch (ereigniss)
     {
      case 1: ioctl( fd, ...);  // parameter des ereignisses holen
                 break;
      // usw
     }
    }
    

    mit tcp sockets wuerde ich das ganze hinbekommen (ausser ioctl). das ist aber etwas overdressed. als module wahrscheinlich auch. aber ein module laeuft im kernelspace (oder?). das ist auch overdressed.
    der client soll 'nur' open, close, read write und ioctl benutzen. in dem link oben habe ich das socket beispiel testen wollen, geht aber nicht (bind fehler).
    kann mir einer auf die spruenge helfen?



  • benutz lieber FIFOs oder Unix-Sockets oder (Für die Geschwindigkeit idr. am besten) Shared Memory.

    Siehe den Link, den ich gepostet hab.



  • baeh. ich will ein modul schreiben 🙂
    ich habe gelesen, das module auch im userspace laufen koennen.

    zur sache. eigentlich ist es mir peinlich, das ich ueberhaupt so ein problem mit der schnittstelle habe.

    ich habe von deinem link oben das hier getestet. steigt aber mit einem bind error aus. woran das wohl liegen mag?

    int main(void)
        {
            int s, s2, t, len;
            struct sockaddr_un local, remote;
            char str[100];
    
            if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
                perror("socket");
                exit(1);
            }
    
            local.sun_family = AF_UNIX;
            strcpy(local.sun_path, SOCK_PATH);
            unlink(local.sun_path);
            len = strlen(local.sun_path) + sizeof(local.sun_family);
            if (bind(s, (struct sockaddr *)&local, len) == -1) {
                perror("bind");
                exit(1);
            }
    
            if (listen(s, 5) == -1) {
                perror("listen");
                exit(1);
            ]
    // ...
    

    geht damit denn auch ioctl? zum thema speed. der 'treiber' bekommt ca 1kb/s . nach dem parsen werden an den client max 2kb/s uebergeben. der zugriff vom client auf den 'treiber' soll so einfach wie irgend moeglich sein. kein bind connect usw. sondern nur wie von mir oben beschrieben.



  • hi, ich schon wieder 🙂

    ich habe den 'treiber' jetzt so geschrieben, das er mit dem client via stream in verbindung steht. wenn im 'treiber' ein ereignis auftritt, wird dieses mittels write geschrieben und vom client mit read gelesen. es gibt ca. 50 verschiedene ereignisse, die als int geschrieben werden. daher ist das lesen seitens des clients recht einfach. nun gehoeren aber zu vielen ereignissen werte in form von strings, strukturen usw. nun waere es ideal, wenn ich diese werte mittels ioctl aufrufen bekommen koennte. das wuerde die programmierung auf der client sehr einfach halten. nun nochmal meine frage

    koennen mit der stream loesung ioctl aufrufe implementiert werden. wenn ja, wie? ich habe bisher einfach keine beispiele gefunden.

    wie das ganze bei modulen funktioniert, habe ich nun gelesen und evtl auch verstanden. da ich jedoch noch immer nicht weiss, wie man module im userspace laufen laesst, bleibe ich erst mal bei meinem einfachen ansatz.


Anmelden zum Antworten