C Autobaud erkennung?!

Janiiix3

Aktives Mitglied
28. Sep. 2013
1.333
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
Hallo,

Wie ist es möglich, dass einige Bootloader eine "Autobaud" Funktion unterstützen?
Muss man dafür nicht für jeden einzelnen Controller den Takt kennen um irgendwelche Zeiten zu messen?
Es gibt ja meistens einen Bootloader für verschiedene Controller Typen.
 
Nunja, wie geht denn das mit so'nem Bootloader via UART überhaupt?
Bei konventioneller Programmierung via SPI etc wird der Controller im Reset gehalten, und die Kommunikation läuft in irgendeiner Form synchronisiert ab.

Beim Bootloader via UART wird der Controller weder im Reset gehalten, doch handelt es sich um eine synchronisierte Verbindung (also kein USART).
Im Controller muß sich also eine Firmware befinden, die vor dem Start des eigentlichen Programmes auf etwaige Instruktionen (Bootloader) wartet, und erst nach einem Timeout das eigentliche Programm startet.

Edit:
Die PC-seitige Software könnte einfach nach dem Reset ein definiertes Byte senden. (zb 0x55). Die Controller-Firmware wartet nach einem PowerUp 'ne Zeitlang darauf. Da das Zeichen bekannt ist, kann man die Bitdauer/Bytedauer, (bezogen auf seine unbekannte Taktfrequenz) bestimmen, und daraus den Wert für das Baudratenregister ableiten.

Das ganze sollte natürlich komplexer als mit nur einem Byte gemacht werden, damit nicht grad zufällig(!) nach einem Reset irgendwas anderes am UART in den Bootloder-Modus gehen kann.

Die Firmware könnte also jetzt mit der eingestellten Baudrate irgend'ne festgelegte "Bin Da" Antwort liefern, woraufhin der PC nochmals antworten muß. Das könnte das Timeout aufheben, die Firmware wäre im "Programmiermodus" bis ein vereinbartes "Programmiermodus Ende"-Kommando kommt.
Anschließend wären etwaige Einstellungen (IRQs etc, verwendete Hardware...) in einen Grundzustand zu bringen, und die Program-Flash-Startadresse anzuspringen.
(alternativ könnte man wenn vorhanden auch den WatchDogReset auslösen)
 
Zuletzt bearbeitet:
Wie messe ich jetzt aber die Bytes? Mit einem Timer? Der Timer muss auch konfiguriert werden und es muss eine genaue Zeitbasis geschaffen werden. Das ist doch wieder Takt abhängig?
 
Indem Du die Takte zählst (bzw das den Timer machen läßt). wieviele (Mikro-)Sekunden das sind, interessiert Dich doch gar nicht. Die PC-seitige Bootloadersoftware gibt einfach eine Baudrate vor, die Firmware im AVR (Bootloader) muß darauf synchronisieren, also den passenden Wert fürs Baudratenregister ermitteln. Welcher tatsächlichen Baudrate das dann entspricht, weiß der AVR dann nicht (wenn er seinen Takt nicht kennt), aber das interessiert Dich doch eigentlich gar nicht, oder?

Oder hab ich Dein "Problem" falsch verstanden?
 
Mein Problem,

Ich möchte mich jetzt mal an das Thema Bootloader ran machen. Dieser soll unter anderem auch eine Autobaud Funktion haben. Vom PC Programm her würde ich dann mit Putty oder ähnlichem arbeiten.

Der PC gibt mir nun 9600kBaud vor... Wie Messe ich diese im Timer?
 
Ähm... 9600kBaud wären 9,6MBaud;)
Du meinst 9600Baud, oder?
Was heißt das?
Daß in einer Sekunde 9600 Bits gesendet werden könnten - oder andersrum ein Bit 1/9600 Sekunden dauert.

