Custom Bootloader

Hallo in die Runde

Hätte mal ne Frage zum Bootloader

Der Reset soll nicht per DTR erfolgen.
Gibt es Lösungen als Bootloader, dass man per Programmcode, ihn in den Zustand zum empfangen von neuen Code setzen kann? Und das ganze mit einer Baudrate.

Meine Vorstellung wäre:
Der Arduino arbeitet nach dem Einschalten ganz normal sein Programm durch.
Dann per Serial (Baud 38400) Message "Update" den arduino in flash mode versetzen.
Daten per Serial (Baud 38400) senden, gegenprüfen und Neustart (halt wieder normal Programm)

So könnte man das ganze auch per Bluetooth durchführen (nein ich suche nicht nach einer BT-Lösung)

Grüße

Hi

Wenn das Programm selber nicht darauf achtet (warum sollte ich mich darum kümmern, daß der Bootloader aktiv wird ... ich bin User), muß der Bootloader den seriellen Verkehr mitlesen - was in der Richtung gab's doch Mal früher ... wenn Da drei Nullen (oder so eine Kombination, kA) am Stück kamen, war's aus mit dem Arduino - also Reset.

MfG

Kann deiner Antwort nicht ganz folgen. Warum sollte der Bootloader die ganze Zeit mitlesen?
Was meinst du mit Programm und User?

Hatte mal was gelesen, dass drei Ausrufezeichen im Programmcode den Arduino beim upload resettet haben.

Ja, das gab (gibt???) es. !!! und nix ging mehr. Das musste aber schon im Compilat vorhanden sein, nicht erst in der Übertragung auf Serial.

Gruß Tommy

Hi

Wenn der Bootloader auf eine Nachricht reagieren soll, muß Dieser mitlesen.
Sonst bekommt Der davon nämlich Nichts mit.
Ok, man könnte in einer neuen Version der IDE in SERIAL einen Sniffer integrieren, Der bei '1elf11einsUpdateImAnmarsch' den Bootloader anspringt - der 08/15-Arduino-Benutzer wird dem Bootloader nämlich nicht vorlesen, was Da gekommen ist und Bescheid geben, daß Er Jetzt ein Update einlesen soll.

Deshalb gibt's das Reset, Wartezeit für Ankündigung eines Upload, Wenn Ja -> Zeug saugen und brennen, dann (und wenn Nein) Start des enthaltenen Programm.

MfG

ah ok. vermutlich denke ich falsch oder erkläre es schlecht.

  1. im loop liest mein programm von serial bereits. muss der bootloader zusätzlich mitlesen?
  2. ich kann im loop doch dann ein flag setzen (kann der bootloader vom eeprom lesen) und einen reset machen.
  3. wenn der bootloader dann das flag erkennt, dann eine gewisse zeit warten, um code zum brennen zu empfangen. flag in jedem fall zurücksetzen.
  4. wenn das flag nicht direkt zur applikation springen.

ist das so möglich?
geht das mit einer baud 38400? weil der nano 115200/57600 nimmt

bin da leider im thema bootloader gar nicht drin, deswegen so stümperhafte fragen.

muss der bootloader zusätzlich mitlesen?

Das ist doch unmöglich!
Entweder läuft die Anwendung oder der Bootloader.
Aber nie beide gleichzeitig.

combie:
Das ist doch unmöglich!
Entweder läuft die Anwendung oder der Bootloader.
Aber nie beide gleichzeitig.

OK das passt ja.
So stellte ich mir das auch vor.
Die Antwort von postmaster-ino hat mich da etwas verwirrt.

harryberlin:
bin da leider im thema bootloader gar nicht drin, deswegen so stümperhafte fragen.

Bist Du denn überhaupt in der Lage, den Bootloader nach Deinen Wünschen zu verändern? Verstehst Du den Quellcode? Kannst Du den veränderten Quellcode zum Harryloader compilieren?

Die für mich zentrale Frage: Warum willst Du Dir das antun?

