Forum: Mikrocontroller und Digitale Elektronik xmega 256 USB Bootloader - Sprung aus Applikation


von Daniel Held (Gast)


Lesenswert?

Hallo Forum,
ich verzweifle gerade dabei den USB Bootloader von Atmel (neu mit iar 
kompiliert wegen Änderung Pin) aus meiner Applikation heraus zu starten.
Im Normalfall soll nur die Applikation starten (Fuse gesetzt) und nur 
bei Bedarf angesprungen werden.
Wenn ich die Fuse auf Bootloader stelle, funktioniert alles bestens und 
auch, wenn noch keine Applikation geladen ist.

Beim Aufruf aus der Applikation startet trotzdem die Applikation nach 
einer kurzen Verzögerung.

Hier mein Aufruf:
void(* start_bootloader)(void) = (void 
(*)(void))(BOOT_SECTION_START/2+0x1FC/2);

...

udc_detach();
udc_stop();
delay_ms(250);
cpu_irq_disable();
start_bootloader();

Das entsprechende Pin liegt fest auf GND.
Die gleiche Funktion benutze ich auch bei einem xmega128, wo sie perfekt 
funktioniert.

Ich hoffe, ihr könnt helfen.
Gruß Daniel

von Basti (Gast)


Lesenswert?

Aus Erfahrung kommt der Bootloader eh nicht mit funktionsfähigem USB 
hoch.

1. EEPROM Flag schreiben
2. uC Reset
3. direkt nach dem Start deiner eigenen Applikation EEProm checken und 
in den Bootloader springen

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Kannst Du mit SRAM machen, wird bei RESET nicht gelöscht. Braucht man 
kein EEPROM für.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Daniel Held schrieb:
> Die gleiche Funktion benutze ich auch bei einem xmega128,

Wenn es beim 128er funktioniert, sollte es bem 256er mit den richtigen 
Einstellungen auch funktonieren.

von Daniel Held (Gast)


Lesenswert?

Knut B. schrieb:
> Wenn es beim 128er funktioniert, sollte es bem 256er mit den richtigen
> Einstellungen auch funktonieren.

Ja, das habe ich auch gedacht. Die Sprünge sind komplett identisch, 
abgesehen von der BOOT_SECTION_START.

Knut B. schrieb:
> Kannst Du mit SRAM machen, wird bei RESET nicht gelöscht. Braucht man
> kein EEPROM für.

Ist das echt so einfach? Eine Variable setzen, Reset und dann der 
Sprung?

Basti schrieb:
> 1. EEPROM Flag schreiben
> 2. uC Reset
> 3. direkt nach dem Start deiner eigenen Applikation EEProm checken und
> in den Bootloader springen

Also dann nur einen direkten Sprung zu BOOT_SECTION_START, oder?

Danke euch.

von Daniel Held (Gast)


Lesenswert?