Ok, wie arbeitet nun der Reciever im AVR?
Der hat quasi sowas wie einen eigenen Timer, der 1zu1 auf den Systemtakt gekoppelt ist. Läuft der "Timer" über, wird die Rx gesampled. Innerhalb eines Bits sechzehn mal (im Normal-Modus) - Oversampling sozusagen. Relevant sind die Samples 8, 9 und 10, von deren Ergebnis die Mehrheitsentscheidung den tatsächlichen Wert des Bits liefert (majority rules - eigentlich sollten alle drei ja gleich sein).
Inwieweit der "Timer" bei jeder Flanke der Rx-Leitung zurückgesetzt wird (Synchronisation), ist mir nicht bekannt, zumindest beim Startbit mit Sicherheit.
Egal, wenn Du die Baudrate im AVR "einstellst", legst Du eigentlich nur die Reichweite des "Timers" fest. Der Überlaufpunkt wird ins Baudratenregister geschrieben. Wenn Deine Hochsprache das für Dich erledigt, bekommst Du davon halt nur nichts mit. Welcher Wert ist das?
naja - der "Timer" soll sechzehnmal pro Bit überlaufen, also "Bitdauer"/16. Und zwar die "Bitdauer" in Takten. Wenn der AVR die "Bitdauer" in Takten nicht kennt, mußt Du sie normalerweise ausrechnen (lassen), bei vorgegebenen 9600Baud eben 1/9600s, und das wiederum in Takte des Controllers.

ABER

Eigentlich interessiert Dich/den AVR die tatsächliche Bitdauer in Sekunden ja gar nicht. Und die Bitdauer in Takten kannst Du ja einfach messen/mitzählen (wenn Du den Inhalt des zu empfangenden Bytes kennst).
Im Idle ist Rx (vom Sender her) high (1). Das Startbit ist Low (0), dann kommen die Datenbits beginnend mit dem LSB, ggf ein Paritätsbit und das Stopbit wäre wieder High (1) und verschmilzt mit dem Idle.
Nimmt man 0x55 als Datenbyte, hätte man:
0x55 = 0b01010101, ohne Paritätsbit wäre das dann
1=Idle->0(Startbit)->1(LSB)->0(Bit1)->1(Bit2)->0(Bit3)->1(Bit4)->0(Bit5)->1(Bit6)->0(Bit7)->1(MSB)->1=Stop=Idle

Du startest also einen Timer mit Prescaler=1, und läßt den laufen.
Dann horchst Du an der Rx auf die erste fallende Flanke, kommt die, setzt Du den Timer auf null zurück.
An Rx weiter gelauscht, bei der nächsten Flanke liest Du den Timer aus, und setzt ihn zurück. Das kannst Du jetzt für alle Flanken machen und den Mittelwert bilden, Du kannst auch die Standardabweichung der Werte ermitteln, wie Du willst...
Prinzipiell hast Du schon mit dem ersten ausgelesenen Wert die Dauer eines Bits in Takten. Den Wert teilst Du also durch sechzehn, ziehst eins ab, knallst das ganze in das/die Baudratenregister, fährst den restlichen UART hoch, und meldest Dein "Communication Online" an den PC.

Noch weiter Klarheiten zu beseitigen??
 
Klingt erstmal logisch, werde es mir später anschauen.
Besten dank schon mal ;)
 
MCS Basic 52 (ein Basic Interpreter für 8051 Controller) nimmt das Space als Baud-Detector-Byte wenn die Baudrate nicht gespeichert ist.
Finally. BASIC checks external memory location 8000H to see if the baud rate information is stored. If the baud rate is stored, MCS BASIC-52 initializes the baud rate generator (the 8052AH's SPECIAL FUNCTION REGISTER--T2CON) with this information and signs on. If it isn't stored, BASIC inter- rogates the serial port input and waits for a space character to be typed.
http://www.nomad.ee/micros/bas52man/index.shtml
http://www.nomad.ee/micros/bas52man/chap1.html#1.1

Ich rate aber von sowas wie Auto-Baud ab. Lieber was definitives setzen. 9600 sind für Microcontroller häufig genug, außer man will jetzt z.B. in realtime die ADC Werte übertragen. Über 115200 sollte man aber nie gehen. Die Controller schaffen zwar auch mehr, viele UART Chips (sei es nun auf dem Mainboard oder in einem USB-zu-UART Wandler) nicht. Auch wenn sie es vorgeben zu können. Hab hier ein der angeblich bis zu 2M Baud können soll. Einstellen kann man es auch, aber die Daten sind mehr als nur fehlerhaft. Verschluckte Bytes, falsche Bits, … unbrauchbar. Könnte an dem Pegelwandler liegen der nach dem Controller geschaltet war, der kann nämlich laut Datenblatt nur max. 120000 Baud umsetzen…

Dann ist auch noch die Frage ob der Code nicht vielleicht zu groß wird für den Bootloader. Da muss man ggf. schon gut tricksen. Wobei ich mir da sicher bin dass zumindest @LotadaC oder @dino03 das hin bekommen würden. Aber… Wozu?
 
Für ein paar Stück macht es überhaupt keinen Sinn, wir machen jedoch ab und zu Projekte für den Zukunftstag.
Wenn später mal ein Fehler behoben werden soll, ist es doch deutlich einfacher die neue Software über USB zu flashen anstatt mit einem ISP oder ähnlichen, zudem hat nicht jeder solch einen Programmer.

Aber ich gebe dir absolut Recht, normalerweise braucht man sowas nicht.
 
Grade bei mehreren ist es doch wichtig. PC Seitig kannst du die Baudrate ja einstellen, Gerätetechnisch festlegen.
Wenn du nun in Batch 1 9600 einstellst und in Batch 2 19200… Tja… Dann biste selber schuld ;)

