Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - FAQ - Zum CC1-Forum - Zum CC-Pro-Forum

Serielle Schnittstelle von mehreren Threads aus Kategorie: Programmierung (von Johannes - 8.03.2004 18:06)


Moin,
ich habe ein Problem, dass ich unbedingt, am besten noch heute lösen muss, allerdings komme
ich nicht drauf und hoffe, dass ihr mir helfen könnt.

Mein Quellcode soll das Senden und Empfangen von 4 Long-Werten pro Sendung über die
serielle Schnittstelle von mehreren Threads aus ermöglichen. Leider funktioniert irgend etwas nicht.

Zur Funktionsweise:
�ber die SEND-Funktion übergebe ich dem Modul "communication_base.c2" einen Command mit 4
Parametern vom Typ Long: z.B. SEND("?xyz", 1000, 2000, 3000, 4000);

Zum Empfangen gibt es die Funktion GETANSWER, die wie folgt verwendet wird:
wait GETANSWER("?xyz"); //wartet, bis "?xyz empfangen wurde, Parameter werden ignoriert.
oder
communication_base.tData Data
wait GETANSWER2("?xyz", Data);
Data.param1.... //so kommt man dann an die Daten.

Die ganze Sache funktioniert folgendermaÃ?en: In dem Modul "communication_base.c2" sind Variablen
deklariert, in die beim Aufruf der SEND-Funktion die übergebenden Parameter und der Command
gespeichert werden. Ein Thread, der dort immer läuft, nimmt diese Daten und sendet sie an die
Schittstelle. Da man ja nur 30 Zeichen senden kann, wird insgesamt 4 mal gesendet.
Dieser Thread überwacht auch die eingehenden Daten und schreibt sie ebenfalls in
Variablen, die dann über die GETANSWER-Funktion wieder abgefragt werden können. Beim Empfangen
wird pro Parameter (also 4 mal insgesamt) ein ":" Doppelpunkt als Bestätigung zurückgesendet.

Nun der Quellcode:

