Hallo Forum,
ich habe mich nun die letzten Tage in die Thematik des Bootloaders
eingearbeitet. Die Funktionsweise ist mir bekannt und ich habe auch
1*10^7 Beispiele und Demos gefunden. Leider handelt es sich dabei immer
um "Stand-Alone" Bootloader, die eine anschließende Programmierung des
Nutzprogrammes über diesen erfordert.
Ich würde jedoch gerne mein Nutzprogramm mit einem Bootloader ergänzen.
Dies hat den Vorteil, dass ich das Gerät im geöffneten Zustand via ISP
und im geschlossenen Zustand via CAN programmieren kann.
In den Musterbeispielen wird einfach die komplette .text Section in den
Bootloader Bereich verschoben und genau das will ich ja nicht.
Ich muss also das ".bootsection" Attribut verwenden um den Loader an
seine richtige Position zu verschieben.
Nun meine Frage: Der Bootloader besteht ja aus mehreren Funktionen, wenn
ich das Attribut mehrfach verwendet, meckert der Compiler, dass die
Funktionen sich gegenseitig überschreiben.
Außerdem ist mir die Thematik mit der main() Funktion noch nicht ganz
klar. Eigentlich bräuchte mein Programm ja zwei main() Funktionen, aber
das kann ja nicht funktionieren.
Gibt es eine Möglichkeit, dass ich diese zwei "quasi" unabhängigen
Programme einfach unter einen Hut bekomme? Kennt jemand ein Beispiel,
indem genau diese Thematik behandelt wird?
Vielen Dank im vorraus
Melanie
Melanie G. schrieb:> Eigentlich bräuchte mein Programm ja zwei main() Funktionen, aber> das kann ja nicht funktionieren.
Du hast es erfaßt, es geht nicht.
Du kannst vom 1. Hexfile die letzte Zeile entfernen und dann das 2.
anfügen.
Peter
Peter Dannegger schrieb:>> Eigentlich bräuchte mein Programm ja zwei main() Funktionen, aber>> das kann ja nicht funktionieren.>> Du hast es erfaßt, es geht nicht.
Das geht in gewissen Grenzen schon:
Im bootloader-Quelltext:
1
intmain(void)__attribute__((weak));
2
3
intmain(void){
4
execute_bootloader();
5
}
Durch das "weak"-Attribute lässt sich der Bootloader dann trotz
Namensüberschneidung mit dem Hauptprogramm linken.
Macht aber nur selten Sinn, z.B. bei alten Tinies ohne echten
Bootloader-Support.
Melanie G. schrieb:> Ich würde jedoch gerne mein Nutzprogramm mit einem Bootloader ergänzen.>> Dies hat den Vorteil, dass ich das Gerät im geöffneten Zustand via ISP>> und im geschlossenen Zustand via CAN programmieren kann.
Eine andere Möglichkeit wäre, der Bootloader erwartet nach jedem Reset
einen Nutzprogramm-File, ist dieser nicht vorhanden wird nach einer
kurzen Zeitspanne das vorhandene Nutzprogramm abgearbeitet.
Hallo
mit AVR-Studio gibt es eine Möglichkeit:
Einstellungen im AVR-Programmer unter "Program":
"Erase device..." und "Verify..." auf EIN
dann 1. Programm flashen.
Einstellungen im AVR-Programmer unter "Program":
"Erase device..." und "Verify..." auf AUS
dann 2.Programm flashen.
Mfg
>dass ich das Gerät im geöffneten Zustand via ISP>und im geschlossenen Zustand via CAN programmieren kann.
Definiere via CAN eine Nachricht die eine Funktion aufruft mit
eingeschaltetem Watchdog und einer While(1). Nach dem Absturz wird erst
Bootloader geladen, der wiederum eine Nachricht an deine Software
sendet, erhält der Bootloader innerhalb einer definierten Zeit eine
Antwort von deinem Programm, wird der uC beschrieben. So ähnlich mache
ich das, bloss nicht über CAN.
Hallo Melanie,
ich hab das so gelöst, durch 2 zusätzliche Sektionen im Linkerscript.
In der 1. section darf nur eine Funktion drin sein um sichszustellen,
das diese Funktion auch wirklich auf die angegebene Adresse kommt.
1
#define BOOT_SEC_SIZE_100 0x0100 /* BootLoader Start 0x1F00 im Makefile*/
2
#define BOOT_SEC_SIZE_200 0x0200 /* BootLoader Start 0x1E00 im Makefile*/
3
#define BOOT_SEC_SIZE_400 0x0400 /* BootLoader Start 0x1C00 im Makefile*/
4
#define BOOT_SEC_SIZE_800 0x0800 /* BootLoader Start 0x1800 im Makefile*/
dem Linker geb ich dann einfach mit:
override LDFLAGS =
-Wl,--section-start=.bootstart=0x1C00,--section-start=.bootloader=0x1C44
,-Map,$(PRG).map
die asm-befehle sind aus der ctors() geklaut und du solltest die je nach
Hardware auch von dort nehmen.
Das Problem Bootlader und User-Prog gemeinsam laden zu müssen
hatte ich auch schon mal bei einem ADUC832, ist sehr ähnlich gelagert
wie beim AVR.
Das "Zusammensetzen" der HEX-Files, wie es Peter Dannegger beschrieben
hat, funktioniert einwandfrei. Man muß halt dann das zusammengesetzte
Hex-File laden- ich finde das ist der geringste Aufwand.
Rangi Jones schrieb:> override LDFLAGS =>> -Wl,--section-start=.bootstart=0x1C00,--section-start=.bootloader=0x1C44
,-Map,$(PRG).map
>>>> die asm-befehle sind aus der ctors() geklaut und du solltest die je nach>> Hardware auch von dort nehmen.
Hallo Rangi,
bin neu im Umfeld ATMega und versuche dein Beispiel zu benutzen.
Ich habe im Linker Script die folgende Zeile eingegeben:
•
Beim Linken kommt dann aber Syntax Error. Irgendwie versteht er diese
Zeile nicht. Ich Programmiere einen ATMega88PA.
Das zweite ist das ich nicht verstehe wie ich aus ctors() die
Asm-Befehle klauen kann. Welche Datei ist das? Bin halt ein ATMega und
AVR Neuling und versuche gerade Schwimmen zu erlernen. Ich muß genau das
hinbekommen einen Bootloader der mit dem Hauptprogramm gemeinsam
Programmiert wird.
Ich habe den Beispiel Code in einer eigenen Datei in mein Projekt
eingebunden.
Kannst du oder irgend jemand mir bitte Helfen?
also den code kannst du dir am einfachsten aus dem listing ziehen. du
machst dir ein pojekt was kompiliert und rufst auf: "make lst". dann
wird dir eine myproject.lst gebaut. darin findest du vermutlich ganz
weit oben die vektor-tabelle mit dem resetvektor auf der 0:
1
00000000<__vectors>:
2
0:0c943e00jmp0x7c;0x7c<__ctors_end>
3
....
welches bei mir auf adresse 0x7c verweist. gehe zu adresse 0x7c und du
findest:
1
0000007c<__ctors_end>:
2
7c:1124eorr1,r1
3
7e:1fbeout0x3f,r1;63
4
80:cfefldir28,0xFF;255
5
82:d0e1ldir29,0x10;16
6
84:debfout0x3e,r29;62
7
86:cdbfout0x3d,r28;61
diese Befehle sind einfach in C-form umzusetzen.
jetzt zu den modifikationen im makefile:
da war ich in meinem post von damals wohl nicht detailliert genug und
hatte gehofft, dass die leute, die das brauchen schon selber wissen, wie
man eine section hinzufügt. also hier fehlt noch folgendes:
erklaerung: mit dem _attribut_ section erklaerst du, dass es eine
section soundso geben wird und diese funktion dort rein kommt. beim
linken wird dann diese section erstellt und per definition wird diese
auf die adresse 0x1c00 (je nach hardware) gelegt. alle sprungbefehle
laufen dann dorthin.
und ich betone nochmal: das ganze ist winavr !