mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR Goto Bootloader aus RXC_vect


Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
Ich habe ein etwas größeres Projekt und will dabei im laufenden Betrieb 
zum Bootloader wechseln können. Der Bootloader ermittelt aus einer Reihe 
von 'U'-Chars seine Baudrate (Chip45boot2).
Damit der Reset schön einfach geht, frage ich im RXC-vect (der Uart wird 
auch sonst fleißig benutzt) einfach ab, ob 10-mal hintereinander ein 
solches 'U' kommt. Da mein restliches Protokoll keine Buchstaben 
enthält, sollte das auch nicht versehentlich ausgelöst werden.
Der Bootloader-Bereich ist 1k Words, die Startadresse 0x3C00. Das ganze 
ist ein Atmega32.
Mein Problem ist jetzt aber: Es funktioniert nicht. Der Controller 
resettet sich zwar, springt aber nicht in den Bootloader.
Der Bootloader an sich funktioniert, wenn ich die 'U's sende und den 
Controler per Reset-Pin bzw Power-Toggle resette, dann springt er 
problemlos in den Bootloader.

Fuses für Bootsize ist per AVR-Studio auf 1K Words gesetzt, Bootrst ist 
Programmed.

Hier das Empfangs-Interrupt. Die sonstige Abwicklung des Empfanges 
funktioniert einwandfrei...Hat jemand eine Idee?
(Bitte nicht: "Nimm doch einfach den Bootloader xyz", oder "Wozu soll 
das gut sein?")
/*Reset an die Bootloader-Adresse*/
void reset_to_bootloader(void)
{
  /*Interrupts deaktivieren*/
  cli();

  /*RXD Pin als Eingang*/
  DDRD &= ~(1 << PD0);

  /*Sprung zur Bootloaderstartadresse*/
  goto *0x7800;  
}


/*USART Empfangs Interrupt*/
ISR(USART_RXC_vect)
{  
  /*UDR leeren (damit UART wieder bereit), Zeichen zwischenspeichern*/
  uint8_t buffer = UDR;                      
  static uint8_t flag = ERR_NO_ERROR;
  static uint8_t ct_reset;

  /*Wenn Zeichen ein U ist*/
  if (buffer == 'U')                        
  {
    /*Reset für Bootloader nach dem 10. U*/
    if(++ct_reset==10)
    {
      reset_to_bootloader();                
    }
    /*wenn 10. U noch nicht erreicht, Vector verlassen*/
    else
    {
      return;
    }
  }

  else
  {
    /*Reset Counter zurücksetzen*/
    ct_reset = 0;
  }

  /*Wenn Endzeichen ankommt*/  
  if (buffer == RX_TERMINATOR)                  
  {  
    /*Wenn zuvor kein Fehler aufgetreten war, dann ist der Frame gültig*/
    if (flag == ERR_NO_ERROR)                    
    {
      /*und wird freigegeben*/
      release_last_frame(&rx_buffer);  
      
      /*Und Zähler wird erhöht*/
      number_rx_frames++;  
    }

    /*Wenn hingegen ein Fehler aufgetreten war, ist der Frame ungültig*/
    else
    {
      /*und wird verworfen*/
      dismiss_last_frame(&rx_buffer);

      /*Es wird eine Fehlermeldung ausgegeben*/
      send_status_message(PREFIX_ERROR, flag);

      /*Und Flag zurücksetzen*/
      flag = ERR_NO_ERROR;
    }
  }

  /*Alle anderen Zeichen*/
  else
  {
    /*Werden im Ringpuffer gespeichert und der Rückgabewert (Fehlermeldung) gespeichert*/
    flag = put_to_ringbuffer(&rx_buffer, buffer);
  }
  return;
}


Autor: Christian Pförtner (Firma: FSW GmbH) (f-sw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Phillip,

ich benutze eine Software die das auch so
ähnlich macht.
Ich benutze dazu den Watchdog. Einfach nach dem
empfangen der 10 'U' den Watchdog einschalten und
der Controller macht nach der eingestellten Zeit einen Reset.

Gruß

Christian

Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Christian,
Momentan mache ich resets auch per Watchdog, allerdings möchte ich den 
zukünftig wirklich als "Wachhund" benutzen und möchte daher die 
goto-Anweisung verwenden. Laut Datenblatt und Beschreibung des 
Bootloaders sollte das ja eingetlich auch ohne weiteres funktionieren, 
leider tut es das einfach nicht, dh. höchst wahrscheinlich mache ich 
dabei noch irgendetwas falsch. Gibt es bei der goto-Anweisung etwas zu 
beachten, zB wenn sie aus einem Interrupt-Vector heraus aufgerufen wird?

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Phillip Hommel schrieb:
> Momentan mache ich resets auch per Watchdog, allerdings möchte ich den
> zukünftig wirklich als "Wachhund" benutzen und möchte daher die
> goto-Anweisung verwenden.

Und warum kannst du den watchdog zukünftig nicht mehr dafür verwenden? 
Ob der nun zuschlägt, weil der Prozessor hängt, oder weil du absichtlich 
eine eine Endlosschleife eingebaut hast, ist dem völlig egal.

Damit bekommst du dann den echten Reset, mit definierten Zuständen aller 
Hardwaremodule. Ein Sprung auf die Resetadresse ist ja kein 
vollständiger Reset.

Phillip Hommel schrieb:
> ...die Startadresse 0x3C00.
>...
>   goto *0x7800;

Hm. Schon mal ins Disassembly geschaut?

Oliver

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
  goto *0x7800;
Das springt zur Word Adresse 0x7800.

Autor: Nils S. (kruemeltee) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void (*jump_to_bootloader)( void ) = 
  bootloaderstartadresse; jump_to_bootloader(); // Jump to bootloader
Quelle: http://www.embedded-projects.net/index.php?page_id=81

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.