Habe jetzt den Tip von hier: 
http://www.avrfreaks.net/forum/xmega128a4u-dfu-bootloader-and-flip-solved?name=PNphpBB2&file=viewtopic&t=122461
umgesetzt.
Es scheint, dass der Bootloader angesprungen wird, aber das USB-Device 
wird nicht angezeigt, bzw. wohl nicht initialisiert :-(

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Bist Du sicher, dass Du die richtigen Adressen angegeben hast? Der 256er 
hat ja doppelt so viel Flash und doppelt so viel SRAM.

von Daniel Held (Gast)


Lesenswert?

Knut B. schrieb:
> Bist Du sicher, dass Du die richtigen Adressen angegeben hast? Der 256er
> hat ja doppelt so viel Flash und doppelt so viel SRAM.

Danke Knut, das war ein Problem - Asche aufs Haupt.
Die Adresse habe ich auf 0x401FC geändert, dass funktioniert jetzt auch.
Allerdings habe ich ein Problem mit dem Eeprom: die Funktionen 
nvm_eeprom_read/write_byte und die "normale" eeprom_read/write_byte - 
zeigen die auf den selben Speicherbereich?
Wenn ja, müsste ich das Bootloaderbyte mit in meine Eeprom-Struktur 
aufnehmen und über nvm_eeprom_read_byte lesen, oder?

Im Moment startet er immer den Bootloader, deshalb vermute ich, dass das 
Bootloaderbyte mit meiner Struktur überschrieben wird.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Daniel Held schrieb:
> zeigen die auf den selben Speicherbereich?

Es gibt 2 EEPROM-Zugriffsmöglichkeiten, über den NVM adressiert und über 
den Speicher adressiert. Erstere greift auf 0x0000 + Adresse zu und 
letztere auf 0x1000 + Adresse.

: Bearbeitet durch User
von Basti (Gast)


Lesenswert?

@Knut
Mit dem Reset meinte ich den über den Watchdog. Mit dem "soft" Reset hat 
es bei mir auch nie geklappt... Seit dem ich über den Watchdog-Reset 
gehe, hatte ich keine Probleme mit dem USB-Bootloader mehr.

Aber auf AVR-Freaks steht ja alles...

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Basti schrieb:
> Mit dem "soft" Reset hat
> es bei mir auch nie geklappt... Seit dem ich über den Watchdog-Reset
> gehe, hatte ich keine Probleme mit dem USB-Bootloader mehr.

Der Soft Reset macht exakt das Gleiche, wie der Watchdog. Es gibt keinen 
(programm-) technischen Unterschied. Das Software-Reset Bit ist durch 
das CCP-Register geschützt und muss vor Benutzung entsperrt werden.

von Basti (Gast)


Lesenswert?

Hm, ist schon wieder eine Weile her...
Gabs nicht zwei Reset-Möglichkeiten am XMega -> Hard-/Soft-Reset ?!

Jedenfalls war das Ergebnis, dass der Controller in den Reset gegangen 
ist und USB am Bootloader nicht sauber hoch kam. Vielleicht ist es auch 
nur eine Timing-Geschichte, die der Watchdog zum Vorteil hat.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Der Watchdog braucht halt Zeit zum Ablaufen. Wenn bis dahin die Hardware 
noch etwas ausgegeben hat, ist sie vielleicht dann fertig damit, bis der 
Wachhund zubeißt. Das ist natürlich etwas Anderes, als wenn der Reset 
20µs nach Ausführen des Befehls aktiv wird. Ab Resetauslösung verhalten 
sich alle Resetquellen genau gleich, da sie dieselbe Hardware im 
Controller triggern.

von Daniel Held (Gast)


Lesenswert?

Hmmm, es will einfach nicht klappen :-(

Ich habe jetzt folgendes drin:
#define ADDR_APP_RUN  0x00
#define APP_RUN       0xFF
#define BL_RUN        0x00
...
int main (void)
{
  // Check boot flag
  Test = eeprom_read_byte(&(pEeprom->StartBL));
  if (Test == BL_RUN )
  {
     asm("jmp 0x401FC");
  }
...
  eeprom_write_byte(&(pEeprom->StartBL), APP_RUN);
...
}

void UpdateFW(void)
{
  udc_detach();
  udc_stop();
  delay_ms(500);
  eeprom_write_byte(&(pEeprom->StartBL),BL_RUN);
  cpu_irq_disable();
  CPU_CCP = CCP_IOREG_gc;
  RST.CTRL = RST_SWRST_bm;
  do {} while (1);
}

Leider wird der Bootloader jetzt nicht mehr angesprungen. Als ich das 
Programm ohne Bootloader im Debug hatte, stimmte der Eintrag bei Test 
jeweils...

von Daniel Held (Gast)


Lesenswert?

Juhu, es funktioniert :-)
Es lag wohl am setzen der Resetregister und am abschalten der 
Interrupts.

cpu_irq_disable();
CPU_CCP = CCP_IOREG_gc;
RST.CTRL = RST_SWRST_bm;

@Knut und @Basti
Danke für eure Hilfe - ist eben doch immer drauf Verlass.

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.