Der Bootloader soll dioe Programmentwicklung vereinfachen, ist sonst aber bedeutungslos. Beispielsweise entwickle ich eine LED-Animation auf dem UNO, da ist der Bootloader praktisch. Dann bin ich fertig, schiebe das Programm auf einen ProMini (gleicher µC, kein USB) und hänge alles in die Bar. Weil es mich nicht stört, bleibt der Bootloader drin, brauchen tue ich ihn aber nicht, könnte auch raus.

Ich unterscheide also zwischen Entwicklungsphase gerne mit Bootloader und Anwendungsphase, wo es gut ohne geht.

Nein, ich blicke beim Bootloader nicht ganz durch. Gibts ne Doku dazu?
Kann mir Jemand helfen?

Ich möchte mit meinem Modul in der Lage sein ein Update per Serial ohne DTR Leitung durchzuführen. Später vllt. auch mal per Bluetooth (HC-05 o.ä.).

Wie ich das ganze compiliere habe ich auch noch nicht weiter bedacht.

Hier findest du den Optiboot

  1. Interpretation Reset über DTR unterbinden:

Auf dem Arduino haben wir mal den Controller den wir programmieren (ATmega168, ATmega328, ATmega1280 oder ATMGA2560) wo auch der Bootloader drauf ist und einen USB-Serial Adapter (je nach Version und Clon) eine FT232, CH340 oder einen programmierten ATmega8U2 oder ATmega16U2.

Der USB-Serial Adapter erkennt ein Resetansuchen des PC zum Uploaden und resetiert über seinen DTR-Ausgang den (hardwaresignal) ATmega168, ATmega328, ATmega1280 oder ATMGA2560. Nach dem Reset wird der Bootloader abgearbeitet und einen neuen Sketch hochgeladen oder auf den vorhandenen, geladenen Sketch gesprungen. Sobald der gespeicherte Sketch ausgeführt wird hat der Bootloader keinen Einfluß mehr da er nicht mehr angesprungen wird.

Einzige Möglichkeit einen Reset über USB zu unterbinden ist die Verbindung von DTR zu Reset zu unterbrechen. Dann ist ein Upload des Sketches nur durch manuelles Betätigen des Resettasters möglich.

Es ist möglich den Bootloader zu löschen und einzig den Sketch auf den Controller zu haben in diesem Fall startet der Sketch sofort nach einem Reset. Der Upload funktioniert nur mehr über einen ISP-Programmierer.

Bei Arduinos mit dem ATmega32U4 sieht die Sache anders aus, da dieser selbst eine USB-Schnittstelle hat und somit softwaremäßig resetiert wird. Der Sketch enthält die Unterstützung der USB-Schnittstelle und somit auch den Bootloader. Um einen Reset zu verhindern müßtest Du die Programmierung der USB-Schnittstelle ändern.

  1. Interppretation:
    Upload außer über Reset auch über andere Modalität:

Meine Vorstellung wäre:
Der Arduino arbeitet nach dem Einschalten ganz normal sein Programm durch.
Dann per Serial (Baud 38400) Message "Update" den arduino in flash mode versetzen.
Daten per Serial (Baud 38400) senden, gegenprüfen und Neustart (halt wieder normal Programm)

Da braucht es nicht nur auf dem Arduino eine andere Firmware des USB-Adapters, sondern auch eine modifizierte IDE, die den Upload nach Deinen Wünschen macht.

Grüße Uwe

Danke für die vielen Infos.

Also DTR kann ich trennen, das ist nicht das Thema. Bzw. mit nen HC-05 gibts das ja(ohne mod) eh nicht.
In der IDE brauche ich es nicht unbedingt.
Kompilierung des sketches in der IDE und upload mit avrdude ist machbar.

Eine Frage zum optiboot. Ist es richtig, dass dieser von haus aus verwendet wird (speziell der nano & mega2560)? Also ich rede nicht vom oldBootloader.

Eine Frage zum optiboot. Ist es richtig, dass dieser von haus aus verwendet wird (speziell der nano & mega2560)? Also ich rede nicht vom oldBootloader.

Das kannst du selber herausfinden, wenn du deine Board Definitionen untersuchst.

Also mal ein kleiner Zwischenstand:
Komilierung des standard optiboot: CHECK
Upload mit eXtreme Burner: CHECK
Upload des sketches (.hex) mit avrdude: CHECK
Anpassung Baudrate und Komplilierung: TODO
Upload mit neuer Baudrate: TODO

Suche mal in einer der boards.txt nach uno.upload.speed=115200

kompilierung mit custom baudrate war ganz easy:

make atmega328 -e BAUD_RATE=38400

upload mit avrdude ebenfalls (mache ich mit cmd file unter windows):

set serialport=COM4
set baudrate=38400
set hexfile="NANO.hex"
%~dp0avrdude -p m328p -c arduino -b %baudrate% -P \\.\%serialport% -D -U "flash:w:%hexfile%:i"

zum test für eeprom schreiben habe ich einfach mal in der main irgendwo diese zeile eingefügt

eeprom_write_byte((unsigned char *)0x02, 222);

dann gab es das problem, dass die hex wohl nicht mehr auf flash passte, bzw. es gabe eine fehlermeldung
"section .version loaded at [00007ffe,00007fff] overlaps section .text loaded at [00007e00,0000805d]"

also musste ich in den Makefile die werte anpassen. ich war mal recht großzügig und habe die

atmega328: LDSECTIONS  = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe

zu

atmega328: LDSECTIONS  = -Wl,--section-start=.text=0x7a00 -Wl,--section-start=.version=0x7ffe

geändert.

und siehe da, der eeprom wird umgeschrieben. :slight_smile:
jetzt kommt der schwerste teil, ich muss verstehen, wo die abfrage ist, ob er in den bootloader springt oder den sketch startet.

Hab es hinbekommen :slight_smile:
Nach dem flashen des kompletten sketches inkl. custom bootloader der sketch gestartet wird.
Mein Sketch kann einen string per serial empfangen, dabei wird ein byte im eeprom umgeschrieben und ein reset durchgeführt.
Der Bootloader liest das byte und überspringt den Sketch.
Wenn das Flashen abgeschlossen ist, wird das byte zurückgesetzt.
Ein flashen per serial ohne update flag ist nicht möglich, weil der Bootloader verlassen wird.

function im sketch:

#include <avr/wdt.h>
void update(){
  EEPROM.update(UPDATEFLAG, 0);
  wdt_enable(WDTO_30MS);
    while(1) {};
}

anpassung in optiboot zum starten des sketches und verlassen der main:

...
  // Skip all logic and run bootloader if MCUSR is cleared (application request)
  if (eeprom_read_byte((unsigned char *)UPDATEFLAG)) { // <-- custom mod
      /*
       * To run the boot loader, External Reset Flag must be set.
       * If not, we could make shortcut and jump directly to application code.
...
...
  if (eeprom_read_byte((unsigned char *)UPDATEFLAG)) return 0; // <-- custom mod
  // Set up watchdog to trigger after 1s
  watchdogConfig(WATCHDOG_1S);
...

zurücksetzen des flags nach dem flashen:

...
   else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
      // Adaboot no-wait mod
      eeprom_write_byte((unsigned char *)UPDATEFLAG, 0xFF); // <-- custom mod
      watchdogConfig(WATCHDOG_16MS);
...

cmd batchfile für avrdude mit hilfe von SerialSend.exe:

set serialport=7
set baudrate=38400
set hexfile="myfile.hex"
SerialSend.exe /devnum %serialport% /baudrate %baudrate% /hex "\ndoupdate\n"
%~dp0avrdude -p m328p -c arduino -b %baudrate% -P \\.\COM%serialport% -D -U "flash:w:%hexfile%:i"
pause

Hoffe ich habe nix vergessen.

Kann ja später mal ein diff file erstellen.
Was haltet ihr davon?
Sonstige Hinweise, Wünsche, Anregungen?
Gibt es vllt. bessere Lösungen, als ein byte im eeprom umzuschreiben?
Bluetooth-Test steht noch aus.

upload per bluetooth vom smartphone per HC-05 funktioniert auch. ich muss halt vorher das updatebyte setzen.

nachteil ist, wenn man ein hex drauf zieht, welches das updatebyte nicht setzen kann, wird man den nur noch per isp zurücksetzen können.