Forum: Mikrocontroller und Digitale Elektronik AVR Bootloader + Hauptprogramm zusammenfügen


von PunchBoy (Gast)


Lesenswert?

Hallo,

mein Thema wurde vor 10(!) Jahren z.B. schon mal in diesen Threads 
behandelt:
Beitrag "Bootmanager und Mainprogramm auf einmal Flashen"
Beitrag "Bootloader und App in einem ELF"
aber vielleicht gibt es inzwischen eine befriedigendere Antwort:

Ich programmiere ATmegas mit Bootloader und Hauptprogramm.
Das zusammenfügen und programmieren erledige ich wie auch im ersten 
Beitrag oben beschrieben immer noch mit
- Main.hex erzeugen
- Boot.hex erzeugen
- beide .hex-files im Texteditor per Hand zusammenfügen
- neues .hex-file programmieren
- Fuse-Bytes programmieren

Schöner wäre es natürlich, wenn ich auf Tastendruck direkt beim 
Kompilieren/Linken eine gemeinsame Boot+Main.elf erzeugen könnte, die 
auch die Fuse-Einstellungen enthält.

Kennt jemand dafür inzwischen eine Lösung?

Oder, das wäre die halbe Lösung: kann ich aus meiner manuell erzeugten 
Boot+Main.hex eine .elf erzeugen, die die Fuse-Bytes enthält?

Ich verwende übrigens das aktuelle Atmel Studio 7.0, dort habe ich die 
beiden Projekte Boot/Main in einer gemeinsamen Solution, irgendwie 
sollte sich das doch verbinden lassen?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

PunchBoy schrieb:
> Schöner wäre es natürlich, wenn ich auf Tastendruck direkt beim
> Kompilieren/Linken eine gemeinsame Boot+Main.elf erzeugen könnte, die
> auch die Fuse-Einstellungen enthält.
>
> Kennt jemand dafür inzwischen eine Lösung?

 Ja.
 Bootloader muss genau einmal geflasht werden.
 Und dient dazu, Applikationen mehrmals zu flashen.

 Aber das weisst du ja wahrscheinlich alles schon, nur weisst du
 anscheinend nicht, dass es in VS weniger als eine Stunde dauert,
 um entsprechendes Programm zu schreiben.

von Draco (Gast)


Lesenswert?

Marc V. schrieb:
> Aber das weisst du ja wahrscheinlich alles schon, nur weisst du
>  anscheinend nicht, dass es in VS weniger als eine Stunde dauert,
>  um entsprechendes Programm zu schreiben.

Das wird er sicherlich wissen, aber in Atmel Studio isses natürlich 
tausendmal schöner einfach beim testen kurz die "F5" zu drücken und ab 
dafür anstatt erst den Flip-Loader oder what ever zu öffnen und dann 
dort zu flashen. ;-)

Ich verstehe Punch-Boy da schon.

von PunchBoy (Gast)


Lesenswert?

Hallo Marc,

die Antwort geht leider an meiner Frage vorbei: Ziel ist es wirklich, 
ein einziges .elf mit allem Code zu erzeugen, das dann an einen 
Lieferanten zum Flashen übergeben werden kann. Ich rede hier nicht von 
Heim-Bastel-Lösungen.

Was Dein in einer Stunde geschriebenes Programm tun soll, habe ich 
allerdings nicht verstanden.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

PunchBoy schrieb:
> die Antwort geht leider an meiner Frage vorbei: Ziel ist es wirklich,
> ein einziges .elf mit allem Code zu erzeugen, das dann an einen
> Lieferanten zum Flashen übergeben werden kann. Ich rede hier nicht von
> Heim-Bastel-Lösungen.
>
> Was Dein in einer Stunde geschriebenes Programm tun soll, habe ich
> allerdings nicht verstanden.

 Und ich verstehe nicht wieso das an einen Lieferanten in einem
 einzigen .elf gehen soll.

 Ein Bootloader dient zum Flashen, wird irgendwann einmal benutzt
 werden. Damit man sicher ist, dass es auch bei gerade geflashtem
 uC auch funktioniert, wird mittels frisch geflashtem Bootloader die
 eigentliche Applikation geflasht.
 Nur so ergibt es einen Sinn, nur so ist es richtig und nur so wird
 es in der Produktion auch gemacht.
 Bootloader und Applikation auf einmal flashen ist etwas unüblich
 und zumindest unseriös. Auch mit Verify ist nicht sichergestellt,
 dass der Bootloader einwandfrei funktioniert.

 Ihr könnt das natürlich machen, wie es euch gefällt.

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Marc V. schrieb:
> Damit man sicher ist, dass es auch bei gerade geflashtem
>  uC auch funktioniert, wird mittels frisch geflashtem Bootloader die
>  eigentliche Applikation geflasht.

Das kann man am Anfang testen, solange bis man sicher ist daß alle 
diesbezüglichen Bugs ausgebügelt sind und das 
Skript/Programm/Tool/Whatever und die Binaries mit denen man in der 
Produktion zu flashen gedenkt richtig funktionieren.

Sobald das der Fall ist kann man in Zukunft alles in einem Rutsch drauf 
flashen. Einfach weils weniger Aufwand ist.

> Bootloader und Applikation auf einmal flashen ist etwas unüblich und
> zumindest unseriös.

Nein, das ist durchaus üblich. Unseriös? Blödsinn. Was soll daran 
unseriös sein die Produktionsprozesse zu entkomplizieren und somit 
mögliche Fehlerquellen zu reduzieren?

von Thomas E. (thomase)


Lesenswert?

PunchBoy schrieb:
> Ziel ist es wirklich,
> ein einziges .elf mit allem Code zu erzeugen,

- Bootloader flashen
- Applikation mit Bootloader flashen

oder

- Bootloader flashen
- Applikation flashen und dabei den Speicher NICHT(automatisch) vorher
  löschen.

dann

