AMA0 und RS485 mit GPIO

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Guten Morgen,
    2. verusch
    Ich habe ein c-Programm geschrieben, dass Nachrichten aus einem TCP-IP-Socket auf ttyAMO schickt. An der seriellen Schnittstelle hängt ein RS485-Treiber (3485). Das nötige SenderEnable-Signal erzeuge ich mit GPIO17. Vor dem Senden Bit=1, nach dem Senden Bit=0. Das klappt auch.
    Das Problem ist, dass das Senden nicht wirklich fertig ist, wenn die Senderoutine ohne Fehler zurückkehrt. Offenbar braucht das Linux noch etwas Zeit. Daher schalte ichdas Sender-Enable erst nach einem delay mit einer aus der Anzahl der zu sendenden Zeichen errechneten Zeit aus. Auch das klappt.
    Ich suche nach einer Lösung, bei der das Errechnen der Wartezeit mit dem delay durch eine Abfrage, die das tatsächliche Ende des Sendevorgangs anzeigt, ersezt wird.

    Bei Bedarf, kann ich gern Scopbilder und Programmcode liefern.

    Hoffentlich klappt der Post diesmal
    Uli

  • [font="Tahoma, Verdana, Arial, sans-serif"]> Das Problem ist, dass das Senden nicht wirklich fertig ist, wenn die[/font]
    [font="Tahoma, Verdana, Arial, sans-serif"]> Senderoutine ohne Fehler zurückkehrt.[/font]
    [font="Tahoma, Verdana, Arial, sans-serif"]Richtig. Die Bytes werden in einen Buffer im Kernel kopiert, von wo sie dann[/font]
    [font="Tahoma, Verdana, Arial, sans-serif"]per Interrupt ausgegeben werden.[/font]

    [font="Tahoma, Verdana, Arial, sans-serif"]> Offenbar braucht das Linux noch etwas Zeit.[/font]
    [font="Tahoma, Verdana, Arial, sans-serif"]Nicht Linux, sondern der Seriell-Chip.[/font]

    [font="Tahoma, Verdana, Arial, sans-serif"]> Ich suche nach einer Lösung, bei der das Errechnen der Wartezeit mit dem delay[/font]
    [font="Tahoma, Verdana, Arial, sans-serif"]> durch eine Abfrage, die das tatsächliche Ende des Sendevorgangs anzeigt, ersezt wird.[/font]
    [font="Tahoma, Verdana, Arial, sans-serif"]Das wird sehr schwierig bis unmoeglich.[/font]

    [font="Tahoma, Verdana, Arial, sans-serif"]Vereinfacht laeuft es so:[/font]

    [font="Tahoma, Verdana, Arial, sans-serif"]Wie oben beschrieben, legt Linux die Bytes in einen Puffer. Wenn der Chip merkt,[/font]
    [font="Tahoma, Verdana, Arial, sans-serif"]dass er Daten zum Senden braucht, macht er einen Interrupt. Der Device-Driver[/font]
    [font="Tahoma, Verdana, Arial, sans-serif"]schiebt dann ein oder mehrere Bytes in den Chip und wartet auf den naechsten[/font]
    [font="Tahoma, Verdana, Arial, sans-serif"]Interrupt.[/font]

    Das Problem ist jetzt, dass man bei vielen UARTs gar nicht feststellen kann,
    wann das letzte Bit vom letzten Byte effektiv gesendet wurde. Der Chip macht
    den Interrupt schon vorher, damit die Software Zeit hat um weitere Bytes
    heranzuschaffen.

    Als erstes muss man also wissen, ob man beim UART abfragen kann, wann
    er letzte Bit des letzten Bytes geschickt hat. Wenn das nicht geht, kann man
    fast nur raten.

    Mal angenommen dass es moeglich ist, kommt das naechste Problem: der
    Code zur UART-Steuerung steckt in einem Device-Driver. Wenn der das
    nicht unterstuetzt, muss man selber einen schreiben.

    Einen Device-Driver zu schreiben ist muehsam, weil man sich mit vielen
    internen Datenstrukturen und Ablaeufen im Kernel auseinandersetzen
    muss. Und dazu kommt noch, dass auch der Chip genau richtig angesteuert
    werden will. Unter Umstaenden kommen noch weitere Einheiten im Chip
    dazu, wie Interrupt-Controller, DMAs oder aehnliches.

    In meiner Umgebung wird meist ein kleiner Mikrokontroller ein Geraet eingebaut
    der den RS485-Bus uebernimmt. So ist das Timing viel einfacher weil man dort
    nicht von vielen, vielen Layern in der Software abhaengig ist ...

  • Hallo Tell,
    danke für deine Antwort!!!!!!
    Du wirst Recht haben und das Steuern des SenderEnable-Signals aus dem RPi ist schwierig. Während meiner Testphase werde ich beim Ausrechnen des Zeitbedarf für den Sendevorgang bleiben. Wenn meine Socket/Uart-Server für meine Haustechnik fertig ist, werde ich eine Platine machen, bei der die Steuerung des SenderEnable-Signals durch einen Monoflop gemacht wird. Das mache ich an anderer Stelle mit Erfolg schon seit Jahren so. Dann brauch ich mich in der Software darum nicht mehr zu kümmern.
    Danke Uli

  • Hallo Tell,
    ich habe mir gerade die Website angesehen, die beim Klick auf Website geöffnet wird. Vermutlich ist das deine. Dabei ist mir der Hinweis auf auf einen Socketserver aufgefallen. Können wir darüber mal reden? Ich entwickle auch einen Server, der Sockets und Uart überblickt. Benutzt wird das für eine von mir erstellte Haussteuerung (Hardware und Software). Ich bin in dem Thema Socket nicht sehr erfahren und würde das gern ändern. Das ganze ist bei mir Hobby und nicht kommerziell.
    Danke
    uli

    Hoffentlich ist diese Frage in dem Forum erlaubt, ich bin Neuling.

  • Wieso sollte die Frage nicht erlaubt sein ?

    Aber vermutlich waere sie in einem neuen Thread besser aufgehoben, denn mit
    dem Titel hat das ja nichts mehr zu tun.

    Wie immer bei einem sinnvollen Projekt, gilt es erst mal die Requirements
    zu definieren:

    * Was soll ueber den Socket gehen ?
    * TCP oder UDP ?
    * Gibt es Einschraenkungen oder spezielle Anforderungen ?
    * Welche Programmiersprache soll es sein ?

    Wenn es meine Webseite war, gibt es unten auf der Seite einen Link um
    den Sourcecode herunterzuladen.

    Der Code muesste eigentlich auf Anhieb laufen. Das Socket-API hat nicht
    grundlegend geaendert und vor dem Posten hatte ich ihn probietrt.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!