Laden...

WinCE Serial Port: Antwort zuverlässig innerhalb von (sehr) kurzer Zeitspanne senden

Erstellt von macke_a vor 10 Jahren Letzter Beitrag vor 10 Jahren 1.967 Views
Hinweis von herbivore vor 10 Jahren

Titel geändert: "WinCE" aufgenommen und das eigentliche Problem benannt

M
macke_a Themenstarter:in
291 Beiträge seit 2007
vor 10 Jahren
WinCE Serial Port: Antwort zuverlässig innerhalb von (sehr) kurzer Zeitspanne senden

Hallo!

Ich möchte gerne die Priorität von meinem seriellen ComPort erhöhen, damit ich Daten schneller senden und empfangen kann.

Derzeit sieht mein der Sourcecode wie folgt aus:

    public static System.IO.Ports.SerialPort SerialPort = new SerialPort();

    public Serial() 
	{
        SerialPort = new System.IO.Ports.SerialPort();

        if (!SerialPort.IsOpen)
        {
            SerialPort.PortName = "COM2";
            SerialPort.BaudRate = 115200;
            SerialPort.DataBits = 8;
            SerialPort.Parity = System.IO.Ports.Parity.None;
            SerialPort.StopBits = System.IO.Ports.StopBits.One;
            SerialPort.Handshake = System.IO.Ports.Handshake.None;
            SerialPort.ReadTimeout = 500;
            SerialPort.WriteTimeout = 500;
            SerialPort.ReceivedBytesThreshold = 1;
            SerialPort.DataReceived += new SerialDataReceivedEventHandler(SerialPortDataReceived);
            SerialPort.Open();
       }
       GC.SuppressFinalize(SerialPort);
     }

    private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            byte[] DataSP = new byte[SerialPort.BytesToRead];
            SerialPort.Read(DataSP, 0, DataSP.Length);
            for (int x = 0; x < DataSP.Length; x++) { Input(DataSP[x]); }
        }
        catch (Exception) { }
    }

Wie kann ich jetzt die Thread Priority von derzeit 251 auf 240 setzen? Kann mir jemand dabei helfen, wie ich dies programmieren muss?

Vielen Dank für Eure Bemühungen.

U
1.688 Beiträge seit 2007
vor 10 Jahren

Ich möchte gerne die Priorität von meinem seriellen ComPort erhöhen, damit ich Daten schneller senden und empfangen kann.

Ich kann mir nicht vorstellen, dass das zielführend sein sollte. Welches Problem möchtest Du dadurch lösen?

C
258 Beiträge seit 2011
vor 10 Jahren

Du kannst die Priority vom SerialPort DataReceived event nicht beeinflussen, das funktioniert nur wenn du mit den Methoden serialPort.Read / serialPort.Write arbeitest. Dabei kannst du die Priority des Threads der die Methoden aufruft erhöhen.

Ich kann mir jedoch auch nicht vorstellen das das dein Problem löst, Ich selbst habe damit schon einmal herum gespielt und konnte keinen unterschied feststellen. Bzw in meinem Fall konnte ich damit keine TimeOuts/Verschwundene Packete die durch hohe CPU last entstehen verhindern. (Falls das auch in etwa dein anliegen ist)

M
macke_a Themenstarter:in
291 Beiträge seit 2007
vor 10 Jahren

Ich empfange 1000 Bytes und muss innerhalb von 20ms eine Antwort bzw. eine erfolgreiche Qutting (nach Überprüfung der Checksumme) darauf senden. In der Regel kann ich in 80% aller Falle diese auch erfolgreich senden, allerdings sind die anderen 20% auch wichtig.

Ich vermute das mein WinCE Betriebssystem bei Änderung der Thread Priorität dies auch schaffen wird. Oder was meint Ihr?

F
10.010 Beiträge seit 2004
vor 10 Jahren

[Hinweis] Wie poste ich richtig? Punkt 5
Da gehört auch hinzu das du dein Umfeld beschreibst, da sich WinCE definitiv anders verhält als ein Desktop PC.

Wenn deine Antworten zu langsam sind, dann höchstens weil der SerialPort noch auf Daten wartet weil sein Puffer noch nicht voll, oder der Timeout noch nicht abgelaufen ist.
Da solltest du mit "spielen".

M
28 Beiträge seit 2011
vor 10 Jahren

20 ms klingt für mich nach einer halben Ewigkeit - sollte doch für einen halbwegs aktuellen Prozessor möglich sein.

Mal ein anderer Ansatz:

Wenn deine Daten ein "festes" Ende-Zeichen (z.B. \r\n) haben, könntest Du dieses als serialPort1.NewLine festlegen und im DataReceived-Event dann die kompletten Daten in einem Rutsch mit ReadLine aus dem SerialPort holen. Habe damit bessere Erfahrungen gemacht, als mit dem byte-weisen Auslesen.

W
872 Beiträge seit 2005
vor 10 Jahren

Deine jetztige Implementierung benutzt den Threadpool. Synchrones Lesen in eigenem Thread ist wahrscheinlich schneller und sicherer, je nach Ressourcen-Lage.
Deine Inputfunktion wuerde ich so aendern, dass sie mit einem Array umgehen kann und Du nicht 1000 mal die Funktion aufrufst - die Funktion fehlt hier im Code.

M
28 Beiträge seit 2011
vor 10 Jahren

@weismat: die Funktion wird sehr wahrscheinlich NICHT 1000 mal (sprich für jedes Byte) aufgerufen! Zwar steht BytesReceivedThreshold auf 1 aber das bedeutet NICHT, dass bei jedem empfangenen Byte das Event gefeuert wird! Das ist ein verbreiteter Irrtum, der gerne zu Datenverlusten führt beim Lesen von Serialport! Das Event wird gefeuert, wenn 1 Byte eingetroffen ist. Es treffen aber womöglich (sehr wahrscheinlich) weitere Bytes ein, während das Event abgearbeitet wird - für diese Bytes wird kein Event gefeuert! Deswegen arbeite ich gerne mit ReadLine - das Event wird gefeuert, wenn das Zeilenende-Zeichen eingetroffen ist - dann stehen tatsächlich alle Daten im Buffer.

W
872 Beiträge seit 2005
vor 10 Jahren

Mir gings um folgende Zeile:

for (int x = 0; x < DataSP.Length; x++) { Input(DataSP[x]); }