- Controller auslesen und in Hex speichern
- Aus diesem Hex mit den Fuse- und Lockbits EINE *.elf erstellen

von SF (Gast)


Lesenswert?

Ich hatte dasselbe Problem: Ich wollte bei der Programmierung des µC 
während der Produktion die Applikation und den Bootloader gleichzeitig 
programmieren. Die zweistufige Variante erst Bootloader und dann die 
Applikation war für die Produktion inakzeptabel, da das viel zu lange 
dauert und sich schlecht automatisieren ließ. Vor allen weil der 
Bootloader über einen Kommunikationkanal kommuniziert, der während der 
Produktion nicht verfügbar ist.

Deshalb verwende ich die SRecord tools um die Hexfiles der Applikation 
mit dem Hexfile des Bootloaders zu vereinen.

http://srecord.sourceforge.net/

Das Tool hat zusätzlich den Vorteil, das es eine CRC für die Applikation 
berechnen kann und diese an einer bestimmten Stelle in das Anwendungs 
Hexfile einfügen kann. Diese CRC wird zum Beispiel vom Bootloader 
überprüft.

Der Aufruf der Tools funktioniert automatisch beim Erstellen der 
Software sowohl unter Eclipse als auch natürlich bei normalen makefiles. 
Mittels postbuild steps geht das bestimmt auch in VS oder Atmelstudio.

Man kann sich aber auch sehr schnell ein kleines Programm schreiben das 
die HEX Files zusammenfügen kann. Das HEX Dateiformat ist ziemlich 
einfach.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Bernd K. schrieb:
>> Bootloader und Applikation auf einmal flashen ist etwas unüblich und
>> zumindest unseriös.
>
> Nein, das ist durchaus üblich. Unseriös? Blödsinn. Was soll daran
> unseriös sein die Produktionsprozesse zu entkomplizieren und somit
> mögliche Fehlerquellen zu reduzieren?

 Nein, das ist nicht üblich.
 Erstens ist ein uC mit Bootloader dazu bestimmt, die auf ihm laufende
 Applikation zu verändern oder durch eine ganz andere zu ersetzen.
 Das sind keine uC die in Zehntausenden produziert werden, und selbst
 wenn, es muss ganz einfach sichergestellt werden, dass es 100%-ig
 funktioniert - auch wenn es 5s länger dauert.
 Alles andere ist ganz einfach unseriös.
 Glaubst du wir (oder irgend jemand anders, der sich ernsthaft damit
 beschäftigt oder sogar davon lebt) baut so einen uC ein, ohne vorher
 Bootloader geprüft zu haben ?
 Nöö, sicher nicht und du sollst nicht Sachen von denen du offenbar
 keine Ahnung hast, als Blödsinn bezeichnen.

von PunchBoy (Gast)


Lesenswert?

Thomas E. schrieb:
> - Aus diesem Hex mit den Fuse- und Lockbits EINE *.elf erstellen

Und hier war Teil 2 meiner Frage :-) : wie geht das am einfachsten?

Marc V. schrieb:
> baut so einen uC ein, ohne vorher
>  Bootloader geprüft zu haben ?

Der Code des Bootloaders wird in der Entwicklung auf Herz und Nieren 
geprüft, der funktioniert (nach bestem Wissen). In der Fertigung wird 
beim Flashen geprüft, dass der Bootloader korrekt geflasht wurde, d.h. 
alle Nullen und Einsen dort sind, wo sie hingehören. Welcher Fehler soll 
sich dann noch von Platine zu Platine ergeben?

von Bernd K. (prof7bit)


Lesenswert?

Marc V. schrieb:
> und selbst
>  wenn, es muss ganz einfach sichergestellt werden, dass es 100%-ig
>  funktioniert - auch wenn es 5s länger dauert.

Das wird es doch.

Und nachdem das sichergestellt ist kann man die anderen 19999 Exemplare 
mit dem selben Script und der selben Firmware flashen.

> baut so einen uC ein, ohne vorher Bootloader geprüft zu haben ?

Wo hab ich das behauptet? Ich habe gesagt das man das ausgiebig testen 
kann (und soll) so lange bis man sich sicher ist daß alle Softwarebugs 
behoben sind und der Bootloader funktioniert. Danach kann man die 
anderen 19999 Exemplare mit der selben Firmware flashen.

von Thomas E. (thomase)


Lesenswert?

PunchBoy schrieb:
> Und hier war Teil 2 meiner Frage :-) : wie geht das am einfachsten?

> Ich verwende übrigens das aktuelle Atmel Studio 7.0

Ich habe das Studio 7 gerade nicht greifbar. Aber es gibt dort eine 
Funktion zum Erstellen von Production Files. Die befindet sich im 
Gegensatz zum alten Studio 4 allerdings nicht im Brenner-Dialog. Da drin 
kannst du das mit ein paar Häkchen in den entsprechenden Checkboxes nach 
deinen Anforderungen zusammenstellen.

von Jay (Gast)


Lesenswert?

PunchBoy schrieb:
> Hallo Marc,
>
> die Antwort geht leider an meiner Frage vorbei: Ziel ist es wirklich,
> ein einziges .elf mit allem Code zu erzeugen, das dann an einen
> Lieferanten zum Flashen übergeben werden kann.

Wenn dein Lieferant mit mehreren Dateien Probleme hat, dann solltest du 
über einen Wechsel nachdenken.

Aber fangen wir vorne an. Fuses kann man mittlerweile im Code setzen. 
http://www.nongnu.org/avr-libc/user-manual/group__avr__fuse.html Das ist 
kein Problem des .elf, sondern ob der von deinem Lieferanten verwendete 
Gang-Programmer Fuse-Settings im .elf versteht. Du solltest mit deinem 
Lieferanten reden was sein Gang-Programmer kann, beziehungsweise warum 
er die Fuses nicht aus dem .elf lesen kann.

