Autor |
Nachricht |
AudiA4B6US Gast
Kostenloser Account, kein CAN Entwicklungs-Support
|
26-11-2006, 18:52 Titel: Probleme beim Ansprechen des ComPorts in C# |
|
|
Hallo zusammen,
Ich mache gerade meine ersten Gehversuche in C# (Visual Studio Express 2005) und stosse immer wieder auf das gleiche Problem. Zum Vergleich habe ich aehnlichen Code auch mal in VB geschrieben aber das Resultat ist das gleiche.
Der unten angehaengte Code ist ein einfaches Programm welches den Serial Port oeffnet, den CANUSB Adapter initializiert und dann die empfangenen Strings in einer Textbox ausgibt. Ich habe den Open Knopf mit der CANUSB Initialissierung verbunden, sodass das Loggen sofort mitlaeuft. Genauso mit dem Close Button der dem CANUSB Adapter sagt er solle aufhoeren mitzuloggen.
Das Problem ist nun, dass mein Programm einfriert wenn ich den Close
Button druecke. Nicht jedes mal aber ungefaehr jedes zweite mal. Wenn ich beim Schliessen die Zeile serialPort1.Write("C
"); weglasse dauert es laenger bis das Programm einfriert, es tritt aber denoch nach 5-10x oeffnen/schliessen auf. Der Wechsel auf einen Timer anstelle des DataReceived Events umgeht das Problem auch, aber ich bin mir nicht sicher, dass dies die Loesung fuer mein Problem ist oder es nur weniger offensichtlich macht.
Da ich noch ganz am Anfang bzgl. Programierkenntnisse stehe bin ich natuerlich etwas verwirrt und wuerde gerne ein paar Meinungen dazu hoeren. Auch Beispiele in VB6, VB 2005 oder C# 2005 waeren nuetzlich. Interessant ist, dass dies nur bei meinem eigenen Code passiert. Den CAN Tool kann ich sooft wie ich will Connecten oder Diconnecten, da fiert nichts ein.
Waere fuer jeden Tipp dankbar.
Gruss,
Dirk
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace CANTest10
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnOpen_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
btnOpen.Text = "Open";
//reset CAN adapter and close COM port
serialPort1.Write("C
");
serialPort1.Close();
}
else
{
btnOpen.Text = "Close";
// set COM port parameters and open COM port
serialPort1.PortName = "COM4";
serialPort1.BaudRate = 115200;
serialPort1.DataBits = 8;
serialPort1.StopBits = StopBits.One;
serialPort1.Parity = Parity.None;
serialPort1.Open();
//init CAN adapter to read all CAN traffic off CAN bus
serialPort1.Write("C
S3
Z0
O
");
}
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//if new data arrives in serial port buffer use invoke to display on Windows form
this.Invoke(new EventHandler(ProcessNewData));
}
private void ProcessNewData(object sender, EventArgs e)
{
//read all data received off buffer and display in text box
this.textBox1.Text = serialPort1.ReadExisting();
}
}
}
|
|
Nach oben |
|
|
candev Gast
Kostenloser Account, kein CAN Entwicklungs-Support
|
27-11-2006, 12:27 Titel: Probleme beim Ansprechen des ComPorts in C# |
|
|
Hi,
die Kiste haengt m.E. genau im serialPort1.Close()-Aufruf. Das koenntest Du mit dem Debugger mal testen. BreakPoint auf den serialPort1.Close()-Aufruf, dann Einzelstep. Haengt die Kiste hier so lange fest oder erst wenn Du das SerialPort-Objekt "loeschst"?
Schade ist, dass Dein Code die relevanten Stellen nicht enthaelt. Wichtig ist, wie und wo Du z.B. das serialPort-Objekt instantiierst und abraeumst.
Das Problem haegt oft mit Resource-Management zusammen. Du kannst unter interpretierten Sprachen und runtime-basierten Sprachen wie C#/Java nicht so programmieren wie in C++. Du solltest insbesondere das Dispose-Pattern ausgiebig nutzen (siehe Microsoft-Seiten). Solange Du wie in VB, C++ oder anderen compilierten Sprachen vorgehst wirst Du noch einen Haufen solcher Probleme bekommen.
Stell erstmal fest wo genau der "Haenger" ist. Die Kiste haengt sich m.E. nicht wirklich auf sondern es dauert einfach saulange, bis das Programm weiter ausgefuerht wird. Zu dem Umgang mit den Ports im besonderen wirst Du aber im Netz ganz gut fuendig.
Ach ja, der Haenger beim Schliessen des ser. Ports mit Close() tritt genauso auch unter C++ auf. Das Verhalten des seriellen Treibers ist, sagen wir mal, nicht gerade amusing. Sollte also der Close-Aufruf der fragliche Knackpunkt sein wirst Du Dich selbst um einen Workaround kuemmern muessen. Bei falschem Resource-Management kannst Du in Deinem eigenen Code Abhilfe schaffen.
Ich bin bei meinem Diagnosetester - auch wegen des Haengers im Close, aber auch wegen der nicht zufriedenstellend arbeitenden Baudraten-Umschaltung und der fehlenden Bitraten-Erkennungsmoeglichkeiten direkt auf der Hardware unterwegs. Das macht weniger Probleme als ueber die von Windows bereitgestellten Moeglichkeiten (API, OCX) zu gehen, allerdings erfordert das einen Geraetetreiber um an die Hardware zu kommen.
Gruß,
Jens |
|
Nach oben |
|
|
candev Gast
Kostenloser Account, kein CAN Entwicklungs-Support
|
27-11-2006, 13:16 Titel: Probleme beim Ansprechen des ComPorts in C# |
|
|
Kleiner Auszug aus der Hilfe-Seite zur SerialPort-Port Class, Member Close:
The best practice for any application is to wait for some amount of time after calling the Close method before attempting to call the Open method, as the port may not be closed instantly.
Wenn bei Dir also wirklich der Close-Aufruf die Ursache sein sollte, dann wirst Du
a) damit leben muessen oder
b) wie ich eigenhaendig Abhilfe schaffen muessen.
Viel Erfolg,
Jens |
|
Nach oben |
|
|
AudiA4B6US Gast
Kostenloser Account, kein CAN Entwicklungs-Support
|
27-11-2006, 15:01 Titel: Probleme beim Ansprechen des ComPorts in C# |
|
|
Hallo Jens,
Danke fuer die Antwort. Leider habe ich gerade erst angefangen, mich mit C# zu beschaeftigen. Und da war ich froh, dass ich mit Visual Studio Express 2005 und dessen drag'n'drop Objekten ueberhaupt schon mal mit dem CANUSB Adapter kommunizieren konnte. Aber ich bin schon mal froh, dass ich nicht der einzige bin, der diese Probleme hat. Um Resourcenverwaltung habe ich mich noch gar nicht gekuemmert, bin immer davon ausgegangen das die IDE schon den passenden Code einfuegen wuerde.
Ich werde Deinen Tipp mal verfolgen und im Debug Mode step by step versuchen herauszufinden, wo das Program genau haengt. Es ist definitiv immer bei einem Click auf Close, egal wie lange der Port davor offen war. Basierend auf dem, was ich bis jetzt gesehen habe passiert es haeufiger wenn viele Daten im Buffer sind oder der Buffer sehr off pro Zeiteinheit abgefragt wird.
Gruss,
Dirk |
|
Nach oben |
|
|
candev Gast
Kostenloser Account, kein CAN Entwicklungs-Support
|
27-11-2006, 16:44 Titel: Probleme beim Ansprechen des ComPorts in C# |
|
|
Hi Dirk,
dann ist es bestimmt wirklich der Close-Aufruf auf dem serialPort.
Ich wollte meinen Diagnosetester erst auch so umschreiben, dass er auf C# basiert (aktuell noch C++/MFC). Hintergrund ist, dass ich fuer meinen Benz ein neues Protokoll anbinden muss (herstellerspez.), da ich bisher nur VAG-Protokolle implementiert habe (Quasi VAG1551 bzw. VASweissnich).
Ich hatte mir erhofft, dass mit der .Net-Runtime nun endlich einmal ein vernuenftiger, funktionierender Zugriff auf den ser. Port moeglich sei. Meine Untersuchungen habe dann schnell gezeigt, dass auch die .Net-Runtime auf dem alten WinAPI-Gelumpe und aufsetzt und damit auch den Serial.sys-Treiber vom Windows verwendet. Dumm gelaufen, denn bis zu 200ms nach Umschalten der Bitrate kann ich mir nicht erlauben. Damit habe ich die Portierung auf C# mangels echter Vorteile (aber einem Haufen Nachteile im Zusammenhang mit dem GarbageCollector) sein lassen.
Gruß,
Jens
PS: Interessanten Wohnort hast Du - gerade fuer's Automobilhobby!
Zuletzt bearbeitet am 11-01-2012, 14:30, insgesamt 1-mal bearbeitet.
|
|
Nach oben |
|
|
rathma Gast
Kostenloser Account, kein CAN Entwicklungs-Support
|
01-12-2006, 15:40 Titel: Probleme beim Ansprechen des ComPorts in C# |
|
|
@candev
ich glaub, wenn ich so bei dir zwischen den zeilen lese brauch ich das gleiche wie du. ich will relativ primitiv(am besten mit vb) daten in einer sehr langsamen baud(5) senden und dann sofort drauf(also noch vor 200ms warten) mit einer anderen baud weiter senden und empfangen. fals du eine lößung hast bitte hier posten oder mir eine mail schicken.
gruss
markus |
|
Nach oben |
|
|
candev Gast
Kostenloser Account, kein CAN Entwicklungs-Support
|
01-12-2006, 20:01 Titel: Probleme beim Ansprechen des ComPorts in C# |
|
|
Aha, da muss auch einer slow init unter ISO9141 machen
Sorry, aber nach einschlaegigen Erfahrungen mit Anbietern von kommerziellen Produkten gibt es von mir weder Source-Code noch den DeviceDriver. Ich bitte um Verstaendnis dass ich keinen Nerv habe jahrelang an sowas zu entwickeln und andere dann Geld damit machen. Ich denke, Du verstehst das und Dir wuerde es nicht anders ergehen.
Um einen Anhaltspunkt fuer den Aufwand zu geben: Meines Wissens bin ich der einzige, der die Bitratenerkennung auf dem PC in seinem Diagnosetester hat - und zwar durch Ausmessen der Bitlaengen. Alle anderen brauchen dafuer externe Hardware (die dann den einen entsprechenden Timer mit Input-Capture-Funktionalitaet hat) oder sie "raten" die Baudrate durch ausprobieren. Allein diese Bitratenerkennung hat mich 2 Jahre beschaeftigt und war alles andere als lustig...
Gruß,
Jens |
|
Nach oben |
|
|
e320cdi Gast
Kostenloser Account, kein CAN Entwicklungs-Support
|
11-12-2006, 0:59 Titel: Probleme beim Ansprechen des ComPorts in C# |
|
|
Das Slow-Init / Fast-Init Problem läßt sich am einfachsten mit etwas Kreativität und geeigneter Interpretation von auf den ersten Blick nicht passenden Baudraten lösen.
Gerade beim Fastinit (25ms low/25ms high) haben viele serielle Schnittstellen einfach das Problem, die Umschaltung von 5Bd auf die 10400Bd oder was auch immer anschließend benötigt wird nicht in der erforderlichen Zeit hinzubekommen oder die Schnittstelle wird ungewollt neu initialisiert.
Wenn man über das Problem allerdings etwas intensiver nachdenkt und dann ggf. noch RTS/CTS der Schnittstelle selbst programmiert, gibt es auch dafür Lösungen.
Gruß, Mike |
|
Nach oben |
|
|
candev Gast
Kostenloser Account, kein CAN Entwicklungs-Support
|
11-12-2006, 20:04 Titel: Probleme beim Ansprechen des ComPorts in C# |
|
|
Gerade beim Fastinit (25ms low/25ms high) haben viele serielle Schnittstellen einfach das Problem, die Umschaltung von 5Bd auf die 10400Bd oder was auch immer anschließend benötigt wird nicht in der erforderlichen Zeit hinzubekommen oder die Schnittstelle wird ungewollt neu initialisiert.
Hi Mike,
das muss ich aber nicht kapieren, oder? Bei mir ist das zumindest anders
Bei Slow-Init habe ich das Problem der Bitraten-Umschaltung (PC als Plattform vorausgesetzt), bei Fast-Init habe ich kein Problem (wir sehen von Spezialfaellen wie dem Umschalten der Baudrate in Verbindung mit SW-Updates und manchem Hintertuerchen bei Entwicklungssteuergeraeten mal ab).
Gruß,
Jens (mit nur W202.078)
Zuletzt bearbeitet am 11-01-2012, 14:31, insgesamt 1-mal bearbeitet.
|
|
Nach oben |
|
|
e320cdi Gast
Kostenloser Account, kein CAN Entwicklungs-Support
|
12-12-2006, 1:51 Titel: Probleme beim Ansprechen des ComPorts in C# |
|
|
Hallo Jens,
ich kenne beim SlowInit eher Probleme mit dem erforderlichen Pegel des Signales (bei VW/Audi), beim FastInit (MB) dagegen eben die Probleme mit dem Wakeup-Pattern.
Allerdings setze ich meist keine PC-Plattformen ein sondern mikrocontrollergesteuerte Boards mit Infineon C164, ATMEL + PHILIPS SJA oder Freescale HCS12.
Gruß, Mike
P.S.: (211.226)
Zuletzt bearbeitet am 11-01-2012, 14:31, insgesamt 1-mal bearbeitet.
|
|
Nach oben |
|
|
|