----------------- "communication_base.c2" -----------------
      type tData {
         string command;
         long   param1;
         long   param2;
         long   param3;
         long   param4;
         long   busy;
       }
       
       type tHshk {
         string command;
         long   busy;
       }

       tData Input;
       tData Output;
       int ACKInput[5];
       int ACKWaiting;
       tHshk ACKOutput;

       function pSplit(byte s[], byte searchfor, string t[]) returns byte {
         byte i,j,x;
         j=0;
         t[0]="";
         for i=0 ... s[31]-1 {
           x=s[i];
           if x==searchfor {
             j=j+1;
             t[j]="";
           }
           else t[j]=t[j] + x;
         }
         return j+1;
       }

       function SETACK()  returns int{
         wait ACKOutput.busy == 0;
         ACKOutput.command = ":";
         ACKOutput.busy = 1;
       }

       function SEND(string command, long param1, long param2, long param3,
                     long param4) {
         // Sendet Command mit Parametern
         wait Output.busy == 0;
         Output.command = command;
         Output.param1 = param1;
         Output.param2 = param2;
         Output.param3 = param3;
         Output.param4 = param4;
         Output.busy = 1;
       }

       function GETANSWER(string command) returns int {
         // Wartet auf Antwort (ohne Parameter-Ã?bergabe)
         if strx.comp(command,Input.command) {
           Input.command = "";
           Input.param1 = 0;
           Input.param2 = 0;
           Input.param3 = 0;
           Input.param4 = 0;
           return -1;
         }
         else {
           return 0; }
       }

       function GETANSWER2(string command, tData Data) returns int {
         // Wartet auf Antwort (mit Parameter-Ã?bergabe)
         if strx.comp(command,Input.command) {
           Data.param1 = Input.param1;
           Data.param2 = Input.param2;
           Data.param3 = Input.param3;
           Data.param4 = Input.param4;
           Input.command = "";
           Input.param1 = 0;
           Input.param2 = 0;
           Input.param3 = 0;
           Input.param4 = 0;
           return -1;
         }
         else {
           return 0; }
       }

       function pSend (string command, int number, long parameter) {
         int length;
         string data;
         data = command + " ";
         str.putint(data,number);
         data = data + " ";
         str.putlong(data,parameter);
         length = str.length(data);
         int a;
         for a=length...30  {
           data = data + " ";
         }
         hwcom.send (data, 30);
         wait hwcom.ready();
       }

       function pSendAck (string command) {
         int a;
         int length;
         length = str.length(command);
         for a=length...30  {
           command = command + " ";
         }
         hwcom.send (command, 30);
         wait hwcom.ready();
       }

       function pReceiveByte(byte Buf[]) returns int {
         int a;
         for a=0...19 {
           Buf[a] = 0; }
         int returnval;
         returnval = hwcom.receive(Buf, 20, 0);
         return returnval;
       }

       function pReceive(string myData) returns int {
         int a;
         byte Buf[19];
         int returnval;
         returnval = pReceiveByte(Buf);
         myData = "";
         for a=0...19 {
           str.putchar(myData, Buf[a]); }
         return returnval;
       }

       thread Communication {
         string rawdata;
         int datalength;
         string command;

         // ACK senden
         wait hwcom.ready();
         command = ACKOutput.command;
         if ACKOutput.busy == 1 {
            pSendAck(command);
            ACKOutput.command = "";
            ACKOutput.busy = 0;
         }

         // Daten senden
         wait hwcom.ready();
         command = Output.command;

         if Output.busy == 1 {
        // sleep 100;
           if (ACKInput[1] == 0) and (ACKWaiting == 0) {
            pSend(command,1,Output.param1);
            ACKWaiting = 1;
           }
           if (ACKInput[1] == 1) and (ACKWaiting == 1) {
            pSend(command,2,Output.param2);
            ACKWaiting = 2;
           }
           if (ACKInput[2] == 1) and (ACKWaiting == 2) {
            pSend(command,3,Output.param3);
            ACKWaiting = 3;
           }
           if (ACKInput[3] == 1) and (ACKWaiting == 3) {
            pSend(command,4,Output.param4);
            ACKWaiting = 4;
           }
           if (ACKInput[4] == 1) and (ACKWaiting == 4) {
            Output.command = "";
            Output.param1 = 0;
            Output.param2 = 0;
            Output.param3 = 0;
            Output.param4 = 0;
            Output.busy = 0;
            ACKInput[0] = 0; ACKInput[1] = 0; ACKInput[2] = 0;
            ACKInput[3] = 0; ACKInput[4] = 0; ACKWaiting = 0;
           }
         }

         // Empfangen
         wait hwcom.ready();
         string dataset[29];
         int number;
         datalength = pReceive(rawdata);
         if datalength > 0 {
           string ident;
           strx.mid(rawdata,ident,0,1);
           string dp;
           dp = ":";
           if strx.comp(ident, dp) {
             // ACK
             if Output.busy == 1 {
              ACKInput[ACKWaiting] = 1;
             }
           }
           else {
             // Daten

             pSplit(rawdata,32,dataset);
             number = strx.getNum(dataset[1]);
             if (number == 1) {
               Input.param1 = strx.getNum(dataset[2]);
               SETACK();
             }
             if (number == 2) {
               Input.param2 = strx.getNum(dataset[2]);
               SETACK();
             }
             if (number == 3) {
               Input.param3 = strx.getNum(dataset[2]);
               SETACK();
             }
             if (number == 4) {
               Input.param4 = strx.getNum(dataset[2]);
               strx.mid(rawdata,Input.command,0,4);
               SETACK();
             }
           }
         }
       }

       function INIT() {
         hwcom.init();
         hwcom.setspeed (8);
         ACKInput[0] = 0; ACKInput[1] = 0; ACKInput[2] = 0;
         ACKInput[3] = 0; ACKInput[4] = 0; ACKWaiting = 0;
         run Communication;
       }


Das war das Modul. Nun ein Beispiel-Programm, das nicht funktioniert. Es sind zwei Dateien, da
hier zwei CC2 verbunden werden (beide enthalten natürlich das communication-Modul).

----------------- "test1.c2" -----------------
function dothebeep(int number) {
    int a;
    for a = 1...number {
      plm.beep (20);
      sleep(5);
      plm.beep (-1);
      sleep(100);
    }
}

thread main {
  communication_base.INIT();

  loop{
    wait communication_base.GETANSWER("?ack"); // "?ack" empfangen wird, "!ack" zurücksenden
    communication_base.SEND("!ack", 0,0,0,0);
    dothebeep(2);
  }
}


----------------- "test2.c2" -----------------
function dothebeep(int number) {
    int a;
    for a = 1...number {
      plm.beep (20);
      sleep(5);
      plm.beep (-1);
      sleep(100);
    }
}

thread main {
  lcd.init();

  loop {
    communication_base.SEND("?ack",0,0,0,0);
    wait communication_base.GETANSWER("!sdn");
    dothebeep(1);
    sleep 1000;
  }
}


Um ehrlich zu sein bin ich verzweifelt. Der Kram muss morgen laufen...
Ich hoffe, dass sich jemand damit beschäftigen kann, wäre aber meine letzte Rettung.

GruÃ?
Johannes


    Antwort schreiben


Antworten:

Re: Serielle Schnittstelle von mehreren Threads aus (von Dietmar Weickert - 8.03.2004 18:28)
    Re: Serielle Schnittstelle von mehreren Threads aus (von Floyd - 8.03.2004 19:34)
        Re: Serielle Schnittstelle von mehreren Threads aus (von Dietmar Weickert - 8.03.2004 20:12)