Das Zusammenführen eines Bootloader .hex und eines Programm .hex muss 
man selbstverständlich nicht von Hand in einem Editor machen. Das kann 
man mit Tools skripten (vielleicht srec_cat?) oder sich, wie oben schon 
erwähnt, ein Programm für schreiben.

Aber, der absolute Star unter den Werkzeugen zum Zusammenfügen von 
Kompilaten ist, man glaubt es kaum, der Linker.

> Ich rede hier nicht von
> Heim-Bastel-Lösungen.

Dann rede zuerst mal mit deinem professionellen Lieferanten, warum er 
mit drei Dateien Probleme hat.

Wenn für dich alles selbstgemachte eine Heim-Bastel-Lösungen ist, dann 
wird sich hier sicher jemand finden, der das Zusammenfügen der Dateien 
als Dienstleistung, vielleicht über einen Webservice, anbietet. So voll 
professionell. Gegen professionelle Bezahlung.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Bernd K. schrieb:
> behoben sind und der Bootloader funktioniert. Danach kann man die
> anderen 19999 Exemplare mit der selben Firmware flashen.

PunchBoy schrieb:
> geprüft, der funktioniert (nach bestem Wissen). In der Fertigung wird
> beim Flashen geprüft, dass der Bootloader korrekt geflasht wurde, d.h.
> alle Nullen und Einsen dort sind, wo sie hingehören. Welcher Fehler soll
> sich dann noch von Platine zu Platine ergeben?

 Der Fehler, der sich Zufall und Murphy's law nennt.
 Nach eurer Auffasung sollte es auch keine Produktionstest geben -
 alles richtig geflasht, richtig gelötet, sieht gut aus, überhaupt kein
 Problem - wird in Autos, Flugzeuge usw. ohne weitere Prüfung eingebaut,
 wird schon funktionieren...

von Markus F. (mfro)


Lesenswert?

Ich glaub', Ihr streitet euch um des Kaiser's Bart.

Meines Erachtens ist ein Bootloader (und die Möglichkeit, den separat zu 
flashen und auch nur dann, wenn's unbedingt notwendig ist) nur dort von 
Bedeutung, wo keine separate, schnelle Flashmöglichkeit besteht.

Also dort, wo ein Fehlschlag beim Flashen das bewußte Gerät zum 
Türstopper macht, weil man nicht mehr an den Flash drankommt und das 
Ding einschicken oder auf den Service warten muß.

Sprich: wenn bei fehlgeschlagenen Flashvorgang keine einfache und 
schnelle Möglichkeit besteht, (z.B.) auf die vorherige Version 
zurückzugehen.

Wenn es die gibt (z.B. weil das Flashen sowieso von einem zweiten µC aus 
gemacht wird), ist m.E. der Bootloader eigentlich unnötig und man kann 
genausogut jedesmal den gesamten Flash auf einmal überklatschen.

von Thomas E. (thomase)


Lesenswert?

Marc V. schrieb:
> Der Fehler, der sich Zufall und Murphy's law nennt.

Deswegen testest du bestimmt auch Schmelzsicherungen vor der 
Auslieferung auf einwandfreie Funktion.

von Bernd K. (prof7bit)


Lesenswert?

Marc V. schrieb:
> Nach eurer Auffasung sollte es auch keine Produktionstest geben -

Was hat das eine mit dem anderen zu tun? Die Hardware kann man 
unabhängig davon und zu gegebener Zeit auf korrekte Funktion prüfen.

Dem Threadersteller gehts darum das Flashen zu vereinfachen.

von Bernd K. (prof7bit)


Lesenswert?

Thomas E. schrieb:
> Marc V. schrieb:
>> Der Fehler, der sich Zufall und Murphy's law nennt.
>
> Deswegen testest du bestimmt auch Schmelzsicherungen vor der
> Auslieferung auf einwandfreie Funktion.

Hört sich eher so an als würde er Excel-Tabellen mit dem Taschenrechner 
nachrechnen. Und zwar nach jeder Kopie der Datei erneut.

von Thomas E. (thomase)


Lesenswert?

Bernd K. schrieb:
> Hört sich eher so an als würde er Excel-Tabellen mit dem Taschenrechner
> nachrechnen. Und zwar nach jeder Kopie der Datei erneut.

Aber nicht, ohne vorher den Taschenrechner zu debuggen.

von PunchBoy (Gast)


Lesenswert?

Seid bitte so gut und lenkt den Thread nicht in einen Privat-Streit. Es 
geht mir nicht um Sinn und Umfang Produktionstests. Natürlich muss man 
zu jedem Zeitpunkt von Entwicklung/Fertigung in sinnvollem Umfang (!) 
testen.

Jay schrieb:
> Wenn dein Lieferant mit mehreren Dateien Probleme hat, dann solltest du
> über einen Wechsel nachdenken.

Jay schrieb:
> Das Zusammenführen eines Bootloader .hex und eines Programm .hex muss
> man selbstverständlich nicht von Hand in einem Editor machen. Das kann
> man mit Tools skripten (vielleicht srec_cat?) oder sich, wie oben schon
> erwähnt, ein Programm für schreiben.

Es geht mir darum, den Release-Prozess einer neuen Version zu 
vereinfachen.
Idealerweise: 1. Änderung im Code, 2. Compile&Link einer .elf Datei mit 
einem Tastendruck, 3. Die eine Datei zum Lieferanten.
Je mehr Schritte beim Erstellen notwendig sind, desto mehr Fehler kann 
man machen.
Und man hat sonst immer ein Paket aus z.B. drei Dateien 
(Main/Boot/FuseSettings), die nur zusammen eine Version definieren.


Jay schrieb:
> Aber, der absolute Star unter den Werkzeugen zum Zusammenfügen von
> Kompilaten ist, man glaubt es kaum, der Linker.

Thomas E. schrieb:
> Ich habe das Studio 7 gerade nicht greifbar. Aber es gibt dort eine
> Funktion zum Erstellen von Production Files. Die befindet sich im
> Gegensatz zum alten Studio 4 allerdings nicht im Brenner-Dialog. Da drin
> kannst du das mit ein paar Häkchen in den entsprechenden Checkboxes nach
> deinen Anforderungen zusammenstellen.

Das ist mein Thema. Wie kann ich dem Linker im Atmel Studio beibringen, 
meine .elf-Datei zu erzeugen?

von Draco (Gast)


Lesenswert?

Also Marc, ich verstehe dein Problem hier nun auch nicht, und kann deine 
Sichtweise auf Bezug: Produktion / Bootloader, auch nicht 
nachvollziehen. Die Produktionsfirmen sparen alle wo sie können, Prüfung 
hin oder her, hier redet auch kein Mensch davon das es sich hierbei um 
Militärtechnik oder Technik für Aero oder Medizintechnik handelt.

Es ist schon ein großer Zeit und Kostenfaktor ob man den µC nun einmal 
im Rutsch flasht (Und warum sollte man ihn dann nicht verifizieren 
können?! Wegen des BL? Quark!) oder ob ich als Firma erstmal den 
Bootloader flashe - dann eventuell warten muss (kann ja sein das die 
Schnittstelle für den BL erst später kommt) um dann nochmals über den BL 
den µC zu flashen.

Das ist ja so als ob man sich ne Banane kauft, die im Geschäft schält, 
erst die Schale nach Hause bringt, nochmal zurück zum Laden geht und 
dann erst den Rest den Banane holt - nur um sicherzustellen das beides 
gut zu Hause ankommt.

Und dein Argument das der BL ja Fehlerhaft sein könnte, kann dir beim 
Flashen des BL only wohl nicht passieren?! Das ist doch alles an den 
Haren herbeigezogen.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Draco schrieb:
> können?! Wegen des BL? Quark!) oder ob ich als Firma erstmal den
> Bootloader flashe - dann eventuell warten muss (kann ja sein das die
> Schnittstelle für den BL erst später kommt) um dann nochmals über den BL
> den µC zu flashen.

 Aha.
 Und um Bootloader zu flashen hast du am uC klitzekleine Drähtchen
 angelötet, mit Prommer verbunden und danach wieder ausgelötet,
 oder wie ?
 Das ist natürlich viel schneller als die übliche Methode, lass dich
 nicht vom Gegenteil überzeugen.


