Hallo Leute, ich verwende einen XMEGA256A3U von Atmel. Ich habe bereits einen Bootloader geschrieben und diesen auch in den Flash unter der Wordadresse 0x20000 hinterlegt. Wenn ich mit den AVRSTUDIO das BOOTRST Fuse auf Bootloader stelle, dann startet nicht meine Application sondern der Bootloader. Soweit so gut nun zu meinem Problem: Wie kann ich den Bootloader aus der Application starten. Ich habe gelesen das man dies mit einem Extended Indirect Jump (eijmp) macht. Dies ist notwendig da ich mehr als 64kByte Flash habe. ich habe dies im Internet bereits gefunden jedoch hat es nicht funktioniert: asm volatile ( "ldi r30, 0x02" "\n\t" // set up EIND "sts 60, r30" "\n\t" "ldi r30,0x00" "\n\t" //indirect call address "ldi r31,0x00" "\n\t" //16bit address z "eijmp" "\n\t" Ich habe daraus eine Funktion erstellet und rufe diese auf. void Jump_To_Bootloader(void) { #asm cli ; Disable Interrupts ldi r30,0x02 ; Set Up EIND to 0x02 sts 60,r30 ; ldi r30,0x00 ; Indirect call adress ldi r31,0x00 ; Indirect call adress eijmp ; Jump to bootloader adress #endasm } Jedoch scheint da ein Fehler drin zu sein. Ich kenne mich leider nicht perfekt mit Assembler aus. Vielleicht kann mir jedmand ja einen Hinweis geben
:
Gesperrt durch Moderator
Hi >Wie kann ich den Bootloader aus der Application starten. Ich habe >gelesen das man dies mit einem Extended Indirect Jump (eijmp) macht. >Dies ist notwendig da ich mehr als 64kByte Flash habe. Wieso? Ein simpler 'jmp' kann 4MWord adressieren. MfG Spess
Ich habe das Gefühlt das die Speicheradresse für EIND falsch ist.
Ich würde es mal so versuchen:
1 | void(* jump_to_bootloader)(void) = (void (*)(void))(BOOT_SECTION_START/2+0x1FC/2); |
2 | EIND = BOOT_SECTION_START>>17; |
3 | jump_to_bootloader(); |
Wobei der Offset der Einsprungadresse 0x1FC natürlich von dir angepasst werden muss.
:
Bearbeitet durch User
Ich hab mich jetzt nicht sehr lange mit deinem Problem beschäftigt, aber bei Atmel sieht das anders aus. http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_EIJMP.html OUT und STS sind nicht äquivalent!
:
Bearbeitet durch User
Coole Seite kann ich noch nicht vielen Dank für die Infos ich werde es gleich mal ausprobieren.
Hat leider auch nicht funktioniert. Ich versuche es jetzt mal mit dem Debugger. Jedoch habe ich mit dem Debugger noch so meine Probleme. Ich downloade gerade das aktuelle AVR Studio.
Hi, vielleicht kannst Du Dir da etwas herauspicken: http://www.avr-praxis.de/forum/entry.php?77-Starten-des-Bootloaders-aus-der-eigenen-Applikation Hier nochmal besser beschrieben: http://www.avr-praxis.de/forum/showthread.php?759-Programmer-und-Developmenttool-f%FCr-Xmega-A1-USB-Mikrocontrollermodul Gruß Dieter
Genau von ARV-Praxis habe ich den Code ja auch. Jedoch funktioniert es bei mir nicht. Ohne den Debuger sehe ich auch nicht wohin der PC springt.
Johann schrieb: > :-) > > Diese Zeile überfordert mich ein wenig :-) Funktioniert aber. Ich habe mal den Einsprungoffset weggenommen (also Einsprung direkt an den Anfang des Laders) und ein typedef eingeführt:
1 | #include <avr/io.h> |
2 | |
3 | typedef void (*bldr_t)(void) __attribute__((noreturn)); |
4 | |
5 | int main(void) |
6 | {
|
7 | const bldr_t jump_to_bootloader = (bldr_t)(BOOT_SECTION_START/2); |
8 | EIND = BOOT_SECTION_START>>17; |
9 | jump_to_bootloader(); |
10 | |
11 | return 0; |
12 | }
|
Das macht der Compiler draus:
1 | .global main |
2 | .type main, @function |
3 | main: |
4 | /* prologue: function */ |
5 | /* frame size = 0 */ |
6 | /* stack size = 0 */ |
7 | .L__stack_usage = 0 |
8 | ldi r24,lo8(2) |
9 | out 0x3c,r24 |
10 | ldi r30,0 |
11 | ldi r31,0 |
12 | eicall |
:
Bearbeitet durch Moderator
Danke für die Info Jörg, aber macht der eicall nicht einen Sprung und legt die Rücksprungadresse auf den Stack ab so das er dann wieder zurückspringt und es dann zu Problemen kommt? Kannst Du vielleicht noch etwas zu diesen 2 Zeilen schreiben was diese genau machen? typedef void (*bldr_t)(void) __attribute__((noreturn)); const bldr_t jump_to_bootloader = (bldr_t)(BOOT_SECTION_START/2);
Johann schrieb: > aber macht der eicall nicht einen Sprung und legt die Rücksprungadresse > auf den Stack ab Ja, macht er. > so das er dann wieder zurückspringt und es dann zu > Problemen kommt? Wer ist „er“? Wer springt denn da wann zurück? Dein Bootloader? Warum sollte er? Allerdings sollte der Bootloader den Stackpointer (re-)initialisieren. > Kannst Du vielleicht noch etwas zu diesen 2 Zeilen schreiben was diese > genau machen? C-Buch, Kapitel über Zeiger? > typedef void (*bldr_t)(void) __attribute__((noreturn)); Vereinbart einen Datentypen (namens „bldr_t“) für einen Funktionszeiger, wobei die Funktion keinen Rückgabewert hat (void), ja nicht einmal überhaupt zurückzukehren gedenkt (attribute noreturn), und keine Parameter übernimmt ((void)). > const bldr_t jump_to_bootloader = (bldr_t)(BOOT_SECTION_START/2); Bildet einen solchen Zeiger per Typecast aus einer Konstante.
das ist dann aber schon advance c. In meinem Bootloader ist eine komplette Intitialisierungsroutine. Jedoch bin ich mir gerade nicht sicher ob ich da den Stackpointer zurücksetze ich versuche das nachschlagen. Danke für die Erklärung. Mit Pointer auf Funktionen selber muste ich noch nicht arbeiten. Aber ich werde mich da mal im Internet belesen.
Johann schrieb: > das ist dann aber schon advance c. Nö, nur Zeiger bis zu Ende verstanden. ;-) Allerdings gebe ich gern zu, dass das Abtrennen des Typs in einem typedef hier wirklich sinnvoll ist.
So den Debugger habe ich installiert nun bin ich aber wirklich mal gespannt :-)
Hi, sollte es nicht reichen, wenn Johann den Offset in sein Konstrukt einbaut und auf die word-address (das Teilen durch 2) umstellt - (0x40000 + 0x1FC) / 2 = 0x200FE: AVR 1916: Internal firmware request: The user application can decide to start a DFU session. This can be achieved by jumping to a specific address in the boot loader firmware. The entry point to start a DFU session initiated by a user application firmware jump is BOOT_SECTION_START + 0x1FC for all devices Also:
1 | void Jump_To_Bootloader(void) |
2 | {
|
3 | #asm
|
4 | cli ; Disable Interrupts |
5 | ldi r30,0x02 ; Set Up EIND to 0x02 |
6 | sts 60,r30 ; |
7 | ldi r30,0xFE ; Indirect call adress |
8 | ldi r31,0x00 ; Indirect call adress |
9 | eijmp ; Jump to bootloader adress |
10 | #endasm
|
11 | }
|
Wobei ich bei "word-address" (jetzt auf 0x20000 angepasst) auf extrem wackligen Boden stehe ...
Dieter Frohnapfel schrieb: > sollte es nicht reichen, wenn Johann den Offset in sein Konstrukt > einbaut und auf die word-address (das Teilen durch 2) umstellt - > (0x40000 + 0x1FC) / 2 = 0x200FE: Zumindest mit dem AVR-GCC nicht: der hat nur 16 bit breite Zeiger. > Internal firmware request: The user application can decide to start a > DFU session. This can be achieved by jumping to a specific address in > the boot loader firmware. Setzt aber voraus, dass er einen DFU-Bootloader installiert hat. Ich habe aber den Eindruck, dass es sein eigener Bootloader ist.
Jörg Wunsch schrieb: > Zumindest mit dem AVR-GCC nicht: der hat nur 16 bit breite Zeiger. Ja, deswegen auch EIND oder?
So Jung ich habe mit dem Debugger das ganze genau untersucht. Wenn ich per RS232 ein Kommando an den XMEGA sende dann wird wirklich ein Sprung zur Adresse 0x20000 ausgeführt. Dort steht auch mein Bootloader drin. Dieser wird aber anscheinend nicht richtig abgearbeitet. Ich kann mit dem Debugger die Bootsection anzeigen dort steht auf jedenfall etwas drin. Nur bleibt der Mikrocontroller dann hängen. Wenn ich jedoch das BOOTRST Fuse auf Bootloader stelle, dann startet der Booloader richtig. Ich verwende eine RS232 Interrupt um die neuen RS232 Flash Daten zu empfangen.
Johann schrieb: > Ich verwende eine RS232 Interrupt um die neuen RS232 Flash Daten zu > empfangen. IVSEL gesetzt? Ansonsten kann man einen Bootloader auch gepollt schreiben.
Du solltest bedenken, dass wenn du von der Applikation in den Bootloader springst, dass alle Register so bleiben wie sie sind. Also würde ich vorher einen Zustand herstellen, der quasi dem Reset entspricht. Also alle Interrupts voher deaktivieren, RTC deaktivieren... Arbeitest du im Bootloader mit Interrupts? Wenn ja musst du den ISR-Vektor noch verbiegen, das kannst du über BOOTRST und IVSEL.
Der Programm Counter bleibt bei 0x2021E stehen. Als wenn es eine Endlosschleife ist wie bei While(1)
1 | ;0000 009A mikrocontroller_init(); |
2 | RCALL _mikrocontroller_init |
3 | ;0000 009B |
4 | ;0000 009C while(1) |
5 | _0x15: |
6 | ;0000 009D { |
7 | ;0000 009E } |
8 | RJMP _0x15 |
9 | ;0000 009F } |
10 | _0x18: |
11 | RJMP _0x18 |
12 | ;.FEND |
:
Bearbeitet durch Moderator
Ich arbeite in der Application Firmware und der Bootloader Firmware mit mit Interrupts. Ich habe natürlich nicht den Interruptverktor verbogen :-) Ok dann werde ich IVSEL und BOOTRST konfigurieren. Das ist doch alles total ... Man ist kurz vor dem Ziel und es geht nichts. Das ist heute wieder echt so ein Tag :-(
Hallo Johann, verwendest Du den Bootloader von dort? http://www.avr-praxis.de/forum/showthread.php?759-Programmer-und-Developmenttool-f%FCr-Xmega-A1-USB-Mikrocontrollermodul Dann solltest Du auch das berücksichtigen: Die Einsprungadresse für den Bootloader ist 0x21FF0 (word address 0x10FF8). Die Einsprungadresse bleibt für folgende Bootloaderversionen gleich.
Johann schrieb: > Ne ich habe einen eigenen geschrieben. Dann wirst Du ja auch Deine eigene Einsprungadresse kennen ... oder?
Meiner setzt den CLOCk auf 32MHZ konfiguriert einen RS232 Receiver Interrupt. In der Interruptroutine werden dann Daten empfangen. In der RS232 Interruptroutine verwende ich noch einen Hardwaretimer. Diesen benutze ich zum Abbruch der RS232 Routine falls nicht genügend Daten kommen. Der Timer benutzt aber keine Interruptroutine. Das Hauptprogramm ist das While(1) Ich verstehe Atmel nicht. Ich könnte ja einfach aus der Application herraus das BOOTRST Fuse verändern anschließnd einen Reset auslösen und alles wäre wunderbar. Das hätte mich nur wenige Minuten gekostet jetzt glüht mein Kopf und nichts geht.
Ich dachte die Einsprungadresse ist die Adresse 0x20000? Das ist doch der Startbereich vom Bootloader. Ich dachte diese wird dann abgearbeitet. Oder liege ich da falsch? ich habe mal meinen Bootloader angehängt
Johann schrieb: > Ich könnte ja einfach aus der Application herraus das BOOTRST Fuse > verändern anschließnd einen Reset auslösen und alles wäre wunderbar. Der Sinn einer Fuse ist es aber, nun gerade nicht durch die Applikation änderbar zu sein. Nur, weil du gerade deine Software nicht im Griff hast, brauchst du jetzt nicht die Schuld beim Hardwarehersteller suchen … Es steht dir ja völlig frei, die Fuse immer zu setzen und bei Bedarf einfach per Watchdog einen Reset zu veranlassen. Dann hast du das Problem halt andersrum, der Bootloader muss dann entscheiden, wann und wie er die Applikation anspringen will.
Johann schrieb: > ich habe mal meinen Bootloader angehängt Sourcecode wäre einfacher zu entziffern … > Ich dachte die Einsprungadresse ist die Adresse 0x20000? Ja, ist sie auch.
:
Bearbeitet durch Moderator
Sorry, aber der Frust sitzt momentan sehr tief. Ich bin für jede Hilfe sehr dankbar Ich habe mal das Main-File beigefügt und meine Initialisierungsroutine.
Johann schrieb: > Der Programm Counter bleibt bei 0x2021E stehen. Als wenn es eine > Endlosschleife ist wie bei While(1) Ist es ja auch, das ist deine while(1)-Schleife aus main(). Was sollte denn in dieser sonst noch passieren? Alles, was passiert, muss ja über einen Interrupt passieren. Am Einsprungpunkt des Codes erfolgt ein Stück Initialisierung, dann ein Sprung auf Byteadresse 0x4043a:
1 | … |
2 | (Hier wird übrigens SP initialisiert) |
3 | 402a8: ef ef ldi r30, 0xFF ; 255 |
4 | 402aa: ed bf out 0x3d, r30 ; 61 |
5 | 402ac: ef e5 ldi r30, 0x5F ; 95 |
6 | 402ae: ee bf out 0x3e, r30 ; 62 |
7 | 402b0: c0 e0 ldi r28, 0x00 ; 0 |
8 | 402b2: d0 e3 ldi r29, 0x30 ; 48 |
9 | 402b4: 1c 94 1d 02 jmp 0x4043a ; 0x4043a |
Dort steht offenbar main():
1 | 4043a: d7 d1 rcall .+942 ; 0x407ea |
2 | 4043c: ff cf rjmp .-2 ; 0x4043c |
3 | 4043e: ff cf rjmp .-2 ; 0x4043e |
Die zweite Endlosschleife scheint dein Compiler (welcher auch immer es ist, hast du uns nicht verraten) nach main() hinzuzufügen, die erste ist deine eigene. 0x407ea ist die Init-Routine, die dein Compiler auch stur so wie geschrieben aufdröselt:
1 | 407ea: 2a de rcall .-940 ; 0x40440 |
2 | 407ec: 39 de rcall .-910 ; 0x40460 |
3 | 407ee: 7a de rcall .-780 ; 0x404e4 |
4 | 407f0: 45 df rcall .-374 ; 0x4067c |
5 | 407f2: 4b df rcall .-362 ; 0x4068a |
6 | 407f4: 82 df rcall .-252 ; 0x406fa |
7 | 407f6: a3 df rcall .-186 ; 0x4073e |
8 | 407f8: 78 94 sei |
9 | 407fa: 08 95 ret |
So ich habe mir das List-File noch mal genauer angeschaut. Dort steht in Adresse 0x020000 der Resetvector vom Bootloader. Demnach habe ich mir die Resetroutine angeschaut. Dort wird auf jedenfall das IVESL Bit 1 1 gesetzt und somit Interrupt Vector im Bootbereich platziert. Durch den Debugger kann ich auch feststellen das ich im Bootloadebereich bin. Jedoch wenn ich ein Kommando per RS232 Sende komme ich nicht in die RS232 Routine vom Booloader.
Johann schrieb: > komme ich nicht in die RS232 Routine vom Booloader. PMIC-Setup? Ich müsste mir die Details für dieses Teil jetzt im Datenblatt durchwälzen. Das wäre aber potenziell ein Unterschied zwischen dem, was dir deine Applikation beim Einsprung in den Bootloader hinterlässt und dem, was du beim Anspringen des Bootloaders per Reset hast. Ich würde wohl nach möglichster Möglichkeit versuchen, in einem Bootloader nur minimal an der Hardware herumzufummeln (nur das wirklich für den Loader nötige) und ohne Interrupts auszukommen. Ob du nun da in einem while(1) im main() Däumchen drehst oder an der Stelle den UART-Rx pollst, bleibt sich schließlich gleich.
:
Bearbeitet durch Moderator
Jörg Wunsch schrieb: > PMIC-Setup? Lass dir doch mal die PMIC-Register dumpen einerseits wenn du die BOOTRST-Fuse gesetzt hast und andererseits wenn dein Loader von der Applikation aus angesprungen worden ist.
Wenn mit AVR das Fuse-Bit BOOTRST veränder, so das er aus dem Bootloader startet (beim Power Up) dann funktioniert ja auch die RS232 Interruptroutine. Ich kann dann auch wieder zurückspringen auf dem Application bereich und auch dort funktioniert dann die RS232-Routine. Ich werde mal eine LED Toggeln wenn ich im Bootloader bin. Und eine 2 LED einschalten wenn ich im Bootloader in die RS232 Routine kommen. --> Oldscool halt.
Ok ich habe den Code geändert. Wenn die XMEGA Bootloader Initialisierung abgeschlossen ist schalte ich eine LED an. Diese leuchtet auch. Demnach muss der XMEGA vollständig initialisiert sein. Jedoch wenn ich einen RS232 Befehl sende wird die 2. LED in der USART Interruptserviceroutine nicht gesetzt. Dies ist schon ein Hinweis das mit dem Interrupt etwas nicht in Ordnung ist. Da habe ich wenigstens etwas wo ich den Fehler suchen kann.
Johann schrieb: > Demnach muss der XMEGA vollständig initialisiert sein. Ja klar, du bist ja schließlich in deiner while(1)-Schleife in main(). Wie ich schon schrob: guck dir den Interruptcontroller an.
Ich werde dann noch mal mit dem Debugger alles prüfen und hoffentlich den Fehler finden.
Ich konnte leider nichts finden. Was mir jedoch aufgefallen ist. Wenn ich aus der Application den Jump in den Bootloader mache, dann komme ich auch in den Bootoader rein und eine LED wird angeschaltet. Wenn ich jedoch anschließend die Betriebsspannung vom Board entferne und anschließend diese wieder aktiviere, dann bin ich wieder im Booloader und die Interruptserviceroutine von der USART funktioniert und alles geht :-( Nach einen Power Up sollte doch die Applikation wieder starten und nicht der Bootloader. Das BOOTRST Fuse Bit steht auf Application und wird auch nicht von mir verändert.
So ich HABE DEN FEHLER GEFUNDEN: Ich habe aus der USART_INTERRUPT_SERVICE_ROUTINE den Sprung zum Bootloader gemacht. Das scheint so nicht zu gehen oder ich habe etwas nicht richtig gelöscht. Wenn ich in der Interrupt Service Routine nur ein globales Flag setze und dieses in der Mainroutine abfrage und dann beim gesetzten Flag den Sprung zum Bootloader ausführe dann geht es auch sofort. Mir ist jedoch aufgefallen das wenn ich im Bootloader bin und die Versorgungspannung ausschalte und anschließend wieder Einschalte bootet der Mikrocontroller immer automatisch aus dem Booloaderbereich. Ist das eine Sicherheitsfunktion so das ich aktive erst wieder den Bootloaderbereich verlassen muss? Dies ist eigentlich sehr gut, denn wenn beim Flashen der Strom ausfällt könnte ich in aus der Application herraus nicht mehr in den Bootloader springen, da die Application ja bereits gelöscht ist und nur bis zu einem gewissen Prozentsatz neu geflasht wurde.
Solange du in einer ISR bist sind globale Interrupts aus (ISRs sind normalerweise nicht unterbrechbar) Und wenn du aus der ISR einen Sprung machst, denkt der Controller das du immer noch in der ISR bist. Der ASM-Befehl RETI aktiviert beim Beenden der ISR wieder die globalen Interrupts. Ich kenne mich mit den XMegas nicht aus, die haben ja so ein tolles Eventsystem. Bei den normalen Megas, sollte eigentlich ein sei() reichen, was du vermutlich in deinem Bootloadercode auch tust. Vor deinem Sprung sollte man alle ISRs deaktivieren. Und noch was, eigentlich ist die elegante Methode einen Reset auszulösen, den Watchdog ablaufen zu lassen. Danach wird der Controller auch Hardwareseitig komplett neu initialisiert. Du hast ja geschrieben das bei einem Reset bei dir zuerst der Bootloader startet.
Christian K. schrieb: > Ich kenne mich mit den XMegas nicht aus, die haben ja so ein tolles > Eventsystem. Insbesondere haben sie einen Interruptcontroller (wies ich nicht oben ausdrücklich darauf hin?), und der denkt natürlich auch, dass die zugehörige ISR nach wie vor in Bearbeitung ist …
Ich bin davon ausgegangen das mein Resetvektor im Bootloader alles neu Initialisiert.
Johann schrieb: > Ich bin davon ausgegangen das mein Resetvektor im Bootloader alles neu > Initialisiert. Beitrag "Re: Jump zum Bootloader beim XMEGA"
Christian K. schrieb: > Solange du in einer ISR bist sind globale Interrupts aus (ISRs sind > normalerweise nicht unterbrechbar) Nicht beim XMEGA. Dort kann ein höher priorisierter Interrupt einen niedriger priorisierten unterbrechen. Aber Du hast schon Recht, irgendwann muss schon ein passendes reti kommen, um die noch laufende ISR abzuschließen.
Mein Resetvektor im Bootloader verbiegt ja auch die Interrupttabelle. Aber über welchen Befehl kann ich dann das RETI löschen so das mein Bootloader nicht mehr denkt das er noch im Interrupt ist?
Ein RETI macht das gleiche wie ein RET, oberstes Element des Stacks in den PC laden und zusätzlich das I-Flag im SREG setzen. Ich konnte jetzt keine Informationen finden ob das RETI bei einem XMega mehr macht. Da ein XMega ein Interrupt Controller hat, würd ich dir mal raten das Disassembly einer ISR anzuschauen, um zu checken ob am Ende der ISR vor dem RETI noch irgendwelche anderen Registerbits verändert werden.
:
Bearbeitet durch User
Johann schrieb: > Aber über welchen Befehl kann ich dann das RETI löschen so das mein > Bootloader nicht mehr denkt das er noch im Interrupt ist? Warum zum Geier™ tust du nicht endlich mal, was ich dir die ganze Zeit lang predige, und guckst dir das Kapitel zum Interruptcontroller im Datenblatt an? Ich mein', ich klapp' das Ding auf, und es guckt mich ein Statusregister an, bei dem sowas steht:
1 | Bit 0 LOLVLEX: Low-level Interrupt Executing |
2 | This flag is set when a low-level interrupt is executing or when the interrupt handler has been interrupted by an |
3 | interrupt from higher level or an NMI. The flag will be cleared when returning (RETI) from the interrupt handler. |
Gut zu wissen das ein RETI bei einem XMega mehr macht. Im Offiziellen "AVR Instruction Set Manual" und im Kapitel Instruction Set Summary eines XMegas-Datenblatts gibt es keinen Verweis darauf. @Johann Jetzt hab ich mir mal das Datenblatt vom Xmega A3U geladen, aber ich find die zitierte Passage nicht. Auch die Volltextsuche bring nichts. EDIT: Atmel hat bei den Datenblättern der XMegas outgesourced. Im Xmega AU hab ich es gefunden.
:
Bearbeitet durch User
Hi >Jetzt hab ich mir mal das Datenblatt vom Xmega A3U geladen, aber ich >find die zitierte Passage nicht. Auch die Volltextsuche bring nichts. Die interessanten Sachen stehen im entsprechenden Manual: http://www.atmel.com/Images/Atmel-8331-8-and-16-bit-AVR-Microcontroller-XMEGA-AU_Manual.pdf MfG Spess
spess53 schrieb: > Die interessanten Sachen stehen im entsprechenden Manual: Ja, diese doppelten Datenblätter sind Scheibenkleister. Wenn sie wenigstens im per-device datasheet dann die unnötigen Kapitel-stubs gleich weggelassen hätten, aber so erwecken die Dinger immer noch den Eindruck, als würden sie alles abdecken, obwohl man in Wirklichkeit darin nur einige ganz wenige Details findet, während der große Rest im Familien-Datenblatt steht. Aber wenn man irgendwie ernsthaft was mit einem Xmega macht, sollte man das eigentlich kennen. Christian K. schrieb: > Im Offiziellen "AVR Instruction Set Manual" und im Kapitel Instruction > Set Summary eines XMegas-Datenblatts gibt es keinen Verweis darauf. Es gibt auch keinen Hinweis drauf, dass bspw. ein OUT auf ein bestimmtes Portregister ein Pin toggeln kann oder ein Interruptflag löschen. Spätestens, wenn man aber mal irgendwie versucht nachzudenken, wie sie die Interruptpriorisierung gelöst haben können, wird einem klar, dass der Interruptcontroller auf irgendeine Weise wissen muss, dass gerade eine ISR in Bearbeitung ist, denn nur so kann er verhindern, dass bei global zugelassenen Interrupts ein Interrupt gleicher oder niederer Priorität die aktuelle ISR unterbricht.
:
Bearbeitet durch Moderator
Hallo Leute, ich versuche im Moment den Bootloader mit der Version 1.04 auf meinem AtxMega63A3U zum Laufen zu bekommen. Ich möchte den bootloader aus meiner Applikation starten. Die Abfrage des IOs zum Starten des Bootloaders habe ich ausgebaut. So dass dieser starten sollte. Kompiliert habe ich mit IAR. Die Fusebits habe ich auf die Applikaiton gestellt. In meiner Applikation benutze ich die USB-Schnittstelle um mit dem PC zu kommunizieren. Mir fehlt jetzt noch der Jump aus der Applikation in den Bootloader. Ich habe zwar schon einiges hier gelesen aber ich kriege es nicht hin. Hat jemand dies schon zuverlässig lösen können? Danke. Gruß, Georg.
Georg X. schrieb: > Hat jemand dies schon zuverlässig lösen können? Bitte öffne einen eigenen Thread, dein Problem hat nur den Namen gemeinsam mit dem Problem, welches in diesem Thread hier behandelt worden ist (verklemmter Interruptcontroller). Ach, und beschreibe dein Problem umfassend, insbesondere was du im Moment tust.
:
Bearbeitet durch Moderator
Georg X. schrieb: > Mir fehlt jetzt noch der Jump aus der Applikation in den Bootloader. Unabhängig vom Device sollte das hier funzen:
1 | void(* jump_to_bootloader)(void) = (void (*)(void))(BOOT_SECTION_START/2+0x1FC/2); |
2 | jump_to_bootloader(); |
:
Bearbeitet durch User