Re: Serielle Schnittstelle von mehreren Threads aus Kategorie: Programmierung (von Dietmar Weickert - 8.03.2004 18:28) | ||
Als Antwort auf Serielle Schnittstelle von mehreren Threads aus von Johannes - 8.03.2004 18:06 | ||
| ||
Hallo Johannes! Verstehe ich das richtig: Du sendest von einer CC2 "!ack" und wartest auf der anderen CC2 darauf, dass "!sdn" ankommt? Muss es da nicht klemmen? Abgesehen davon: Pfeift eine der beiden CC2 wenigstens einmal, oder passiert einfach gar nichts? Hast du schon versucht, Debug-Ausgaben auf den Displays zu machen? Beste Grü�e, Dietmar. > 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 Floyd - 8.03.2004 19:34) Re: Serielle Schnittstelle von mehreren Threads aus (von Dietmar Weickert - 8.03.2004 20:12) |