> Und dein Argument das der BL ja Fehlerhaft sein könnte, kann dir beim
> Flashen des BL only wohl nicht passieren?!

 Natürlich.
 Deswegen flasht man danach mit dem Bootloader die Applikation und hat
 damit beide getestet - die Schnittstelle übrigens auch.

 Und nochmal:
 Ein uC mit Bootloader dessen funktionstüchtigkeit nicht geprüft wurde,
 geht bei keiner normaler Firma raus - nicht nur beim Hersteller,
 sondern auch bei Firmen die so etwas einbauen.

von PunchBoy (Gast)


Lesenswert?

PunchBoy schrieb:
> Seid bitte so gut und lenkt den Thread nicht in einen Privat-Streit. Es
> geht mir nicht um Sinn und Umfang Produktionstests. Natürlich muss man
> zu jedem Zeitpunkt von Entwicklung/Fertigung in sinnvollem Umfang (!)
> testen.

PunchBoy schrieb:
> Jay schrieb:
>> Aber, der absolute Star unter den Werkzeugen zum Zusammenfügen von
>> Kompilaten ist, man glaubt es kaum, der Linker.
>
> Thomas E. schrieb:
>> Ich habe das Studio 7 gerade nicht greifbar. Aber es gibt dort eine
>> ...
>> deinen Anforderungen zusammenstellen.
>
> Das ist mein Thema. Wie kann ich dem Linker im Atmel Studio beibringen,
> meine .elf-Datei zu erzeugen?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

PunchBoy schrieb:
> Das ist mein Thema. Wie kann ich dem Linker im Atmel Studio beibringen,
> meine .elf-Datei zu erzeugen?

 Wie wäre es hiermit:
1
__attribute__ ((section (".myboot")))
2
uint8_t bootcode(uint8_t lPas) __attribute__ ((section (".myboot")));
3
4
int main(void)
5
{
6
...
7
}
8
...
9
...
10
uint8_t bootcode(uint8_t lPas)
11
{
12
 static uint8_t lVar;
13
 lVar++;
14
 return lPas+lVar;
15
}

 Und dem linker so etwas vorsetzen:
1
 -Wl,--section-start=.myboot=0x1234
 oder wo auch immer du deinen code haben willst...

 P.S.
 Nicht ausprobiert, nur gedacht, dass es vielleicht so gehen kann,
 um deinen Lieferenten zu schonen...

 P.P.S.
 Ist natürlich nur eine Heim-Bastel-Lösung, dein Lieferant hat
 wahrscheinlich viele Fachleute die das besser können.

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Marc V. schrieb:
> Und nochmal:
>  Ein uC mit Bootloader dessen funktionstüchtigkeit nicht geprüft wurde,
>  geht bei keiner normaler Firma raus

Das hat auch keiner verlangt.

Der Bootloader wird bei seiner Entwicklung ausgiebig getestet, danach 
funktioniert er. Und zwar bis ans Ende der Zeit. Es ist nicht zu 
erwarten daß er plötzlich mutiert wenn nachts keiner hinsieht.

Die Hardware vor der Auslieferung zu testen ist ein komplett anderes 
Thema.

Hier gehts aber ums effiziente Flashen, das hat damit null und nichts zu 
tun.

von Jannyboy (Gast)


Lesenswert?

Nach dem ich lange Zeit stiller Mitleser bin und schon lange in anderen 
Foren aktiv bin.

Muss ich jetzt mal meinen Senf mit dazu geben.
Ihr denkt alle viel zu kompliziert.

Klitze kleines C-Programm,
es liest die beiden Hex-files ein, fügt sie zusammen und schraubt sie 
wieder als Hex-file.

Gruß,
Jan

