Relaissteuerung +SoftwareProblem



  • Ich habe mir eine Relaissteuerung gebaut und gedacht ich kann einfach das Programm welches ich unten angefügt habe dafür benutzen!
    Jedoch habe ich im Moment kein Plan wieso es nicht auf dem Linux Rechner(Suse 9.1) läuft!

    Ich hoffe jemand kann mir helfen und sagen was ich ändern muss.
    Habe das Proramm mit gcc -o name.c aufgerufen!
    War das falsch??

    //This program is free software under the terms of the GNU GPLv2
    //copyleft Christoph Schleifenbaum
    
    #include <stdio.h>
    #include <unistd.h>
    #include <asm/io.h>
    
    #define LPT1 0x378
    
    #define COM1 0x3f8
    #define COM2 0x2f8
    
    //sets a pin on the serial port
    int set_serial_pin(int baseport, int pin, int value){
        int result = ioperm(baseport, 7, 1);
        if(result) return -1;
        if(pin==3){
            if(value)outb( inb(baseport+3) | 0x40, baseport+3);
            else     outb( inb(baseport+3) & 0xbf, baseport+3);
        }
        else if(pin==4){
            if(value)outb( inb(baseport+4) | 0x01, baseport+4);
            else     outb( inb(baseport+4) & 0xfe, baseport+4);
        }
        else if(pin==7){
            if(value)outb( inb(baseport+4) | 0x02, baseport+4);
            else     outb( inb(baseport+4) & 0xfd, baseport+4);
        }
        else{
            ioperm(baseport, 7, 0);
            return -1;
        }
        ioperm(baseport, 7, 0);
    }
    
    //reads a pin from the serial port
    int get_serial_pin(int baseport, int pin){
        int result = ioperm(baseport, 7, 1);
        if(result) return -1;
    
        if(pin==1)      result = inb(baseport+6) & 0x80;
        else if(pin==3) result = inb(baseport+3) & 0x40;
        else if(pin==4) result = inb(baseport+4) & 0x01;
        else if(pin==6) result = inb(baseport+6) & 0x20;
        else if(pin==7) result = inb(baseport+4) & 0x02;
        else if(pin==8) result = inb(baseport+6) & 0x10;
        else if(pin==9) result = inb(baseport+6) & 0x40;
        else            result = -1;
    
        if(result>0) result/=result;
    
        ioperm(baseport, 7, 0);
        return result;
    }
    
    //sets a pin on the parallel port
    int set_parallel_pin(int baseport, int pin, int value){
        int result = ioperm(baseport, 3, 1);
        if(result) return -1;
    
        if(pin==1){
            if(value)outb( inb(baseport+2) | 0x01, baseport+2);
            else     outb( inb(baseport+2) & 0xfe, baseport+2);
        }
        else if(pin>=2 && pin <=9){
            if(value)outb( inb(baseport) | pow2(pin-2), baseport);
            else     outb( inb(baseport) & 0xff-pow2(pin-2), baseport);
        }
        else if(pin==14){
            if(value)outb( inb(baseport+2) | 0x02, baseport+2);
            else     outb( inb(baseport+2) & 0xfd, baseport+2);
        }
        else if(pin==16){
            if(value)outb( inb(baseport+2) | 0x04, baseport+2);
            else     outb( inb(baseport+2) & 0xfb, baseport+2);
        }
        else if(pin==17){
            if(value)outb( inb(baseport+2) | 0x08, baseport+2);
            else     outb( inb(baseport+2) & 0xf7, baseport+2);
        }
        else if(pin==11){
            if(value)outb( inb(baseport+1) | 0x80, baseport+1);
            else     outb( inb(baseport+1) & 0x7f, baseport+1);
        }
        else{
            ioperm(baseport, 3, 0);
            return -1;
        }
        ioperm(baseport, 3, 0);
    }
    
    //reads a pin from the parallel port
    int get_parallel_pin(int baseport, int pin){
        int result = ioperm(baseport, 3, 1);
        if(result) return -1;
    
        if(pin==1)       result = inb(baseport+2) & 0x01;
        else if(pin>=2 && pin <=9) result = inb(baseport) & pow2(pin-2);
        else if(pin==10) result = inb(baseport+1) & 0x40;
        else if(pin==11) result = inb(baseport+1) & 0x80;
        else if(pin==12) result = inb(baseport+1) & 0x20;
        else if(pin==13) result = inb(baseport+1) & 0x10;
        else if(pin==14) result = inb(baseport+2) & 0x02;
        else if(pin==15) result = inb(baseport+1) & 0x08;
        else if(pin==16) result = inb(baseport+2) & 0x04;
        else if(pin==17) result = inb(baseport+2) & 0x08;
        else             result = -1;
    
        if(result>0) result/=result;
    
        ioperm(baseport, 3, 0);
        return result;
    }
    
    int pow2(int n){
        if(n<1) return 1;
        return pow2(n-1)*2;    
    }
    
    int main(int argc, char **argv)
    {
        int pin;
        int value;
    
        if(argc!=4 && argc!=3){
            printf("Usage: %s <port> <pin> [<value>]\n", argv[0]);
    	return -1;
        }
    
        if(ioperm(LPT1, 3, 1)){
            printf("Must be root...\n");
    	return -1;
        }
        ioperm(LPT1, 3, 0);
    
        pin = atoi(argv[2]);
        if(argc==4) value = atoi(argv[3]);
    
        if(!strcmp(argv[1], "LPT1")){
           if(argc==4)
               set_parallel_pin(LPT1, pin, value);
           else
               return get_parallel_pin(LPT1, pin);
        }
    
        if(!strcmp(argv[1], "COM1")){
            if(argc==4)
                set_serial_pin(COM1, pin, value);
    	else
    	    return get_serial_pin(COM1, pin);
        }
    
        if(!strcmp(argv[1], "COM2")){
            if(argc==4)
    	    set_serial_pin(COM2, pin, value);
    	else
    	    return get_serial_pin(COM2, pin);
        }   
    
        return(-1);
    }
    

    <edit=kingruedi> sfds </edit>



  • Die Funktionen outb() und inb() sind keine "echten" Funktionen sondern Inline-Makros des gcc und nur mit der Option "-O" (oder auch "-O2") verfügbar (Achtung: nicht Null sondern großes 'o'). Siehe auch outb() man page.

    Also: gcc -O2 -o mein_prog mein_prog.c

    Was sonst noch zu beachten ist, findest du auch in meinem Buch "C und Linux", in dem ich ein ganzes Kapitel der Hardware-nahen Programmierung gegönnt habe.

    Martin


Anmelden zum Antworten