Ist so eine Sache wie "Seit wann kommt der Kuchen zum Hund?" ;)
 
In erster Linie waren mir halt nur mal Lösungsansätze wichtig, um zu wissen wie man sowas realisieren könne.

Außerdem soll da ja auch kein "schnick-schnack" rein, damit es nicht unnötig groß wird.
 
Was meinst'n Du mit zu groß, @TommyB ? Daß bei einigen Controllern SPM nur arbeitet, wenn die Instruktion in einem bestimmten Flash-Bereich (eben dem Bootloader-Bereich) steht? Dann kann man doch trotzdem den Code für den seriellen Transfer (inklusive Bauratenerkennung) woanders ablegen, und für die Flash-Operationen (Pageerase, Pagewrite, blablub) in den autorisierten Bereich hüpfen (sofern man das in Hochsprachen umsetzen kann - in ASM kein Ding). Wenn der PC ein bekanntes Byte sendet, ist die Ermittlung der Baudrate kein Thema - ein Klacks gegen das ganze andere.
  • Watchdog Starten
  • Resetquelle auswerten, wenn Watchdog, dann leere Endlosschleife
  • sonst warten bis Rx high
  • Z-Register auf 0
  • warten bis Rx low
  • Einsprungpunkt: 1 auf Z addieren(ADIW) -> 2 Takte
  • Dreimal NOP -> 3 Takte
  • nächsten Befehl überspringen, wenn Rx high (SBIS) 1 Takt (2 wenn Rx high)
  • Zurück zum Einsprungpunkt -> 2 Takte
Jeder Durchlauf der Schleife dauert 8 Takte beim Austritt braucht SBIS nur einen und der Rücksprung entfällt, aber dann ists eh egal.
Wenn nach dem Startbit die Schleife verlassen wird, steht ein achtel dar verstrichenen Takte im Z-Doppelregister. Schiebt man dieses (diese beiden) einmal nach rechts, hat man die geforderten sechzehntel, und kann sie direkt ins Baudratenregister kopieren.
 
Was meinst'n Du mit zu groß, Thomas? Daß bei einigen Controllern SPM nur arbeitet, wenn die Instruktion in einem bestimmten Flash-Bereich (eben dem Bootloader-Bereich) steht? Dann kann man doch trotzdem den Code für den seriellen Transfer (inklusive Bauratenerkennung) woanders ablegen, und für die Flash-Operationen (Pageerase, Pagewrite, blablub) in den autorisierten Bereich hüpfen (sofern man das in Hochsprachen umsetzen kann - in ASM kein Ding).
Ok, das wusste ich jetzt nicht. Dachte der Bootloader muss sich auch an seine Grenzen halten, außer natürlich für SPM/LPM. Aber ob sich das in C umsetzen lässt (zumindest so dass es auch noch verständlich ist…)

Machen würde ich das so aber nicht, weil ist aus irgendeinem Grund der Flash geschrottet, ist der Bootloader gleich mit hops. Der ist dann ja davon abhängig.
 
Ok, es gibt einige Controller, die SPM unterstützen ohne einen Extra ausgewiesenen Bootloader-Bereich zu besitzen. Da kann man also den Loader an eine beliebige Stelle im Flash packen.
Dann gibt es Controller, die diesen Bereich besitzen, und wo SPM auch nur von dort funktioniert (und die entsprechende Fuse das erlaubt). AFAIR kann dieser Bootloader-Bereich dann durch eigene Lockbits getrennt vom restlichen Flash geschützt werden, insofern isses natürlich besser, alles was zum Loader gehört dort zu haben.
P.S.: ich(!) habe weder Bootloader noch dWire etc genutzt. Ich habe nur mal zum testen beim Tiny10 RSTDSBL aktiviert und den mit HV-TPI zurückgeholt.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)