von Stefan K. (stefan64)


Lesenswert?

Jannyboy schrieb:
> Klitze kleines C-Programm,
> es liest die beiden Hex-files ein, fügt sie zusammen und schraubt sie
> wieder als Hex-file.

Ist zwar nicht kliteklein (weil tausende Optionen), dafür aber bereits 
geschrieben:

srec_cat, siehe Doku hier:

http://srecord.sourceforge.net/

Damit kannst Du Files unterschiedlichster Formate zusammenfügen. RCA 
Cosmac Elf ist auch dabei, habe ich aber persönlich noch nicht verwendet 
und ich weiss nicht, ob das kompatibel mit dem aktuellen gcc elf Format 
ist.

Damit erzeugen wir unsere kombinierten Bootloader-und Applikationsfiles 
direkt im makefile, d.h. bei jedem Compilieren fällt auch das 
kombinierte File ab.

Viele Grüße, Stefan

von Markus F. (mfro)


Lesenswert?

GNU objcopy müsste das eigentlich auch können (hab's nie probiert).

objcopy bootloader.elf --add-section sectionname=application.elf 
fat_binary.elf

sollte das eigentlich hinkriegen.

von Axel S. (a-za-z0-9)


Lesenswert?

PunchBoy schrieb:
> Ich programmiere ATmegas mit Bootloader und Hauptprogramm.
> Das zusammenfügen und programmieren erledige ich wie auch im ersten
> Beitrag oben beschrieben immer noch mit
> - Main.hex erzeugen
> - Boot.hex erzeugen
> - beide .hex-files im Texteditor per Hand zusammenfügen

Meine Güte, wie steinzeitlich. GNU textutils installieren und eine 
Kommandozeile aus cat und tail bauen. Alternativ sreccat oder 
etwas ähnliches verwenden.

> - neues .hex-file programmieren
> - Fuse-Bytes programmieren
>
> Schöner wäre es natürlich, wenn ich auf Tastendruck direkt beim
> Kompilieren/Linken eine gemeinsame Boot+Main.elf erzeugen könnte, die
> auch die Fuse-Einstellungen enthält.
>
> Kennt jemand dafür inzwischen eine Lösung?

Fuses im Programmcode geht seit geraumer Zeit. Verlangt aber, daß man 
eine hinreichend neue Version von avrdude zum Brennen verwendet. Die 
Fuses kann man dann wahlweise mit dem Bootloader oder mit der 
Applikation verheiraten. Der Bootloader erscheint mir aber als die 
bessere Wahl.

Was das Zusammenlinken von Bootloader und Hauptprogramm in ein 
gemeinsames .elf angeht - das geht, ist aber entschieden nichtrivial. 
Die Grundidee wurde oben schon skizziert: man braucht zwei Codesegmente 
im Flash und muß einerseits ein angepaßtes Linkerskript verwenden und 
andererseits den Code per __attribute() in das jeweilige Segment 
plazieren.

Allerdings ist es entschieden nichtrivial, das hinzubekommen. Zumal man 
dann einiges an Magie in die Toolchain stecken muß was nicht auf einen 
anderen µC portabel ist oder nach einem Update der Toolchain vielleicht 
verschwindet.

Die viel einfachere Lösung besteht darin, einfach zwei Flashvorgänge via 
ISP vorzunehmen. Im ersten Durchgang macht man ein Chip-Erase und flasht 
Bootloader und Fuses. In zweiten Durchgang flash man die Applikation und 
darf natürlich kein Chip-Erase machen. Der IDE kann man das wahlweise 
in Form eines Makefiles oder eine Skripts beibringen, der Fertiger wird 
wohl auch eine Möglichkeit haben, ein Skript auszuführen (als 
Alternative zu einem direkten Aufruf von avrdude).

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Bernd K. schrieb:
> Hier gehts aber ums effiziente Flashen, das hat damit null und nichts zu
> tun.

 Genauso wie deine und die Beiträge von Thomas E.
 Ausser zumüllen habt ihr beide wenig bzw. nichts beigetragen.

Jannyboy schrieb:
> Ihr denkt alle viel zu kompliziert.
> Klitze kleines C-Programm,

 Habe ich ihm schon um 10:11 vorgeschlagen, sein Lieferant war dagegen.
 Danach die fruchtlose Diskussion mit beiden Experten bis 13:30.

 Hat dann aber ganze 29 Minuten gedauert (13:59) bis er eine Lösung
 für sein "Problem" hatte:
 Beitrag "Re: AVR Bootloader + Hauptprogramm zusammenfügen"
 Die Zeitspanne von 29 Minuten war natürlich unakzeptabel, bei seinem
 Lieferanten darf so viel Zeit nicht unnütz vergeudet werden.
 Wetten dass sich der TO, sein Lieferant und die beiden Experten nicht
 wieder melden ?

 Oder falls doch, wird es nur Anspuckerei mit hohlköpfigen Argumenten
 sein...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Axel S. schrieb:
> Die viel einfachere Lösung besteht darin, einfach zwei Flashvorgänge via
> ISP vorzunehmen. Im ersten Durchgang macht man ein Chip-Erase und flasht
> Bootloader und Fuses. In zweiten Durchgang flash man die Applikation und

 Sein Lieferant scheint dazu nicht imstande zu sein.

Axel S. schrieb:
> Allerdings ist es entschieden nichtrivial, das hinzubekommen. Zumal man
> dann einiges an Magie in die Toolchain stecken muß was nicht auf einen
> anderen µC portabel ist oder nach einem Update der Toolchain vielleicht
> verschwindet.

 Solange man sich auf relative calls und jumps beschränkt (was man ja
 im Bootloaderbereich sowieso tun soll) ist es gefahrlos und 100%
 portabel.
 Und der Compiler wird sowieso immer relative adressierung vorziehen,
 da man ja nicht aus dem Bootloaderbereich rausdarf und der Code
 dementsprechend nicht grösser als 2KB ist.

: Bearbeitet durch User
von Thomas E. (thomase)


Lesenswert?

Marc V. schrieb:
> Oder falls doch, wird es nur Anspuckerei mit hohlköpfigen Argumenten
>  sein...

https://www.youtube.com/watch?v=MS_Hp9j-0UY

https://www.youtube.com/watch?v=I7VQNjnKRAQ

: Bearbeitet durch User
von PunchBoy (Gast)


Lesenswert?

Marc V. schrieb:
> Oder falls doch, wird es nur Anspuckerei mit hohlköpfigen Argumenten
>  sein...

Bisher war ich höflich. Jetzt beginnt die "Anspuckerei":

1. Ich habe um die Lösung für eine konkrete Aufgabenstellung gebeten. 
Ich habe mir vorab Gedanken gemacht, warum ich das, was ich tun will, 
innerhalb meiner Arbeitsumgebung (die Du nicht kennst), so tun will.
Von Dir kommen aber hauptsächlich Meinungen, warum die Aufgabenstellung 
Unsinn wäre. Zugegeben irgendwann ein Lösungsvorschlag mit 
Fuse-Definition im Code, der aber für meine Firmware (die Du nicht 
kennst), nicht anwendbar ist.

2. Ich habe nie etwas dazu gesagt, was mein Lieferant (den Du nicht 
kennst) kann und was nicht. Mir geht es darum meinen Prozess für mich zu 
vereinfachen.

3. Alle hier im Thread haben Deinen Aussagen (zu Fertigungstest z.B.) 
widersprochen. Liegt das daran, dass die Masse immer so hohlköpfig ist?

Das war jetzt undankbar, ich weiß...

von PunchBoy (Gast)


Lesenswert?

Zur Diskussion:

Stefan K. schrieb:
> srec_cat, siehe Doku hier:
>
> Damit erzeugen wir unsere kombinierten Bootloader-und Applikationsfiles
> direkt im makefile, d.h. bei jedem Compilieren fällt auch das
> kombinierte File ab.

Markus F. schrieb:
> GNU objcopy müsste das eigentlich auch können (hab's nie probiert).
>
> objcopy bootloader.elf --add-section sectionname=application.elf
> fat_binary.elf
>
> sollte das eigentlich hinkriegen.

Ein solcher Befehl im Makefile wäre eine Lösung. Habe dazu allerdings 
ein bißchen gegooglet, weder srec_cat noch objcopy können wohl eine .elf 
erzeugen, bzw. zwei .elfs kombinieren (das Thema gibt es ja nicht nur 
bei AVRs).

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

PunchBoy schrieb:
> Von Dir kommen aber hauptsächlich Meinungen, warum die Aufgabenstellung
> Unsinn wäre. Zugegeben irgendwann ein Lösungsvorschlag mit
> Fuse-Definition im Code, der aber für meine Firmware (die Du nicht
> kennst), nicht anwendbar ist.

 Waaas ?
 Bist du wirklich so dumm ?
 Wo siehst du Fuse-Definition ?
 Warum ist das nicht anwendbar ?

 Es ist genau das, wonach du (und dein Lieferant) gebeten hast.
 Beitrag "Re: AVR Bootloader + Hauptprogramm zusammenfügen"

 Was soll da nicht anwendbar sein ?

 Oder bist du nur zu dumm, um es zu verstehen ?
 Hier noch einmal, ganz langsam, da du offenbar Schwierigkeiten mit
 verstehen hast:
1
__attribute__ ((section (".myboot")))
2
//* Das wird beim Reset angesprungen
3
void bootcode(void) __attribute__ ((section (".myboot")));
4
// Man kann auch weitere funktionen im Bootloader definieren z.B.
5
uint8_t testrut(uint8_t lPas) __attribute__ ((section (".myboot")));
6
7
//* Applikation
8
int main(void)
9
{
10
...
11
...
12
}
13
14
//* Bootloader
15
void bootcode(void) // __attribute__ ((section (".myboot")));
16
{
17
// Dein (oder wessen auch immer) code
18
}
19
// Dummy funktion
20
uint8_t testrut(uint8_t lPas) // __attribute__ ((section (".myboot")));
21
{
22
 return lPas++;
23
}

 Und dem linker wird die Adresse vorgegeben:
1
 -Wl,--section-start=.myboot=0x0C00
 oder wo auch immer du den code haben willst...

 Und das war's dann...
 Ist doch nicht soooo schwer zu verstehen und anzuwenden, oder ?

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Falls jemand (wer wohl) Schwierigkeiten mit begreifen hat...

Auszug aus .lss
1
00000000 <__vectors>:
2
   0:  0c 94 34 00   jmp  0x68  ; 0x68 <__ctors_end>
3
...
4
...
5
int main(void)
6
{
7
  a6:  df 93         push  r29
8
...
9
...
10
00000342 <_exit>:
11
 342:  f8 94         cli
12
00000344 <__stop_program>:
13
 344:  ff cf         rjmp  .-2        ; 0x344 <__stop_program>


Disassembly of section .myboot:
1
void bootcode(void)  // __attribute__ ((section (".myboot")));
2
{
3
    e000:  df 93         push  r29
4
    e002:  cf 93         push  r28

von Axel S. (a-za-z0-9)


Lesenswert?

PunchBoy schrieb:
> 2. Ich habe nie etwas dazu gesagt, was mein Lieferant (den Du nicht
> kennst) kann und was nicht.

Du hast verlangt, daß doch bitte alles in einem .elf File sein solle. 
Für den Lieferanten. Das läßt darauf schließen daß er (aus welchen 
Gründen auch immer) mit zwei .elf Files und evtl. noch einem .hex mit 
den Fuses nicht klar kommt.

Ich halte das auch nicht für wahrscheinlich; deswegen mein pragmatischer 
Vorschlag, einfach zwei .elf Files nacheinander per ISP zu flashen. 
Das ist trivial, das erfordert keine Änderungen am Code und das geht 
auch noch, wenn ihr nächstes Jahr auf einen anderen AVR wechseln 
solltet.

> Mir geht es darum meinen Prozess für mich zu vereinfachen.

Dann lerne, mit deinen Tools umzugehen. Zu wissen, welchen Button du im 
GUI anklicken mußt, damit dein Projekt geflasht wird, ist zu wenig. Du 
solltest schon verstehen, was da im Hintergrund passiert und wie du dort 
z.B. eine eigene Kommandosequenz hinterlegen kannst.

Wir "Kommandozeilenfrickler" auf die ihr GUI-Typen immer so abschätzig 
herabblickt, machen das mit einem Makefile. Das ist leistungsfähig und 
elegant. Und eigentlich auch nicht schwer. Man muß halt die Bereitschaft 
mitbringen, auch mal was neues zu lernen.

: Bearbeitet durch User
von Markus F. (mfro)


Lesenswert?

PunchBoy schrieb:
> Ein solcher Befehl im Makefile wäre eine Lösung. Habe dazu allerdings
> ein bißchen gegooglet, weder srec_cat noch objcopy können wohl eine .elf
> erzeugen, bzw. zwei .elfs kombinieren (das Thema gibt es ja nicht nur
> bei AVRs).

Das bezweifle ich (ich hab's nämlich - statt zu Googeln - einfach 
ausprobiert):

wenn ich ein bl.elf (Bootloader) und ein app.elf (Applikation) habe, 
macht

arm-none-eabi-objcopy bl.elf --add-section application=app.elf fat.elf

ziemlich genau das, was ich von ihm erwartet hätte (hängt app.elf als 
zusätzliche Section "application" hinten an).

Scheint objcopy ziemlich wurscht zu sein, was bei Google so steht.

Natürlich müssen deine Flash-Tools mit der zusätzlichen Section auch 
zurechtkommen, aber dabei kann ich nicht helfen.

: Bearbeitet durch User
von PunchBoy (Gast)


Lesenswert?

Ok, ich bin dann weg. Jetzt wird es nur noch unkonstruktiv und 
beleidigend (wie leider die meisten Threads hier). Danke für die 
konstruktiven Vorschläge.

Nur noch dazu:
Marc V. schrieb:
> Wo siehst du Fuse-Definition ?
Sorry, habe mich vertippt. Habe schon verstanden, dass Du den Funktionen 
Code-Bereiche zuweist.

von Stefan K. (stefan64)


Lesenswert?

PunchBoy schrieb:
> Ok, ich bin dann weg. Jetzt wird es nur noch unkonstruktiv und
> beleidigend

Das kann ich verstehen. Das nervt die meisten hier. Und Mark pöbelt hier 
öfters so rum - > einfach ignorieren.

Aber Markus sein Beitrag war doch genau das, was Du suchst, probiers 
doch einfach mal aus.

Gruß, Stefan

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

PunchBoy schrieb:
> Nur noch dazu:
> Marc V. schrieb:
>> Wo siehst du Fuse-Definition ?
> Sorry, habe mich vertippt. Habe schon verstanden, dass Du den Funktionen
> Code-Bereiche zuweist.

 Hier:
1
#include <avr/io.h>
2
3
__fuse_t __fuse __attribute__((section (".fuse"))) =
4
 {
5
    .low = LFUSE_DEFAULT,     //* Oder welcher Wert auch immer
6
    .high = (FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_SPIEN),     //* Oder wie auch immer
7
    .extended = EFUSE_DEFAULT,     //* Oder welcher Wert auch immer
8
 };

: Bearbeitet durch User
von PunchBoy (Gast)


Lesenswert?

Markus F. schrieb:
> arm-none-eabi-objcopy bl.elf --add-section application=app.elf fat.elf

Ich werde es ausprobieren. Danke!

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

PunchBoy schrieb:
> Ich werde es ausprobieren. Danke!

 Tu das.
 Nichtsdestotrotz in Zukunft deinem Lieferanten .elf mit der von mir
 geposteten Lösung schicken.
 Pfui.

von PunchBoy (Gast)


Lesenswert?

Stefan K. schrieb:
> Das kann ich verstehen. Das nervt die meisten hier. Und Mark pöbelt hier
> öfters so rum - > einfach ignorieren.

Fällt mir schwer, sorry...

Ganz ehrlich Marc, ich verstehe Dich nicht (aber mit verstehen habe ich 
ja auch Probleme :-)).

Dein Beitrag hier

Marc V. schrieb:
> _attribute_ ((section (".myboot")))
> //* Das wird beim Reset angesprungen
> void bootcode(void) _attribute_ ((section (".myboot")));
> // Man kann auch weitere funktionen im Bootloader definieren z.B.
> uint8_t testrut(uint8_t lPas) _attribute_ ((section (".myboot")));
 ...
>
>  Und dem linker wird die Adresse vorgegeben:
> -Wl,--section-start=.myboot=0x0C00 oder wo auch immer du den code haben
> willst...

ist ein durchaus sehr sinnvoller Lösungsvorschlag.

(Den ich übrigens nicht so gern umsetzen (und daher auch nicht testen) 
möchte, weil ich meinen vorhandenen und recht umfangreichen Code nicht 
mehr grundsätzlich anfassen und ändern und testen möchte, sondern nur 
noch den Link-Prozess vereinfachen, wenn es EINFACH geht. Die Zeit, die 
ich darein stecke, ist Budgetiert).

Deine teilweise wirklich hilfreichen Lösungsvorschläge garnierst Du mit 
Beleidigungen und Unterstellungen, so dass man kaum Lust hat, die 
Beiträge inhaltlich zu lesen.

Hast Du eigentlich Kunden oder Kollegen, oder, noch schlimmer 
Mitarbeiter auf der Arbeit, mit denen Du auch so redest?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

PunchBoy schrieb:
> Ganz ehrlich Marc, ich verstehe Dich nicht

 Und ich verstehe es ganz einfach nicht, wieso du nicht verstehst...

> (Den ich übrigens nicht so gern umsetzen (und daher auch nicht testen)
> möchte, weil ich meinen vorhandenen und recht umfangreichen Code nicht
> mehr grundsätzlich anfassen und ändern und testen möchte, sondern nur

 Deinen Code brauchst du in keiner Weise anzufassen...

 Wenn man es dem Linker nicht anders sagt, wird alles in der Sektion
 .text (default) ab der Adresse 0x00 aufwärts gelinkt.
 Damit du einen funktionierenden Bootloader schreiben kannst, muss
 dem Linker mitgeteilt werden, dass die Sektion .text z.B. nach
 Adresse 0x7800 verschoben werden soll.
 Deswegen hast du aber bei deiner bisherigen Lösung zwei getrennte
 Programme, die du jetzt gerne als ein einziges .elf File haben
 möchtest, richtig ?

 Bei der von mir geposteten Lösung bleibt die Sektion
1
.text  // (und das ist die Applikation)
 da wo sie ist, du definierst aber zusätzlich eine neue Sektion
1
.myboot // (und das ist der Bootloader)
 mit
1
 __attribute__ ((section (".myboot")))

 Jetzt brauchst du nur mitzuteilen, dass sich die paar Routinen,
 die sich im Bootloader befinden, alle zur Sektion .myboot
 gehören.
 Also, wird am Programmanfang mit dieser Definition:
1
void bootcode(void) __attribute__ ((section (".myboot")));)
 dieses auch mitgeteilt.
 Natürlich werden anstatt void bootcode etc. alle deine bestehenden
 Routinen im Bootloader angeführt - und es können normalerweise nicht
 mehr als 4-5 zusätzliche Routinen sein - wenn es mehr sind, stimmt
 etwas mit deinem Bootloader nicht. Deine schon bestehenden Routinen
 sowohl in der Applikationsektion als auch in der Bootloadersektion
 brauchst du weder zu ändern noch überhaupt anzufassen.
 Wie du die Fuses setzst, steht hier:
 Beitrag "Re: AVR Bootloader + Hauptprogramm zusammenfügen"
 Und damit ist schon alles beendet und deine Voraussetzung
 will grundsätzlich nicht anfassen und nicht ändern und nicht testen
 ist auch erfüllt.

 Bleibt nur noch dem Linker mitzuteilen, dass die Sektion .myboot
 nach 0x7800 verschoben werden soll und das machst du mit:
1
-Wl,--section-start=.myboot=0x7800

 Und damit hast du alles in einem .elf File in einem Durchgang.
 Einfacher geht es nicht.

> Die Zeit, die ich darein stecke, ist Budgetiert).
 Meine leider nicht.

: Bearbeitet durch User
von PunchBoy (Gast)


Lesenswert?

Marc V. schrieb:
> PunchBoy schrieb:
>> Ganz ehrlich Marc, ich verstehe Dich nicht
>
>  Und ich verstehe es ganz einfach nicht, wieso du nicht verstehst...
>

Sorry, da habe ich mich missverständlich ausgedrückt :-). Deinen 
Vorschlag habe ich (auch schon beim ersten Mal) verstanden. Ich verstehe 
nur weiterhin nicht, wieso Du kluge Gedanken in unfreundliche Worte 
packen musst.

>  Deinen Code brauchst du in keiner Weise anzufassen...

Das "in keiner Weise" bezweifle ich wiederum. Ich muss ja (so verstehe 
ich die Dokumentation) jeder Funktion und jeder globalen Variable die 
Section zuweisen.

Da mein Bootloader doch recht umfangreich ist (sollte nicht so sein, ich 
weiß, ist aber der Anwendung und der Historie geschuldet), müsste ich an 
mehreren Stellen die Section mit definieren.

Der momentane Bootloader ist getestet und im Einsatz, jede kleine 
Änderung am Code ist eine Fehlerquelle. Gerade im Bootloader, der ja, 
wie Du oben richtig geschrieben hast, das Herzstück, weil die 
Update-Fähigkeit, darstellt.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

PunchBoy schrieb:
> Das "in keiner Weise" bezweifle ich wiederum. Ich muss ja (so verstehe
> ich die Dokumentation) jeder Funktion

 Nur denen, die sich im Bootloader befinden. Man nimmt den Namen der
 Funktion, kopiert diese eine Zeile nach oben und fügt den Namen der
 Sektion dazu.
 Nennt sich Copy&Paste

> und jeder globalen Variable die Section zuweisen.

 Was haben Variablen mit Flash zu tun ?

PunchBoy schrieb:
> Da mein Bootloader doch recht umfangreich ist (sollte nicht so sein, ich
> weiß, ist aber der Anwendung und der Historie geschuldet), müsste ich an
> mehreren Stellen die Section mit definieren.

 Nein.

von PunchBoy (Gast)


Lesenswert?

Marc V. schrieb:
> Was haben Variablen mit Flash zu tun ?
>
> PunchBoy schrieb:
>> müsste ich an mehreren Stellen die Section mit definieren.
>
>  Nein.

Variablen haben mit dem Flash nichts zu tun, da war ich gedanklich 
falsch unterwegs. Der Gedanke kam daher, dass ein paar Daten (natürlich 
nicht Variablen) per PROGMEM im Flash abliegen.

Diesen Daten müsste ich, genau wie jeder einzelnen Funktion, die Section 
zuweisen.

Es ist aber, wie gesagt, eine gute Lösung. Ich werde mir überlegen, ob 
mir die Vereinfachung beim Linken das (geringe) Risiko wert ist, damit 
noch einen Fehler einzubauen.

Zusammen mit Markus F.s
> arm-none-eabi-objcopy bl.elf --add-section application=app.elf fat.elf
habe ich damit zwei gute Lösungswege.

Danke für die Diskussion.
Die ich damit nicht schließen möchte, falls jemand noch eine andere Idee 
hat :-)

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.