Hi, ich implementiere gerade RTS/CTS Handshake auf einem Controller. Bei meinen HowTo-Recherchen bin ich auf zwei unterschiedliche Implementierungen gestoßen: 1) Ein Teilnehmer signalisiert durch RTS, dass Daten gesendet werden (wollen). Die Gegenstelle signaliert durch RTS, dass sie für den Empfang bereit ist. 2) Ein Teilnehmer signalisiert durch RTS, dass Daten angenommen werden können. Bisher kannte ich eigentlich nur Variante 2, die ich auch gerade zu implementieren versuche. Sollte ja soweit passen, denke ich. Für einen einfachen Test habe ich RTS/CTS der Controllerschaltung miteinander verbunden, wie man es auch bei den einfachen Kabeln am PC sieht. Der Handshake bedient sich also lokal selbst. Über den PC sende ich ohne Handshake Daten zum Controller. Dieser sendet die Daten postwendend zurück, also quasi reines Echo. Wähle ich nun eine Baudrate aus, die so schnell ist, dass der Controller die Daten nicht schnell genug umschaufeln kann, bedient er auch entsprechend RTS. So, mein Problem ist nun folgendes: Der Controller sendet nur, wenn CTS aktiv ist. Da er aber RTS deaktiviert hat, wird nicht mehr gesendet. Die Funktion, die die Daten aus dem Empfangs- in den Sendebuffer schiebt bleibt somit hängen, wenn der Sendebuffer voll ist. Somit komme ich gar nicht dazu, den Empfangsbuffer zu leeren, um RTS wieder zu aktivieren. Quasi Henne-Ei-Problem. Leider habe ich bei meiner Suche kein FlowChart oder ähnliches gefunden, was eine 'ordentliche' Handshake-Implementierung beschreibt. Falls also jemand etwas in der Hinsicht kennt, wäre ein Hinweis nett. Dann wär da noch die Frage, ob mein Test und die Implementierung überhaupt stimmig sind: Erstens wär die Frage, ob ich mit dem Senden aufhören soll, sobald CTS deaktiviert ist, oder stattdessen einfach nichts mehr in den Sendebuffer eintragen, wenn CTS deaktiviert ist, den Sendebuffer aber trotzdem noch rauspusten (so macht es glaube ich der PC). Momentan habe ich ersteres implementiert. Zweitens kam mir die Überlegung, dass ich evtl. nicht einfach aus dem Empfangsbuffer in den Sendebuffer schieben darf, sondern für diesen speziellen Test eben auch einen Zwischenbuffer anlegen müsste, um einen Deadlock zu vermeiden. Die Implementierung selbst ist wie folgt: - Ringbuffer für Senden und Empfangen, funktioniert ohne Handshake - Die Funktion für das Schreiben eines Bytes prüft, ob Platz im Sendebuffer ist, wenn nicht, wird gewartet (deadlock?) - Der Empfangsinterrupt bedient RTS, wenn eine bestimmte Anzahl an Bytes im Buffer überschritten ist - Die Funktion für das Auslesen des Empfangsbuffer bedient RTS, wenn die o.g. Anzahl unterschritten wird - Der Sendeinterrupt sendet das nächste Byte aus dem Buffer nur, wenn CTS aktiv ist - Solange gesendet wird, ist ein Flag gesetzt, dieses wird gelöscht, wenn keine Bytes mehr im Buffer sind oder der Sendeinterrupt eine inaktives CTS feststellt - Das CTS-Signal wird mit einem externen Interrupt ausgewertet, wechselt CTS zum aktiven Zustand und ist das o.g. Flag nicht gesetzt, wird der Sendeinterrupt ausgelöst, dieser prüft dann, ob Bytes zum Senden vorhanden sind und agiert entsprechend Ich würde mich freuen, wenn mir jemand sagen kann, ob ich wenigstens einigermaßen auf'm richtigen Weg bin. Ralf
Ralf schrieb: > 1) Ein Teilnehmer signalisiert durch RTS, dass Daten gesendet werden > (wollen). Die Gegenstelle signaliert durch RTS, dass sie für den Empfang > bereit ist. > > 2) Ein Teilnehmer signalisiert durch RTS, dass Daten angenommen werden > können. > > Bisher kannte ich eigentlich nur Variante 2, die ich auch gerade zu > implementieren versuche. Sollte ja soweit passen, denke ich. Beides nicht. RTS Request to send (ich will senden, sachma) CTS Clear to send (also schick mal)
Ralf schrieb: > 1) Ein Teilnehmer signalisiert durch RTS, dass Daten gesendet werden > (wollen). Die Gegenstelle signaliert durch RTS, dass sie für den Empfang > bereit ist. Als simple Modems üblich waren, signalisierte das Endgerät (DTE = data terminal equipment) dem Modem per RTS, dass es senden will, und das Modem (DCE = data communication equipment) antwortete mit CTS, wenn es das darf. Das war insbesondere bei Halbduplex-Verfahren für die Richtungsumschaltung wichtig. Mit dem heutigen RTS/CTS-Handshake zur Drosselung der Übertragung hat das nichts zu tun, ist aber der Grund für den Namen "RTS". > 2) Ein Teilnehmer signalisiert durch RTS, dass Daten angenommen werden > können. Das ist der RTS/CTS Handshake. Man hätte statt RTS auch DTR (data terminal ready) verwenden können, um den irritierenden Widerspruch zum Namen zu vermeiden. Bei Druckern hat man das auch so gemacht. Bei Computer-Terminals aber nicht, und daher stammt diese Methode.
RS232 stammt aus der Modem-Zeit. An diesen (DCE) ist RTS ein Eingang. Solche Endgeräte die über nicht gekreuzte Kabel mit dem PC verbunden werden sind aber inzwischen unüblich könnten aber Ursache deiner Verwirrung sein. Ein Moden ist immer übertragungsbereit, es signalisiert mit CTS (Erinnerung: Ist dort ein Ausgang,verbunden mit dem Eingang CTS am PC) nicht dass es selbst bereit ist (das tut es durch DSR, am Modem ein Ausgang, verbundem mit dem Eingang DSR am PC und aktiviert nach dem der PC durch seinen Ausgang DTR dem Modem mit dessen Eingang DSR gesagt hat dass es sich einschalten soll), sondern dass die Gegenseite bereit ist. Beim Modem passiert das überkreuzen also auf der Telefonleitung. Ohne Modem bei PC/PC Direktverbindung sind immer unterschiedlich lautende Pins verbunden, RTS-CTS. Wenn derAusgang RTS dem Eingang CTS sagt dass nicht mehr gesendet werden soll, muss das aktuelle Byte trotzdem noch gesendet wrrden, nicht mittendrin abbrechen.
Ralf schrieb: > Dann wär da noch die Frage, ob mein Test und die Implementierung > überhaupt stimmig sind: Erstens wär die Frage, ob ich mit dem Senden > aufhören soll, sobald CTS deaktiviert ist, oder stattdessen einfach > nichts mehr in den Sendebuffer eintragen, wenn CTS deaktiviert ist, den > Sendebuffer aber trotzdem noch rauspusten (so macht es glaube ich der > PC). Der sicherste und verbreitetste Weg ist, direkt das Senden zu unterbinden. Bei PCs mit USB/Seriell-Konverter ist das aber nur dem USB-Konverter möglich, der PC-Software ist das aufgrund des recht happigen Puffers dazwischen nicht möglich. Das muss folglich dem Treiber und damit dem Konverter mitgeteilt werden.
MaWin schrieb: > Wenn derAusgang RTS dem Eingang CTS > sagt dass nicht mehr gesendet werden soll, muss das aktuelle Byte > trotzdem noch gesendet wrrden, nicht mittendrin abbrechen. Das ist totaler Blödsinn, das sollte man schon merken wenn man bloss etwas Englisch kann. RTS heisst ich möchte senden, CTS heisst du darfst senden. Also setzt der PC RTS, wenn er was senden möchte, tut das aber erst, wenn das angeschlossene Gerät, z.B. ein Modem, mit CTS signalisiert, dass es dazu bereit ist, die Daten zu übernehmen. Joachims Antwort "Beides nicht" war also korrekt, die übrigen sinnloses Geplapper von Leuten die nicht den Schatten einer Ahnung haben. Gruss Reinhard
Früher hatten RTS und CTS mal diese Bedeutung. Heute üblich ist RTS mit CTS der Gegenstelle zu verbinden und dann darüber zu signalisieren, ob noch Daten empfangen werden können. Das wird dann Symmetrisch in beide Richtungen gemacht. So macht das sowohl Windows als auch Linux.
Guten Morgen zusammen, vielen Dank für eure Antworten. @Joachim Drechsel: > Beides nicht. > RTS Request to send (ich will senden, sachma) > CTS Clear to send (also schick mal) Eigentlich dachte ich, eben genau dieses in meiner Variante 1) beschrieben zu haben (allerdings auf RTS beider Teilnehmer bezogen) @A.K.: Danke für die Erläuterung, dieser entnehme ich, dass 2) heute wohl üblicher ist, zumal mein Controller in dem Sinne ja kein DCE ist. @MaWin: > Ohne Modem bei PC/PC Direktverbindung sind immer unterschiedlich > lautende Pins verbunden, RTS-CTS. Wenn derAusgang RTS dem Eingang CTS > sagt dass nicht mehr gesendet werden soll, muss das aktuelle Byte > trotzdem noch gesendet wrrden, nicht mittendrin abbrechen. Klar, ein bereits im UART befindliches Byte kann man eh nicht mehr stoppen (ausser vielleicht Portpin hart auf GND setzen). Das "aktuelle Byte" ist dann wirklich nur noch das aktuelle Byte (so hab ich's aktuell implementiert), oder der aktuelle Inhalt des Sendebuffers des UARTs(nicht vom Buffer von Windows, einem Schnittstellenobjekt oder sonstwas)? Ich frag deswegen, weil man ja die Schwelle für das Deaktivieren von RTS immer ein paar Bytes unterhalb der eigentlich Buffergröße ansetzen soll, da angeblich trotz deaktiviertem RTS immer noch ein paar Bytes reintröpfeln könnten... @Reinhard: > Das ist totaler Blödsinn, das sollte man schon merken wenn man bloss > etwas Englisch kann. RTS heisst ich möchte senden, CTS heisst du darfst > senden. Also setzt der PC RTS, wenn er was senden möchte, tut das aber > erst, wenn das angeschlossene Gerät, z.B. ein Modem, mit CTS > signalisiert, dass es dazu bereit ist, die Daten zu übernehmen. Wird es denn heutzutage auch wirklich noch so gehandhabt? :) Die Signalnamen, die vor zehn, zwanzig, dreissig oder was weiss ich wie vielen Jahren für den damaligen Zweck verwendet wurden müssen heute nicht mehr unbedingt etwas mit ihrer tatsächlichen Arbeitsweise zu tun haben... Ich weiss leider nicht, ob die Option 'Hardware-Handshake' eine BIOS Funktion ist, dann würde sich jeder Rechner nahezu gleich verhalten. Wenn nicht, dann ist es Sache des OS oder gar nur der jeweiligen Software, welche die Schnittstelle grad im Zugriff hat... > Joachims Antwort "Beides nicht" war also korrekt, die übrigen sinnloses > Geplapper von Leuten die nicht den Schatten einer Ahnung haben. Warum so gereizt? Aber abgesehen davon, es könnte auch einfach sein, dass die o.g. Antworten einfach daher kommen, dass den Leuten eben nur die jeweiligen Funktionsweisen begegnet sind. @Daniel: > Früher hatten RTS und CTS mal diese Bedeutung. > Heute üblich ist RTS mit CTS der Gegenstelle zu verbinden und dann > darüber zu signalisieren, ob noch Daten empfangen werden können. Das > wird dann Symmetrisch in beide Richtungen gemacht. So macht das sowohl > Windows als auch Linux. So in etwa kenne ich das auch. Jetzt muss ich aber noch herausfinden, wie ich das Henne-Ei-Problem lösen kann. @Alle: Nochmals besten Dank für alle bisherigen Antworten. Nach wie vor ist jetzt aber immer noch die Frage nach der nicht funktionierenden Selbstfreischaltung offen. Alle weiteren dienlichen Infos sind natürlich auch willkommen :) Ralf
Ralf schrieb: > Ich frag deswegen, weil man ja die Schwelle für das Deaktivieren von RTS > immer ein paar Bytes unterhalb der eigentlich Buffergröße ansetzen soll, > da angeblich trotz deaktiviertem RTS immer noch ein paar Bytes > reintröpfeln könnten... So ist es. Die Hardware einer klassischen seriellen Schnittstelle hat einen Puffer und wenn diese Hardware nicht selbst schon eine Kopplung mit RTS vorsieht, dann will der Inhalt des Puffers trotzdem raus. Simple UARTs eines µC mit nur einem Byte Puffer senden also ggf. 2 Bytes bevor sie Ruhe geben.
So wie ich es kenne (also nicht die alte Arbeitsweise) sind die Leitungen in beide Richtungen erstmal auf Kommunikation erlauben. Dann sendet ein Teilnehmer z.b ein paar Daten aber an RTS/CTS ändert sich nichts. Erst wenn bei einem Partner die Puffer voll sind, dann wird dieser seinen RTS Ausgang auf "Stop" stellen. Dann muss der Gegner aufhören zu senden. Das stellt er fest in dem er seinen CTS-Eingang überwacht welcher ja mit dem RTS des Empfängers verbunden ist. Sind die Puffer wieder frei, wird RTS wieder freigegeben und der Sender darf weitersenden. Die Kommunikation zwischen µCs läuft byteorientiert ab. Das meint, das wenn die Leitung gezogen wird, wird das aktuelle Byte noch gesendet, danach darf aber nichts mehr kommen (Pufferfüllstand 100%). Das macht dann die DMA, bzw. Hardware selbsttätig. Mache Implemtationen sind sogar so aufgebaut, dass die RTS Leitung gezogen wird nachdem das Byte komplett empfangen wurde und losgelassen wird sobald das Byte aus der Schnittstelle gelesen wird (z.b. im Interrupt). D.h. das nach jeden Byte ein kurzer Spike auf RTS gemessen werden kann. Das Problem sind PC-Schnittstellen. Hier können nach dem per RTS ein Stop signalisiert wurde noch einige Bytes nach kommen. Bei meinem aktuellen Rechner und 115200 sind das 9 bis 10 Bytes bevor der aufhört Daten zu senden. Deswegen muss man auf Controller-Ebene seinen Pufferfüllstand auswerten und ab einem bestimmtem Füllstand (z.b. 75%) schon die RTS-Leitung ziehen.
Ralf schrieb: > Das "aktuelle Byte" ist dann wirklich nur noch das aktuelle Byte (so hab > ich's aktuell implementiert), oder der aktuelle Inhalt des Sendebuffers > des UARTs(nicht vom Buffer von Windows, einem Schnittstellenobjekt oder > sonstwas)? > Ich frag deswegen, weil man ja die Schwelle für das Deaktivieren von RTS > immer ein paar Bytes unterhalb der eigentlich Buffergröße ansetzen soll, > da angeblich trotz deaktiviertem RTS immer noch ein paar Bytes > reintröpfeln könnten... Du musst damit rechnen, dass dein Gegenüber nicht sofort aufhört, sondern noch ein paar Bytes kommen. Wenn der eine UART hat, die nicht, wie der AVR nur 1 Byte buffert, sondern ein paar mehr, dann kann nämlich er wiederrum nicht sofort den ganzen Vorgang stoppen. > Wird es denn heutzutage auch wirklich noch so gehandhabt? :) Was hier noch ins Spiel kommt, ist dass es 2 Arten von Kabeln gibt. gekreuzte und nicht gekreuzte Kabel. Und damit auch, ob RTS auf CTS führt oder ob RTS auf RTS führt. Ja ich weiß, das alles ist ein ziemliches durcheinander. > vielen Jahren für den damaligen Zweck verwendet wurden müssen heute > nicht mehr unbedingt etwas mit ihrer tatsächlichen Arbeitsweise zu tun > haben... Doch, denn am Funktionsprinzip hat sich ja nichts geändert. Der ganze Pallawatsch entstand dadurch, dass man am Anfang keine direkten Computer zu Computer Verbindungen hatte, sondern zwischen 2 Computer 2 Modems hatte, die mit einem 1:1 Kabel an die Computer angebunden wurden. D.h. die Verbindung Sendeleitung-Empfängerleitung wurde vom Modem 'gekreuzt'. Als man dann dazu überging Rechner direkt miteinander zu verbinden, legte man diese Kreuzung naheliegenderweise ins Kabel. Aber am Funktionsprinzip hatte sich nichts geändert. Konnte auch nicht, denn es wurden ja nach wie vor dieselben Endgeräte mit denselben Schnittstellen und dem selben Handshake-Funktionsprinzip verwendet. > So in etwa kenne ich das auch. Jetzt muss ich aber noch herausfinden, > wie ich das Henne-Ei-Problem lösen kann. Welches Henne/Ei Problem? > Nochmals besten Dank für alle bisherigen Antworten. Nach wie vor ist > jetzt aber immer noch die Frage nach der nicht funktionierenden > Selbstfreischaltung offen. Alle weiteren dienlichen Infos sind natürlich > auch willkommen :) Es läuft praktisch gesehen auf diese Strategie hinaus Ehe ein Byte gesendet wird, wird der Zustand des CTS-Eingangs überprüft. Ist der OK, dann darfst du das Byte wegschicken. Umgekehrt: empfängst du ein Byte, dann schaust du dir den Füllgrad deines Buffers an und entscheidest, ob du deinen eigenen RTS-Ausgang zurücknehmen musst. Mit Abarbeitung des Buffers kann der dann irgendwann wieder freigegeben werden. Im Grunde kannst du so vorgehen: RTS hat seine Bedeutung verloren. Der Sender fragt nicht mehr wortwörtlich an, ob er senden darf. Sondern das Gegenüber signalisiert mit seinem RTS-Ausgang dem Sender (der dieses Signal an seinem CTS bekommt), ob er aufnahmebereit ist. Und da das natürlich wechselseitig so sein muss, muss es logischerweise auch 2 Leitungen dafür geben. Heutzutage ist die Bezeichnung RTS irreführend. Besser wäre es RTR (Ready to Receive) zu nennen, mit der das jeweilige Gerät signalisiert, ob es aufnahmebreit ist oder nicht.
:
Wiederhergestellt durch User
@ Karl Heinz Buchegger CTS ist der Eingang, RTS der Ausgang, so stehts in den Datenblättern der Controller die ich kenne, also so als wären sie PCs und keine Modems. UPDATE: du hast es schon korrigiert
Rangi Jones schrieb: > @ Karl Heinz Buchegger > CTS ist der Eingang, RTS der Ausgang, so stehts in den Datenblättern der > Controller die ich kenne, also so als wären sie PCs und keine Modems. Sag ich doch :-) (Ne, du hast schon recht. Ich hab beim Korrekturlesen nach dem Posten gemerkt, dass ich mitten drinn auch durcheinander gekommen bin und habs nachträglich korrigiert. Es ist eben ein Durcheinander mit den Bezeichnungen. Genauso, wie es ein Durcheinander gibt, wer jetzt eine Buchse haben sollte und wer einen Stecker.
Ich finde, mit dem Bild (aus dem AVR-Tutorial:Uart) ist am besten ausgesagt, wer wem was zu signalisieren hat.
Regel 1 beim Verbinden der Schnittstellen: einfach verbinden, du hast 50% Gewinnchance. Denn wenn du eine Stunde drauf verwendest es herauszufinden ärgerst du sich am Ende doch nur weil es trotzdem falsch war.
Karl Heinz Buchegger schrieb: > Ich finde, mit dem Bild (aus dem AVR-Tutorial:Uart) ist am besten > ausgesagt, wer wem was zu signalisieren hat. Auch, wenn es aus einem Tutorial ist, muss es nicht ganz richtig sein. RTS und CTS gehören zusammen. Der eine Teilnehmer (PC als Beispiel) sagt dem anderen (Modem als Beispiel) per RTS, das er senden möchte. Das Modem unternimmt alles notwendige, um diesen Wunsch erfüllen zu können. Wenn es bereit ist, gibt es mit CTS die Datenübertragung frei. Wenn es dann zwischendurch Probleme gibt, kann das Modem CTS wegnehmen und damit die Übertragung stoppen. Wie viele Bytes dann noch nachtröpfeln können, ist nicht definiert. Man sollte aber auf bis zu 16 eingestellt sein. Uralte UARTs hatten den Handshake per Hardware eingebaut. Da kam noch maximal ein Byte. Für die Gegenrichtung gibt es drei Signale. Mit DCD sagt das Modem dem PC, dass ein Empfang unmittelbar bevorsteht (Data Carrier Detected). Ob und wie der PC reagiert, ist ihm selbst überlassen. Wenn dann tatsächlich Daten bereit sind, aktiviert das Modem DSR und der PC erlaubt die Übertragung mit DTR. Der PC kann jederzeit die Übertragung stoppen, indem er DTR deaktiviert. Unter Windows gibt es Fälle, bei denen der PC scheinbar nichts empfängt. Ursache ist dann oft, dass DSR und DCD nicht aktiv sind. Bei Wikipedia findet man unter "nullmodem" einen recht guten Artikel.
Georg G. schrieb: > Auch, wenn es aus einem Tutorial ist, muss es nicht ganz richtig sein. Das Tutorial bezieht sich nicht auf Modems, sondern auf Kommunikation zwischen PC und Controller. RTS wird heute nicht mehr so verwendet, wie es bei Modems üblich war. Sondern so, wie es bei DEC VT100 Terminals an VAXen üblich war. CTS hat dabei seine Bedeutung ungefähr behalten, RTS aber nicht.
@Rangi: Danke für die Erläuterung. So kenne ich das auch. @Karl Heinz: > Du musst damit rechnen, dass dein Gegenüber nicht sofort aufhört, > ... > Was hier noch ins Spiel kommt, ... > ... > Doch, denn am Funktionsprinzip hat sich ja nichts geändert. Danke für die Erläuterung. > Welches Henne/Ei Problem? Wie oben beschrieben: RTS/CTS lokal verbunden, vom Rechner kommen Daten und werden direkt wieder zurückgeschickt. Ist die Baudrate so hoch, dass der Controller nicht mehr hinterher kommt, deaktiviert er wie gewünscht RTS, allerdings sperrt er damit einerseits das Senden des (ebenfalls vollen) Sendebuffers, und zweitens bleibt er momentan in der Abfrage, ob Platz im Sendebuffer vorhanden ist, hängen. Das war der Grund für die Frage, ob ich den Test überhaupt richtig durchführe. > Es läuft praktisch gesehen auf diese Strategie hinaus > Ehe ein Byte gesendet wird, wird der Zustand des CTS-Eingangs überprüft. > Ist der OK, dann darfst du das Byte wegschicken. > Umgekehrt: empfängst du ein Byte, dann schaust du dir den Füllgrad > deines Buffers an und entscheidest, ob du deinen eigenen RTS-Ausgang > zurücknehmen musst. Mit Abarbeitung des Buffers kann der dann irgendwann > wieder freigegeben werden. Genauso mache ich das auch. Nur ist eben noch n Deadlock drin, den ich gerne lösen würde. @Georg: > Bei Wikipedia findet man unter "nullmodem" einen recht guten Artikel. Danke, ich schau gleich mal rein. @A.K.: > Das Tutorial bezieht sich nicht auf Modems, sondern auf Kommunikation > zwischen PC und Controller. Aus dem Grund verwende ich die eingangs erwähnte Variante 2 - oder versuche es zumindest :) Ralf
Ich weiss ja nicht mit welcher Hardware du programmierst, aber du musst das Empfangen bzw. Senden von Byte aus dem Puffer programmtechnisch trennen von der Weiterverarbeitung der Daten. Am einfachsten geht das im Interrupt. Hier werden Daten aus dem Tx-Puffer gesendet wenn da welche sind, bzw empfangen und im Empfangsbuffer abgelegt. Bei der gelegenheit kannst du prüfen wieviel noch Platz ist und ggf. das RTS ansteuern. Ausserhalb der ISR, also im Hauptprogramm liesst du dann die Daten aus dem Rx-Puffer, gibst damit wieder Platz frei. Jetzt kann du beim Auslesen nachschauen ob in der ISR zuvor das RTS gesetzt wurde und ob jetzt nach dem auslesen wieder genügend Platz vorhanden ist. Dann gibst du RTS wieder frei. Beim Senden wird im Interrupt nur dann gesendet wenn CTS als frei angezeigt wird. Andernfalls wird der Interrupt abgeschaltet. Um jetzt mitzubekommen das der andere wieder Daten haben möchte musst du zyklisch das CTS pollen oder gleich eine Port-Pin-Interrupt verwenden, der dich informiert wann die CTS-Leitung wieder frei anzeigt. Hier kannst du dann einfach den Tx-Interrupt wieder anschalten. Mit DMA wird das ganze etwas komplexer, für die Erklärung isses mir einfach zu warm.
@Rangi: > Ich weiss ja nicht mit welcher Hardware du programmierst, aber du musst > das Empfangen bzw. Senden von Byte aus dem Puffer programmtechnisch > trennen von der Weiterverarbeitung der Daten. Das habe ich. Empfangsinterrupt -> Empfangsbuffer -> Empfangsroutine sowie Senderoutine -> Sendebuffer -> Sendeinterrupt. Die Empfangs- und Senderoutine arbeiten unabhängig voneinander, sie sind in diesem Fall wirklich nur über das Testprogramm verbunden, indem das, was aus dem Empfangsbuffer gelesen wird in den Sendebuffer geschrieben wird. > Am einfachsten geht das im Interrupt. Hier werden Daten aus dem > Tx-Puffer gesendet wenn da welche sind, bzw empfangen und im > Empfangsbuffer abgelegt. Bei der gelegenheit kannst du prüfen wieviel > noch Platz ist und ggf. das RTS ansteuern. Genauso macht das die gegenwärtige Implementierung. Wird im Empfangsinterrupt festgestellt, dass nur noch ein paar Bytes frei sind, wird RTS deaktiviert. > Ausserhalb der ISR, also im Hauptprogramm liesst du dann die Daten aus > dem Rx-Puffer, gibst damit wieder Platz frei. Jetzt kann du beim > Auslesen nachschauen ob in der ISR zuvor das RTS gesetzt wurde und ob > jetzt nach dem auslesen wieder genügend Platz vorhanden ist. Dann gibst > du RTS wieder frei. Das habe ich momentan ebenfalls so gelöst. > Beim Senden wird im Interrupt nur dann gesendet wenn CTS als frei > angezeigt wird. Andernfalls wird der Interrupt abgeschaltet. Um jetzt > mitzubekommen das der andere wieder Daten haben möchte musst du zyklisch > das CTS pollen oder gleich eine Port-Pin-Interrupt verwenden, der dich > informiert wann die CTS-Leitung wieder frei anzeigt. Hier kannst du dann > einfach den Tx-Interrupt wieder anschalten. Auch hier exakt meine Implementierung. > Mit DMA wird das ganze etwas komplexer, für die Erklärung isses mir > einfach zu warm. Das glaub ich dir :) Und DMA kann der Controller eh nicht. Wie gesagt, ich denke, dass das direkte Zurücksenden das Problem ist, evtl. müsste ich zwischen den Empfangs- und Sendebuffer noch einen Buffer für den Test einbauen. Ralf
Ralf schrieb: Es wird Zeit, dass du deinen tatsächlichen Code herzeigst. Aussagen ala "Hab ich genau so implementiert" haben wir jede wochen mindestens 3 Stück. UNd dann stellt sich ein ums andere mal raus, dass eben irgendetwas doch nicht so implementiert ist, wie es sein soll. > Wie gesagt, ich denke, dass das direkte Zurücksenden das Problem ist, > evtl. müsste ich zwischen den Empfangs- und Sendebuffer noch einen > Buffer für den Test einbauen. Genau das sollte überhaupt kein Problem sein. Das Problem muss schon irgendwo in der Verwaltung der Sende- Empfangsbuffer und der daraus abgeleiteten RTS/CTS Verwaltung liegen.
Apropos: Wenn du 2 µC hast, die sich nur gegenseitig im weitesten Sinne ein Echo schicken .... ja, dann kannst du dich in einen RTS/CTS Deadlock manövrieren. Aber wenn einer davon ein PC mit einem Terminalprogramm ist, dann sollte das nicht vorkommen.
Irgendwie hab ich das eigentliche Problem aus den Augen verloren. Wenn du das alles implementiert hast und einen PC anschliesst, dann sendet der nicht? Verwende mal "HTerm". Da wird der Zustand der CTS-Leitung als grüne LED dargestellt. Ausserdem kannste RTS per Button einfach schalten. Da kannste schon ne Menge mit testen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.