/dev beschreiben mit C (kleines anfänger Problemchen)



  • Hi Leute, ich hab hier ein Problem,
    genauer gesagt eigentlich 2 😃

    hab jetzt mehrere stunden gegoogelt und da sich die Probleme gehäuft haben und ich momentan voll auf dem Schlauch stehe hab ich doch beschlossen, ein Forum auf zu suchen. 🙂

    Ich besitze ein kleines Board mit einem Mikrocontroller (Grasshopper AP7000 von iCnova).
    um meine GPIO Pins zu Steuern, muss ich auf die von mir erstellten Knoten (mit mknod) schreiben, bzw. lesen. Ich habe 3 Knoten:

    1.) /dev/gpioA
    2.) /dev/gpioC
    3.) /dev/gpioD

    ich benutze den (avr32-linux-gcc) -Compiler.

    jetzt zu meinen Problemen:

    Problem #1:
    Ich kann meine /dev -files nicht beschreiben. 😞
    Ich brauche etwas, das Äquivalent zu diesem Shell-Befehl ist:
    echo -ne '\\x00\\x19\\xFC\\x3F' > /dev/gpioA

    vielleicht kann einer mir Zeigen wie ich das machen kann.
    Ich habe schon so viele Tutorials gelesen, aber ich schaffe es nur die ersten beiden Hexa-Dezimalzahlen zu schreiben:
    am weitesten bin ich gekommen, als ich das versucht habe:

    #include <stdio.h>
    int main(){
    FILE *gpioA;
    gpioA =  fopen("/dev/gpioA", "r+");
    long pins = 0x3FFC1900; //Ich muss immer 2 Hex-Zahlen rückwärts schreiben,
    damit sie nachher in der Datei richtig ankommen.
    fwrite(&pins, sizeof(pins), 1, gpioA);}
    

    Wie oben schon erwähnt, reagiert mein Mikrocontroller nur auf die ersten beiden Hex-zahlen, also "3F". Wenn ich diesen Befehl auf meinem Rechner ausführe und dann die Datei mit einem Hex-Editor öffne, dann scheint es zu funktionieren.

    Problem #2:
    Auf meinem Board ist Linux installiert.
    Ich will die Funktion "msleep(mikrosekunden);" verwenden.
    Bevor aber mein scheduler diesen Prozess in den Schlafmodus setzt, muss ich vorher meine Dateien mit fclose() wieder freigeben. Und danach sofort wieder wieder öffnen mit fopen().Ich will es letzt endlich das hier schaffen:
    while (true)
    {
    1.) an mein GPIO-Ausgane ein "high" setzen.
    2.) 2 micro-sekunden schlafen.
    3.) an mein GPIO-Ausgang "low" setze.
    4.) 2 micro-Sekunden schlafen.
    }
    Das geht aber nicht so einfach, weil mein scheduler minimal 5 micro-Skunden schlafen kann, der soll aber 2 micro-Sekunden schlafen.
    Außerdem hab ich bemerkt, dass die Funktionen fopen() und fclose() alleine schon so viel Zeit in Anspruch nehmen (etwa 1000 micro-Sekunden) das ich gar nicht mal anfangen sollte mir über sleep Gedanken zu machen. (mein Micro-Controller hat 120MHz und arbeitet Linux-embeded).

    Was ich letztlich vor habe, ist das hier nach zu bauen:
    http://www.youtube.com/watch?v=gklBWwGyreM

    also so etwas ähnliches 🙂 (Bei mir sind es 45 LEDs, die ich auf einen Ventilator anbringe mit ca. 20 ups)

    Ich wäre für jede Hilfe Dankbar!!! 😃

    Um euch nicht mit diesem Text tot zu schlagen hab ich mal ein paar Fotos von meine Mikrocontroller und noch ein paar andere gemacht.
    dann könnt ihr euch ein besseres Bild von meinem kleinen Projekt machen. 😃

    http://img121.imageshack.us/img121/245/00017rp.jpg
    http://img97.imageshack.us/img97/5854/00009l.jpg
    http://img248.imageshack.us/img248/1399/00011h.jpg



  • Hi,
    also ich hab es jetzt geschafft meine /dev zu beschreiben, ich kann auf gut Deutsch jetzt alle GPIO Ein-/Ausgänge ansteuern. Der folgende Quelltext funktioniert:

    Testplattform.c

    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    #include <errno.h> 
    
    void init_gpio();
    void del_gpio();
    
    void sleepnow(unsigned int);
    
    int main()
    {
    	init_gpio();
    
    /*with this while loop, you can test, which GPIOs work***********
    	while(1)
    {
    	system("echo -ne '\\x00\\x19\\xFC\\x3F' > /dev/gpioA");
    	system("echo -ne '\\xFF\\xF8\\x00\\x00' > /dev/gpioC");
    	system("echo -ne '\\x00\\x07\\xFF\\xFF' > /dev/gpioD");
    
    	system("echo -ne '\\x00\\x00\\x00\\x00' > /dev/gpioA");
    	system("echo -ne '\\x00\\x00\\x00\\x00' > /dev/gpioC");
    	system("echo -ne '\\x00\\x00\\x00\\x00' > /dev/gpioD");
    }
    **************************************************************/
    	FILE *gpioA;
    	FILE *gpioC;
    	FILE *gpioD;
    
    	long pins;
    
    	// my uController needs 30 sec to run this (a = 10000)
    	// that means, that my uController needd 0.003sec (3minSec) to run this one time
    	// this also means, that my uController can run this loop 333.33 times in one sec.
    	// But i need about 800 times in one sec. (20*40) (the resolution of my LED Pov is 40)
    
    	int a = 10000;
    while(a!=0)
    	{
    
    		pins = 0x0019fc3f;
    		gpioA =  fopen("/dev/gpioA", "r+");
    		fwrite(&pins, sizeof(pins), 1, gpioA);
    		fclose(gpioA);
    
    		pins = 0xfff80000;
    		gpioC =  fopen("/dev/gpioC", "r+");
    		fwrite(&pins, sizeof(pins), 1, gpioC);
    		fclose(gpioC);
    
    		pins = 0x0007FFFF;
    		gpioD =  fopen("/dev/gpioD", "r+");
    		fwrite(&pins, sizeof(pins), 1, gpioD);
    		fclose(gpioD);
    
    //		usleep(200000);
    
    		pins = 0x00;
    		gpioA =  fopen("/dev/gpioA", "r+");
    		fwrite(&pins, sizeof(pins), 1, gpioA);
    		fclose(gpioA);
    
    		pins = 0x00;
    		gpioC =  fopen("/dev/gpioC", "r+");
    		fwrite(&pins, sizeof(pins), 1, gpioC);
    		fclose(gpioC);
    
    		pins = 0x00;
    		gpioD =  fopen("/dev/gpioD", "r+");
    		fwrite(&pins, sizeof(pins), 1, gpioD);
    		fclose(gpioD);
    
    //		usleep(200000);
    
    		a--;
    	}
    }
    
    {
    	system("echo none > /sys/class/leds/led1\\:green/trigger ");
    
    	system("mkdir /config/gpio/gpioA");
    	system("echo 0 > /config/gpio/gpioA/gpio_id");
    	system("echo 0x0019fc3f > /config/gpio/gpioA/pin_mask");
    	system("echo 0x0019fc3f > /config/gpio/gpioA/oe_mask");
    	system("echo 1 > /config/gpio/gpioA/enabled");
    
    	system("mkdir /config/gpio/gpioC");
    	system("echo 2 >  /config/gpio/gpioC/gpio_id");
    	system("echo 0xfff80000 > /config/gpio/gpioC/pin_mask");
    	system("echo 0xfff80000 > /config/gpio/gpioC/oe_mask");
    	system("echo 1 > /config/gpio/gpioC/enabled");
    
    	system("mkdir /config/gpio/gpioD");
    	system("echo 3 >  /config/gpio/gpioD/gpio_id");
    	system("echo 0x0007ffff > /config/gpio/gpioD/pin_mask");
    	system("echo 0x0007ffff > /config/gpio/gpioD/oe_mask");
    	system("echo 1 > /config/gpio/gpioD/enabled");
    }
    

    nun, ich hab jetzt nur noch ein kleines Problem, ich muss es schaffen 800 mal in einer Sekunde, meine GPIOs zu steuern, bzw. mit 800 Herz meine /dev -files beschreiben. 🙂

    Ich habe folgendes Versucht: wie schnell kann ich mit C meine /dev beschreiben, ohne die Files vorher zu schließen bzw. zu öffnen. (Dann darf ich allerdings die sleep funktion nicht mehr verwenden):

    Testplattform2.c

    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    #include <errno.h> 
    
    void init_gpio();
    void del_gpio();
    
    void sleepnow(unsigned int);
    
    int main()
    {
    	init_gpio();
    
    /*with this while loop, you can test, which GPIOs work***********
    	while(1)
    {
    	system("echo -ne '\\x00\\x19\\xFC\\x3F' > /dev/gpioA");
    	system("echo -ne '\\xFF\\xF8\\x00\\x00' > /dev/gpioC");
    	system("echo -ne '\\x00\\x07\\xFF\\xFF' > /dev/gpioD");
    
    	system("echo -ne '\\x00\\x00\\x00\\x00' > /dev/gpioA");
    	system("echo -ne '\\x00\\x00\\x00\\x00' > /dev/gpioC");
    	system("echo -ne '\\x00\\x00\\x00\\x00' > /dev/gpioD");
    }
    **************************************************************/
    	FILE *gpioA;
    	FILE *gpioC;
    	FILE *gpioD;
    
    	long pins;
    
    	pins = 0x0019fc3f;
    	gpioA =  fopen("/dev/gpioA", "r+");
    	gpioC =  fopen("/dev/gpioC", "r+");
    	gpioD =  fopen("/dev/gpioD", "r+");
    
    	int a = 10000;
    while(a!=0)
    	{
    
    		pins = 0x0019fc3f;
    		fwrite(&pins, sizeof(pins), 1, gpioA);
    
    		pins = 0xfff80000;
    		fwrite(&pins, sizeof(pins), 1, gpioC);
    
    		pins = 0x0007FFFF;
    		fwrite(&pins, sizeof(pins), 1, gpioD);
    
    //		usleep(200000);
    
    		pins = 0x00;
    		fwrite(&pins, sizeof(pins), 1, gpioA);
    
    		pins = 0x00;
    		fwrite(&pins, sizeof(pins), 1, gpioC);
    
    		pins = 0x00;
    		fwrite(&pins, sizeof(pins), 1, gpioD);
    
    //		usleep(200000);
    		printf("%d \n",a);
    		a--;
    	}
    		fclose(gpioA);
    		fclose(gpioC);
    		fclose(gpioD);
    }
    
    void init_gpio()
    {
    	system("echo none > /sys/class/leds/led1\\:green/trigger ");
    
    	system("mkdir /config/gpio/gpioA");
    	system("echo 0 > /config/gpio/gpioA/gpio_id");
    	system("echo 0x0019fc3f > /config/gpio/gpioA/pin_mask");
    	system("echo 0x0019fc3f > /config/gpio/gpioA/oe_mask");
    	system("echo 1 > /config/gpio/gpioA/enabled");
    
    	system("mkdir /config/gpio/gpioC");
    	system("echo 2 >  /config/gpio/gpioC/gpio_id");
    	system("echo 0xfff80000 > /config/gpio/gpioC/pin_mask");
    	system("echo 0xfff80000 > /config/gpio/gpioC/oe_mask");
    	system("echo 1 > /config/gpio/gpioC/enabled");
    
    	system("mkdir /config/gpio/gpioD");
    	system("echo 3 >  /config/gpio/gpioD/gpio_id");
    	system("echo 0x0007ffff > /config/gpio/gpioD/pin_mask");
    	system("echo 0x0007ffff > /config/gpio/gpioD/oe_mask");
    	system("echo 1 > /config/gpio/gpioD/enabled");
    }
    

    Etwas ganz merkwürdiges ist dann passiert:
    von der Geschwindigkeit braucht er jetzt nur noch etwa 3 sec um 10000 mal die Files zu beschreiben. Das sind 3333.333 Herz.
    Was allerdings mit meinen GPIO Pins tatsächlich passiert, ist etwas ganz anderes.
    Die LEDs, die an den GPIO Pins angeschlossen sind, gehen etwa 10x AN und AUS.
    Erwartet hätte ich allerdings, dass sie 1000 AN und AUS gehen, und mein Auge es deshalb nicht mehr wahrnehmen können.

    Vielleicht weiß einer von euch eine Antwort. 🙂

    Trotzdem Danke an alle, die bei meinem Threat davor mit dem Gedanken gespielt haben, zu antworten. 😉


Anmelden zum Antworten