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) |