Serial-port(COM1) splitter
-
Hallo leute,
ich hab folgendes problem:
ich habe 2 programme die gleichzeitig auf ein gerät zugreifen möchten, welches auf dem serial-port angeschlossen ist.
Greift ein programm auf serial-port zu, wird dem anderem programm der zugriff verweigert. (win_xp)so möchte ich den treiber etwas verändern und einen virtuellen serial-port für jeweils ein programm erstellen. z.B das gerät hängt auf COM1
das eine programm greift auf COM8 zu, das andere auf COM9 zu.
COM8 und COM9 sind virtuell und sollen von meinem treiber verwaltet werden.wie kann ich nun den virtuellen COM erstellen, bzw. die Daten von tatsächlichen auf den virtuellen übertragen.
(es muss auch kein treiber sein, dienst ist auch ok, bzw. für alle ideen bin ich offen)
danke im vorraus.
-
Sowas ist echt ne "lustige" Sache. Ich musste auch schon so etwas ähnliches machen. Allerdings hatte ich den Vorteil, dass der Zugriff in einem Programm stattfand. Bei zwei Programmen ist das natürlich etwas schwieriger zu realisieren.
Wie du virtuell ein COM8 und COM9 erstellst, weiß ich leider nicht :(. Aber über einen Dienst (also einem 3. Programm) könnte man es hinkriegen.
Wie wärs eigentlich, wenn du gleich ein 3. Programm laufen lässt, dass ständig die Daten vom Gerät abholt und dann über eine betimmte Schnittstelle die Daten anderen Programmen zur Verfügung stellt? Dann wäre auch die Anzahl der Programme, die es nutzen nicht dermaßen begrenzt.
-
Und wie erkennt der Dienst oder das "Programm", wohin die an COM1 reinkommenden Daten hinsollen?
Blackbird
-
Der Dienst speichert die aktuellen Daten einfach im Arbeitsspeicher, sobald ein Programm den Dienst in Anspruch nimmt, wird diesem der aktuelle Stand aus dem Arbeitsspeicher übermittelt.
-
So wies oben genannt wurde ist sicher der einfachste weg.
Nen virtuellen Treiber zu schreiben ist erstens zu viel Arbeit und zweitens machts ned so viel sinn
mfg
-
Die Logik ist mir nicht klar.
Da sendet das serielle Gerät Daten (z.B. für die App. an COM8), der Dienst speichert sie und die App. an COM9 pollt ständig. Die Daten, die für die App. an COM8 bestimmt waren, hat dann die App. an COM9. Und die interpretiert sie "irgendwie" oder schmeißt sie weg. Die App. an COM8 pollt nur irgendwann und bekommt nichts.
Und wenn die App. nicht pollen, sondern auf Events warten - an wen soll der Dienst die Daten senden? Das beste wäre noch an beide App. Aber da in den seriellen Daten keine Adressen drinstehen, werden die beiden verschiedenen App. die Daten auch falsch interpretieren.Wenn da nicht mit einem Software-Protokoll zwischen dem (einen) seriellen Gerät und den beiden Applikationen gearbeitet wird - geht es nicht.
Blackbird
-
@Blackbird
Also, da ist ein Gerät. Sagen wir an COM1, denn COM8 und COM9 ist schon ziemlich unwahrscheinlich ;). Das Gerät ist also NUR an COM1. Dann haben wir einen Dienst. Dieser Dienst läuft ständig und hat nur die eine Aufgabe, Daten vom Gerät zu empfangen bzw. dafür erstmal Anfragen zu stellen, wenn nötig. Die empfangenen Daten speichert der Dienst im Arbeitsspeicher (vorzugsweise als structs oder Klassen, je nachdem ob man C oder C++ verwendet). Dann besitzt der Dienst natürlich noch eine Schnittstelle. Sagen wir einfach mal OLE bei Windows. Nun hast du beliebig viele andere Programme, die Daten von dem Gerät brauchen und das auch noch "gleichzeitig". Da die serielle Schnittstelle, aber nicht gleichzeitig mehrfach benutzt werden kann und wir ja extra dafür einen Dienst haben, greifen die beliebig vielen Programme einfach über OLE auf den Dienst zu. Der Dienst kann dann auf Anforderung über OLE die aktuellen Daten im Arbeitsspeicher übergeben.
-
Hallo @AJ,
technisch ist das OK. Aber die Logik stimmt nicht!?
Der Dienst stellt 2 (oder mehr) virtuelle serielle Schnittstellen bereit (z.B.: COM1 und COM3 oder so). Selber greift er aber physikalisch auf COM1 zu, die dann natürlich im System im Direktzugriff nicht mehr vorhanden ist. Also können jetzt 2 unabhängige COM-Port-Programme über EINE serielle Schnittstelle auf ein Gerät zugreifen (einmal über 'COM1' und 'COM3').
Nun aber zum Ablauf und damit zur "Logik":
Senden zu diesem einem seriellen Gerät ( == zum Dienst): - fast kein Problem, wenn die zu sendenden Daten nicht gerade "tröpfeln". Woher soll der Dienst auch wissen, wann eine Datensequenz zu Ende ist? Er könnte also unwissentlich die Datensezenzen der beiden Programme mischen. Ob das aber dem seriellem Gerät so gut bekommt?
Empfangen vom seriellen Gerät: - ist immer ein Problem, denn für welches Programm sind denn die Daten jetzt bestimmt?
Erhalten beide die gleichen Daten sind zumindest ungültige Daten dabei. Aber wie soll das Programm das unterscheiden?Ein Beispiel (zugegeben, ist etwas weit hergeholt):
Ein RS232-Multimeter wird von einem Programm zur Spannungs- und vom anderen Programm zur Drehzahlmessung verwendet.
Jedes Programm schaltet das Meßgerät um und will Daten haben.
Oder ein Modem: jedes Programm macht eine eigene Verbindung auf. Wie unterscheiden sich denn die ankommenden Daten?Mal abgesehen davon, dass jedes Programm die Sequenz des anderen rigoros unterbricht oder stört, wenn es einfach so Steuerbefehle schickt.
Rein technisch ist so ein Dienst kein Problem. Aber praktisch ist er sinnlos.
Blackbird
-
@blackbird
Hast du mir meinen Beitrag eigentlich richtig durchgelesen?Ich gehe davon aus, dass die anderen Programme sich nur die Daten vom Dienst holen. Der Dienst regelt ganz alleine die Anforderungen und Antworten vom und zum Gerät.
Lass mal deine umständlichen virtuellen seriellen Schnittstellen weg.Wenn der Dienst auf Anforderung auch noch Daten vom Gerät anfordern muss, dann wird es natürlich etwas umständlicher mit dem Programmieren des Dienstes. Allerdings kann man den Dienst so programmieren, dass er die Anforderungen anderer Programme in eine Warteschleife hängt oder einfach ablehnt, wenn bereits ein Programm eine Anforderung an den Dienst geschickt hat und damit noch das Gerät belegt.
Interesant wär es mal um welches Gerät es sich überhaupt handelt.
Ich setze jetzt mal dein Beispiel mit dem Multimeter mit meiner Vorstellung des ganzen zusammen:
An COM1 ist ein Multimeter angeschlossen. Auf bestimmte Anforderungen sendet es verschiedene Daten. Dann besteht nun ein Dienst, dessen Aufgabe es ist, ständig die nötigen Anforderungen zum Holen aller Daten des Multimeters (beschränken wir es mal auf die zwei genannten: Spannung und Drehzahl) zu senden. Intern speichert der Dienst die aktuellsten Werte im Arbeitsspeicher (hier einfach in zwei globalen Variablen: spannung, drehzahl). Außerdem hat der Dienst eine Softwareschnittstelle, z. B. OLE mit der er zwei Funktionen bzw. Methoden zur Verfügung stellt: get_spannung(), get_drehzahl().
Nun gibt es zwei Programme. Das eine braucht die Spannung des Geräts, das andere die Drehzahl. Beide Programme erstellen ein OLE-Objekt um auf die Schnittstelle des Dienstes zuzugreifen. Das erste Programm ruft die Methode get_spannung() auf, das zweite die Methode get_drehzahl(). Der Dienst gibt nun ganz einfach bei der ersten Methode den Wert seiner globalen Variable spannung zurück und bei der zweiten Methode die globale Variable drehzahl.Was ist jetzt bitte so schwierig und verwirrend dran?
-
Hallo @AJ,
Deinen Beitrag habe ich schon genau gelesen. Und Du hast auch mit Deiner Lösung recht. Nur beantwortet sie nicht die eingangs gestellte Frage von @plushkin. Er will einfach "virtuelle COM"-Schnittstellen haben. Also
einfach einen Treiber/Service/... der aus den COM1 und COM2 dann eben COM1 ... COMx macht, die dann (vielleicht paarweise?) den tatsächlichen Schnittstellen zugeordnet sind. Und zugreifen mit CreateFile ("COM3", ....).... ich habe 2 programme die gleichzeitig auf ein gerät zugreifen möchten, welches auf dem serial-port angeschlossen ist.
Greift ein programm auf serial-port zu, wird dem anderem programm der zugriff verweigert. (win_xp)... so möchte ich den treiber etwas verändern und einen virtuellen serial-port[b] für jeweils ein[b] programm erstellen ...
So habe ich die Frage verstanden.
Und das ist zwar möglich, aber sinnlos.
-
@Blackbird
Ich hab mich darauf bezogen.plushkin schrieb:
(es muss auch kein treiber sein, dienst ist auch ok, bzw. für alle ideen bin ich offen)
Wir stimmen wohl dahingehend überein, dass die Lösung mit den virtuellen COM-Schnittstellen erheblich schwieriger zu realisieren wäre.
Möglich wäre es, aber ich denke, man müsste ziemlich tief ins Betriebssytem eingreifen, was das ganze schwierig und aufwendig machen würde.@plushkin
Was willst du jetzt eigentlich machen? Oder hat sich das Problem schon gelöst?
-
Wenn man eingeloggt ist, könnte man ja auch editieren ...
[quote]... so möchte ich den treiber etwas verändern und einen virtuellen serial-port für jeweils ein programm erstellen ...
Dein Dienst ist ideal, wenn man selber diese Programme schreibt oder schon geschrieben hat.
Blackbird
-
Gleich noch einen hinterher ... :p
Ja, wir haben von verschiedenen Dingen gesprochen.
Wobei ich mir nicht sicher bin, ob @plushkin weiß, was ein Dienst und was ein Treiber ist?Aber noch mal:
Wir stimmen wohl dahingehend überein, dass die Lösung mit den virtuellen COM-Schnittstellen erheblich schwieriger zu realisieren wäre.
Möglich wäre es, aber ich denke, man müsste ziemlich tief ins Betriebssytem eingreifen, was das ganze schwierig und aufwendig machen würde.Egal wie schwierig, es ist sinnlos, da die Daten nicht auseinandergehalten werden können. Es besteht keine Zuordnung der eintreffenden Bytes zu den Programmen.
Blackbird
-
Hmmm ich überleg grad, ob es nicht doch etwas einfacher gehen könnte, als ich erst dachte. Kommt hald drauf an wie man virtuell eine COM-Schnittstelle erstellt und diese regelt.
-
Blackbird schrieb:
Egal wie schwierig, es ist sinnlos, da die Daten nicht auseinandergehalten werden können. Es besteht keine Zuordnung der eintreffenden Bytes zu den Programmen.
Blackbird
Hmmm ja ich verstehe schon auf was du hinauswillst. Das große Problem ist, dass man nicht weiß, welches Gerät an der Schnittstelle hängt und jedes Gerät reagiert natürlich anders und meistens ist es auch von den Befehlen abhängig.
Gut generell kann man solch einen Treiber nicht schreiben, aber für spezielle Geräte könnte man es dennoch, bzw. für jedes Gerät einen extra Treiber, der weiß, wie Anforderungen und Antworten zu handhaben sind und dadurch eine saubere Trennung ermöglicht.
Es gibt auch noch andere Möglichkeiten, die mir gerade einfallen. Allerdings hängen diese vom Verhalten der Programme ab.
-
So ist es, für unbekannte serielle Geräte geht es nicht. Für spezielle Geräte geht es, wenn man den Aufbau und das Handling der Byte- (Daten-)Sequenzen kennt. Da könnte es sich schon lohnen, sowas zu programmieren.
Als mögliche Anwendung fällt mir z.B. nur das AVR-Studio und der AVR-Programmer PonyProg ein, die sich beide die serielle Schnittstelle teilen und auf das selbe Gerät (die ISP-Schnittstelle des Atmel-Prozessors) zugreifen.Oder sowas in der Art für PIC-Prozessoren.
Mein ganzer Modellbau- und Modelleisenbahn-"Krempel", der Hausbus und noch ein paar Meßgeräte habe ich alle mit serieller Schnittstelle gebaut. Die sind natürlich jetzt ziemlich rar bei mir zu Hause
Da hatte ich schon die "Idee" mit den virtuellen COM-Ports.
Aber für miteinander "verwandte" Programme, z.B. verschiedene Versionen, die das gleiche serielle Gerät bedienen, könnten schon über einen (speziell für sie geschriebenen) Dienst sich dieses eine Gerät "teilen".
Blackbird