xmega 256 USB Bootloader - Sprung aus Applikation

Gast #4525779
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
Gast #4526123
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
Gast #4526435
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.
Gast #4526646
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.
Gast #4526709
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...
(Firma: TravelRec.) Persönliche Seite #4526724
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.
Gast #4526734
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.
(Firma: TravelRec.) Persönliche Seite #4526939
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.
Gast #4526966
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...
Gast #4527047
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren