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

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
Ich nutze:
C-Control II Station, OSOPT V3.0
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: