Forum: Mikrocontroller und Digitale Elektronik Arduino - Software-Reboot zum Start des Bootloaders


von Hans (net_hans)


Lesenswert?

Hallo,

ich betreibe über RS485 zahlreiche Sensoren und Aktoren. Auf den Sensor- 
und Aktorboards laufen Arduino Pro Minis in der 5V - 16MHz Version. Als 
Master dient ein Raspi mit Node-RED.

Bisher habe ich Softwareaktualisierungen immer direkt über 
USB-TTL-Wandler auf die Arduinos gespielt. Seit einiger Zeit spiele ich 
aber mit der Idee, die Arduinos über RS485 zu flashen. Dazu 
experimentiere ich seit ein paar Tagen mit dem Bootloader-Tutorial hier 
von Mikrocontroller.net 
(https://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung)

Soweit funktioniert das mit dem Bootloader auch super. Aber ich muss 
immer von Extern ein Reset an den Arduino - aktuell Taster - senden, 
damit der Bootloader gestartet wird. Diesen Schritt würde ich gerne als 
Command über RS485 senden. Dazu müsste ich in meinem Arduino-Sketch nach 
erhalt des Rest-Commands einen Software-Reset einleiten.

Dazu habe ich aber nicht wirklich was im Netz gefunden. Die einzige 
halbwegs sinnvolle Lösung war, den WatchDog absichtlich mittels einer 
Schleife in den Reset zu schicken.

Gibt es da noch andere, bessere Möglichkeiten den Reset auszulösen? Oder 
kann ich im Bootloader eventuell eine Art ISR setzten, die anspringt, 
wenn über RS485 ein bestimmtes Command kommt, um so den Arduino wieder 
sauber in den Bootloader zu schicken?

Ich würde mich über Anregungen zu meinem Problem von euch freuen.
DANKE!

Grüße Hans

von Sebastian R. (sebastian_r569)


Lesenswert?

Viel mehr als Watchdog gibt es als Möglichkeit nicht.

Für einen wirklichen Hard-Reset besteht die Möglichkeit, den Reset-Pin 
mit einem anderen Pin des Controllers zu betätigen, aber dabei braucht 
es noch einen externen Resetbaustein (mindestens einen Monoflop), weil 
der Reset-Puls länger sein muss als der Pin ihn bei einem Reset erzeugen 
kann.

von Hans (net_hans)


Lesenswert?

Danke für die Antwort.

Die Hardwareerweiterung um den Reset-Pin über einen anderen Pin zu 
triggern, werde ich nur bei neuen Aktoren und Sensoren realisieren 
können. Dann probiere ich mein Glück mal mit dem Watchdog.

von Klaus S. (kseege)


Lesenswert?

Hans schrieb:
> Gibt es da noch andere, bessere Möglichkeiten den Reset auszulösen?

Man kann auch ohne Reset arbeiten. Man setzt alle Register brav auf die 
Resetzustände und springt dann an die Anfangsadresse des Bootbereichs. 
Spricht irgendwas dagegen?

Just my 2 cents

von Axel R. (axlr)


Lesenswert?

An welcher Startadresse befindet sich der Bootloader?
mit asm jmp dorthin springen ist jetzt keine echter Reset, sollte aber 
gehen.
aus 
https://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung
 void (*start)( void ) = 0x0000;

: Bearbeitet durch User
von Klaus S. (kseege)


Lesenswert?

Axel R. schrieb:
> An welcher Startadresse befindet sich der Bootloader?

An der Adresse, die der Lieferant durch Setzen der Fuses festgelegt hat. 
Nur er weiß, welchen Bootloader er wo aufgespielt hat.
Also einfach die Fuses auslesen und ins Datenblatt schauen.

Der reine Sprung zur Startdresse geht nur dann gut, wenn der 
Programmierer des Bootloaders alle benutzten Register explizit 
initialisiert hat und sich nicht darauf verläßt, das der Hardwarereset 
das bereits für ihn erledigt hat. Da Bootloader gern mal Platzprobleme 
haben, würde ich auf Nummer "Sicher" gehen.

Gruß Klaus (der soundsovielte)

: Bearbeitet durch User
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Axel R. schrieb:
> An welcher Startadresse befindet sich der Bootloader?
> mit asm jmp dorthin springen ist jetzt keine echter Reset, sollte aber
> gehen.

Um Einzelfall mag man das hinbekommen.

Das Datenblatt spricht alle Reset Ursachen an.
Ein Jump zum Bootloader gehört nicht dazu.
Also nein!

Der Watchdog, oder externe Hardware.
Das ist zuverlässig und recht universell.

von Klaus S. (kseege)


Lesenswert?

Arduino F. schrieb:
> Um Einzelfall mag man das hinbekommen.
> Das Datenblatt spricht alle Reset Ursachen an.
> Ein Jump zum Bootloader gehört nicht dazu.
> Also nein!

Knapp vorbei ist auch daneben. Von Hardware scheinst Du wenig zu wissen.

Die Resetlogik eines Computers ist ein Stück Hardware, die auf ein 
externes Signal mindestens den ProgramCounter auf einen vorbestimten 
Wert setzt und die CPU loslaufen läßt. Das ist das erforderliche Minimum 
und das haben alle programmgesteuerten Elektroniken seit ihrer 
Erfindung. Zusätzlich bauen erfindungsreiche Hardwareentwickler noch 
alle möglichen Komfortfunktionen ein.

Ein erfindungsreicher Softwareentwickler kann nun alle diese 
erforderlichen Aktionen auch in Software nachbilden, dafür wurden 
Computer schließlich erfunden. Das ist dann auch kein Reset sondern ein 
sogenannter Kaltstart und taucht dementsprechend auch nicht in der Liste 
der Resetgründe auf. Es ist die softwaremäßige Nachbildung eines Resets, 
im Volksmund auch Emulation genannt. Es macht aber dasselbe und ist 
deshalb auch vom nachfolgenden Programm nicht zu erkennen, weshalb es 
auch findige Hardwareentwickler gegeben hat, die extra ein Register 
erfunden haben, das bei Sprung an die Resetadresse sich den Zustand des 
Reseteingangs merkt.

Das ist dann die einzige Möglichkeit zu erkennen, ob ein Kaltstart per 
Resethardware oder anders ausgeführt wurde. Und solange der 
Programmierer eines Bootloaders dieses spezielle Bit nicht auswertet, 
ist die Emulation einem Hardwarereset gleichwertig.

Dieses spezielle Bit ist mir bei AVRs noch nicht untergekommen und ein 
Bit, das nicht da ist, kann eine Software auch nicht auswerten. Ich 
kenne mich in  der Typenpalette der AVRs vermutlich weniger aus als Du, 
deshalb wäre ich um Korrektur dankbar, falls ich da falsch liege.

Zuguterletzt nochmal zurück zum Zweck der Übung: der TO möchte den 
Bootloader starten und der Reset ist nur eine von zwei Möglichkeiten 
dazu.

Gruß Klaus (der soundsovielte)

von Harald K. (kirnbichler)


Lesenswert?

Klaus S. schrieb:
> Knapp vorbei ist auch daneben. Von Hardware scheinst Du wenig zu wissen.

Du scheinst ihn nicht verstanden zu haben, auch wenn Dein Elaborat schön 
lang ist.

Denn tatsächlich widersprechen tust Du der Aussage, daß es mit einem 
Sprung in den Bootloader nicht getan ist, mit keinem Wort.

Der sinnvollste und mit am wenigsten Aufwand umsetzbare Mechanismus 
dürfte in der Tat das Aktivieren und Nicht-Bedienen des Watchdogs sein.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Klaus S. schrieb:
> Von Hardware scheinst Du wenig zu wissen.

Klaus S. schrieb:
> Ich
> kenne mich in  der Typenpalette der AVRs vermutlich weniger aus als Du,

Interessante Weltsicht.

von Olaf D. (Firma: O.D.I.S.) (dreyero)


Lesenswert?

Statt euch gegenseitig anzugreifen, solltet ihr lieber auf den TO 
eingehen.
Er möchte doch nur in den Bootloader springen.
Aus der Applikation heraus. Da ist der Reset doch nur eine Möglichkeit.

Ich benutze durchaus das springen in den Bootloader (Atmega128):

#ifndef BOOTLOADER
                            // Start the bootloader
                            void (*pBootloaderSection)(void);
                            pBootloaderSection = (void(*)())0xF000;
                            pBootloaderSection();
#else
                            // Start the program
                            void (*pApplicationSection)(void);
                            pApplicationSection = (void(*)())0x0000;
                            pApplicationSection();
#endif
                            break;

Gruß
Olaf

von Oliver S. (oliverso)


Lesenswert?

Olaf D. schrieb:
> Er möchte doch nur in den Bootloader springen.
> Aus der Applikation heraus. Da ist der Reset doch nur eine Möglichkeit.

Wir wissen nicht, was er will. Der Unterschied zwischen dem echten Reset 
und einem jmp auf den Bootloader ist, daß der Reset die Hardware in 
einen definierten Zustand versetzt. Ob das erforderlich ist, oder nicht, 
kann nur der TO selber beantworten.

Oliver

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Olaf D. schrieb:
> Statt euch gegenseitig anzugreifen, solltet ihr lieber auf den TO
> eingehen.
Mein kritisierter und kritisierender Vorredner meint, sämtliche Hardware 
vollständig im Griff zu haben und traut sich zu, jedes einzelne Bit so 
setzen zu können, dass sich der µC wie im Kaltstart verhält.

Und du offensichtlich auch!

von Harald K. (kirnbichler)


Lesenswert?

Arduino F. schrieb:
> und traut sich zu, jedes einzelne Bit so
> setzen zu können, dass sich der µC wie im Kaltstart verhält.

Eine Möglichkeit könnte sein, daß der verwendete Bootloader explizit so 
geschrieben ist, daß er keine Annahmen über Resetinitialisierungen 
macht, sondern alles, was er für sich benötigt, gezielt passend 
initialisiert.

Das vergrößert zwar den Code des Bootloaders, erlaubt aber im Gegenzug 
eben auch, den Bootloader durch ein einfaches jmp aufzurufen.

Da wir nichts über den verwendeten Bootloader wissen, wissen wir 
natürlich nicht, ob der sich so verhält.

Und damit ist die universal simpelste Variante die, einen Reset 
auszulösen, was sich ohne externe Hardwarebeihilfe eben mit dem Watchdog 
erzielen lässt.

von Steve van de Grens (roehrmond)


Lesenswert?

Olaf D. schrieb:
> Ich benutze durchaus das springen in den Bootloader (Atmega128)

Fehlt da nicht eine Initialisierung des Stack Pointers? Bei einem Reset 
würde das die Hardware machen (zumindest gilt das für die mir bekannten 
AVR Modelle).

von Oliver S. (oliverso)


Lesenswert?

Steve van de Grens schrieb:
> Olaf D. schrieb:
>> Ich benutze durchaus das springen in den Bootloader (Atmega128)
>
> Fehlt da nicht eine Initialisierung des Stack Pointers? Bei einem Reset
> würde das die Hardware machen (zumindest gilt das für die mir bekannten
> AVR Modelle).

Beim genannten Atmega128 und allen anderen aus dieser Generation 
(8/16/32/64, …) macht die Hardware das nicht.

Oliver

von Steve van de Grens (roehrmond)


Lesenswert?

Oliver S. schrieb:
> Beim genannten Atmega128 und allen anderen aus dieser Generation
> (8/16/32/64, …) macht die Hardware das nicht.

Gut zu wissen. Ich habe AVR erst etwas später kennen gelernt, als diese 
Reihe schon nicht mehr aktuell war.

von Klaus S. (kseege)


Lesenswert?

Harald K. schrieb:
> Denn tatsächlich widersprechen tust Du der Aussage, daß es mit einem
> Sprung in den Bootloader nicht getan ist, mit keinem Wort.

Wozu auch. Ich habe schon ein Paar Stunden vorher geschrieben, was noch 
dazu nötig ist und wenn Du es gelesen hättest, wüßtest Du das. Die 
Verengung auf den reinen Sprung zeigt eben, daß auch "Arduino F." es 
nicht gelesen oder nur nicht verstanden hat.

Ich halte sowohl Dich als auch "Arduino F." für Menschen mit Grips. Nur 
deswegen diskutiere ich mit Euch. Aber es gibt eben mehrere Lösungen für 
das Problem, das der TO beschrieben hat. Aussuchen darf er selber. Was 
wir als das Optimum betrachten, kann ihm an der Kehrseite vorbeigehen. 
Ich schlage nur das vor, was bei mir seit 40 Jahren zuverlässig 
funktioniert. Was in seinem Fall das Optimum ist, kann ich gar nicht 
beurteilen und würde es mir auch nie anmaßen. Für mich ist eben der 
Kaltstart das Optimum, weil ich faul bin und auch uCs ohne Watchdog 
programmiere und mit dieser Lösung unterm Strich die wenigste Arbeit 
habe.

Gruß Klaus (der soundsovielte)

P.S. @Arduino F.
Peace! In der Theorie kann es tatsächlich unbekannte 
Hardwareanforderungen geben. In der Praxis sind sie mir aber in 40 
Jahren Kaltstart noch nicht untergekommen. Und ich kenne tatsächlich 
nicht alle AVRs, die je erschienen sind. Das geht wohl den meisten 
Menschen so. Der Sprung an die Startadresse des Bootloaders meines 
Arduino Pro Mini hat bisher jedenfalls immer geklappt. Kann aber 
natürlich theoretisch daran liegen, daß ich einfach Glück habe.

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
Noch kein Account? Hier anmelden.