Re: Bug im OS - eigentlich nicht Kategorie: Progr. Assembler, TaskingTools, OS (von Christian Jost - 6.11.2005 9:51) | ||
Als Antwort auf Re: Bug im OS - eigentlich nicht von Günni - 3.11.2005 20:49 | ||
| ||
Hallo Günni, ich habe ein Demoprogramm geschrieben. Vielleicht (hoffentlich) kann es jemand reproduzieren. Das PC-Programm ist in Java (könnte es auch in C# schreiben). Ich habe es vereinfacht und es sendet nun immer drei Befehle: 1. Led1 aus 2. Led1 ein 3. Led1 aus 4. und wieder bei 1. beginnen... Auf der C-Control Station läuft meine Empfangsroutine. Diese schaltet die LED1 der Station ein und aus. Anhand der empfangenen Daten führt dies nun dazu, dass die LED1 immer kurz blinkt: ____-_____-_____-_____-_____ Nach einer gewissen Zeit ändert sich plötzlich das Muster. Die LED1 bleibt leuchten und geht nur noch kurz aus weil sie den dritten Befehl (3. Led1 aus) noch nicht erhalten hat. Hier ist der Fehler. Das letzte Byte (ETX) fehlt. Es ist im Buffer aber der Befehl "wait hwcom.rxd();" blockiert! Erst wenn nach einem Moment der erste Befehl (1. Led1 aus) empfangen wird, wird der letzte Befehl ausgeführt. Bei mir tritt das Problem unregelmässig auf. Es gibt Fälle da passierte es nach dem 5. Befehl und manchmal läuft es nach 400 Befehlen immer noch Fehlerfrei. Die LED5 zeigt an, wenn die C-Control auf ein Byte in der Empfangsroutine wartet. Der Empfangsbuffer läuft nie über und ist genügend gross. const STX = 0x02; const ETX = 0x03; const DLE = 0x10; const FALSE = 0; const TRUE = -1; const SERIAL_BUF_SIZE = 1024; byte _serialBuf[SERIAL_BUF_SIZE]; //============================================================================== // S E R I A L R E C E I V E R //============================================================================== //------------------------------------------------------------------------------ // Empfängt ein Frame von der seriellen Schnittstelle // // data < ein Buffer für die zu empfangenen Daten // length > Grösse des Buffers. // returns < int : �bertragungsstatus: // >=0 : Anzahl empf. Bytes. // -2 : Bufferüberlauf. //------------------------------------------------------------------------------ function _receiveFrame(byte data[], int length) returns int { int pos; byte oldValue, newValue; pos = 0; oldValue = 0; newValue = 0; // Warte auf Startbedingung... do { wait hwcom.rxd(); oldValue = newValue; newValue = hwcom.get(); } while(oldValue != DLE | newValue != STX); wait hwcom.rxd(); newValue = hwcom.get(); // Empfange Daten... loop { // Warte auf Datenbyte... oldValue = newValue; stports.setLED(5,1); wait hwcom.rxd(); stports.setLED(5,0); newValue = hwcom.get(); // 2 DLE's heben sich auf... if (oldValue == DLE & newValue == DLE) { wait hwcom.rxd(); newValue = hwcom.get(); } if (oldValue == DLE & newValue == STX) { // Fehler: Startbedingung während der Datenübertragung erhalten! // => neu beginnen... pos = 0; wait hwcom.rxd(); newValue = hwcom.get(); continue; } // Auf Endbedingung prüfen... if (oldValue == DLE & newValue == ETX) { return pos; } // Auf Bufferüberlauf prüfen... if (pos >= length) return -2; data[pos] = oldValue; pos = (pos + 1); } } thread main { byte data[14]; int result; stports.init(); lcdext.init(); hwcom.init(); hwcom.setbuf(_serialBuf, SERIAL_BUF_SIZE); hwcom.setspeed(hwcom.SPEED_9600); hwcom.flush(); loop { result = _receiveFrame(data, 14); if (data[6] == 0) { // LED1 ein stports.setLED(1,1); } else { // LED1 aus stports.setLED(1,0); } lcdext.clear(); lcdext.home(); lcdext.print("in Buf: "); lcdext.zahl(hwcom.inbuffercnt()); } } und hier das Java-Programm: import java.io.OutputStream; import javax.comm.CommPortIdentifier; import javax.comm.SerialPort; public class SerialSender { private SerialPort port; private OutputStream os; public SerialSender() { try { CommPortIdentifier comId = CommPortIdentifier .getPortIdentifier("COM2"); this.port = (SerialPort) comId.open("TControl", 2000); this.port.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); this.port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE); this.os = this.port.getOutputStream(); } catch (Exception ex) { System.out.println(ex.toString()); } } public void sendTestMessage() { try { byte[] data; for (int i = 0; i < 1000; i++) { // LED1 aus data = new byte[] { 16, 2, 48, 10, 17, 0, 5, 1, 1, 0, 0, 0, 0, 0, (byte) 224, (byte) 230, 16, 3 }; this.os.write(data); this.os.flush(); // LED1 ein data = new byte[] { 16, 2, 52, 10, 17, 0, 5, 1, 0, 0, 0, 0, 0, 0, 16, (byte) 248, 16, 3 }; this.os.write(data); this.os.flush(); // LED1 aus data = new byte[] { 16, 2, 56, 10, 17, 0, 5, 1, 1, 0, 0, 0, 0, 0, 1, 57, 16, 3 }; this.os.write(data); this.os.flush(); Thread.sleep(600); System.out.println(i); } } catch (Exception ex) { System.out.println(ex.toString()); } } public static void main(String[] args) { SerialSender s = new SerialSender(); s.sendTestMessage(); } } Wäre schön wenn jemand dieses Verhalten bestätigen könnte bzw. mir sagen wo ich den Fehler gemacht habe. Das Java Programm benötigt zusätzlich das Comm-API um die serielle Schnittstelle anzusprechen: http://java.sun.com/products/javacomm/downloads/index.html Besten Dank. Gruss, Christian | ||
Antwort schreiben Antworten: |