Forum: Compiler & IDEs aufruf flash-schreib-routine aus RWW-section


von kosmonaut pirx (Gast)


Lesenswert?

hallo,
folgendes problem stellt sich mir grad, und nach mehreren stunden suchen 
möchte ich eure hilfe in anspruch nehmen:

meine anwendung läuft ganz normal, ab adresse 0 in der rww-section. nun 
soll irgendwas im falsh gespeichert werden, erstmal egal, was.

was habe ich also getan .. eine routine geschrieben, die in die 
bootloader-section verschoben (0x1E000 bei mir, can128) und auf geht's.

allerdings funktionieren die spm-aufrufe nicht. beispiel ist
boot_page_erase(dest), welches schlicht hängen bleibt. die kiste steht.

was mache ich verkehrt? es muss doch gehen, den flash zu beschreiben, 
ohne gleich die gesamte anwendung in die bootloader-section zu 
verschieben. oder irre ich mich da? mein code entspricht dem beispiel 
aus der avr-libc
(http://www.nongnu.org/avr-libc/user-manual/group__avr__boot.html). bis 
zum erase kommt er noch, danach ist ende.

im voraus danke für eure hilfe,
bye kosmo

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Du musst nicht die gesamte Anwendung in den Bootloader-Bereich
hängen.  Aber: du musst vorsichtig sein mit den Interrupts:

``... During an on-going programming, the software must ensure that
the RWW section never is being read. If the user software is trying to
read code that is located inside the RWW section (i.e., by load
program memory, call, or jump instructions or an interrupt) during
programming, the software might end up in an unknown state. To avoid
this, the interrupts should either be disabled or moved to the Boot
Loader section. ...''

von kosmonaut pirx (Gast)


Lesenswert?

hallo jörg,

das mit den interrupts ist mir schon klar. aber die werden im 
beispielcode ja
gleich ausgeschaltet.
grübel

bye kosmo

von Peter D. (peda)


Lesenswert?

kosmonaut pirx wrote:

> allerdings funktionieren die spm-aufrufe nicht. beispiel ist
> boot_page_erase(dest), welches schlicht hängen bleibt. die kiste steht.

Woher weißt Du das ?

Ich würde sowas nur mit LEDs an Portpins oder interruptfreie UART 
debuggen.
JTAG verträgt sich nicht mit Bootfunktionen.

Wenn man Bootfunktionen im RWW oder im NRWW vor dem Bootstart ausführt, 
werden sie ohne Wartezeit durchlaufen und es passiert nichts im Flash.

Hängenbleiben kann es also nicht.

Wichtig ist bloß, vor dem Erlauben von Interrupts oder Rücksprung in RWW 
das RWW-Enable auszuführen.


Peter

von kosmonaut pirx (Gast)


Lesenswert?

hallo,

>Woher weißt Du das ?

ja, gute frage. man befolge immer die goldene regel, selbst dem 
debugging zu misstrauen. debuggen tue ich mit uart.

grundsätzlich funktioniert das schreiben in den flash, das habe ich 
rausgekriegt, und das beruhigt schon einmal.
problematisch war/ist wohl die verkettung unglücklicher umstände:

zum einen zuckt mein stk200 rum und zieht meine boards ab und an auf 
dauer-reset. mangels root-rechte hilft da bisher nur ein neustart des 
rechners (der par_port registered und deregistered sich ständig, iirc). 
macht freude, das rauszukriegen

zum anderen hat meine uart-ausgabe-routine wohl eine macke, oder sie 
nimmt einfluss auf das rww-schreiben:
1
static void LIBMEM_DEBUG(char* str){
2
  while( *str ){                                                          
3
    /* Wait for empty transmit buffer */                                    
4
    while ( !(UCSR0A & (1<<UDRE0)) );                               
5
      /* Start transmition */                                                 
6
      UDR0 = (unsigned char) *str++;                                  
7
    }                  
8
  }
9
}
(war eigentlich ein macro)
initialisiert wird mit
1
  /* Enable UART receiver and transmitter */
2
  UCSR0B = ( ( 1 << RXEN0 ) | ( 1 << TXEN0 ) );                         
3
  /* Set frame format: 8N1 */                                           
4
  UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
für den, den's interessiert.
gebe ich mit LIBMEM_DEBUG vor dem boot_page_erase ein debugging aus, 
wird ein nachfolgendes LIBMEM_DEBUG nicht mehr erreicht:
1
LIBMEM_DEBUG("Erase page\n");
2
  boot_page_erase (page);
3
LIBMEM_DEBUG("Page erased\n");
resultiert in lediglich einer ausgabe. ob das löschen klappt, lässt sich 
nicht so einfach in erfahrung bringen.

Ich kann nur vermuten, dass der uart etwas braucht, und daher während 
des
löschens ein register (UDR0) geändert wird. warum das auswirkungen auf 
ein erase sonstwo haben sollte, ist mir aber nicht klar und spricht 
gegen diese theorie.

bye kosmo



von mthomas (Gast)


Lesenswert?

> ob das löschen klappt, lässt sich nicht so einfach in erfahrung bringen.
Flashspeicher auslesen und in die Hex-Datei schauen, ob der bei "page" 
beginnende Speicherbereich auf Länge der flash-page mit 0xff gefüllt 
ist.

von kosmonaut pirx (Gast)


Lesenswert?

jo klar. nur löscht man nicht eben gerne belegte bereiche.

von Peter D. (peda)


Lesenswert?

kosmonaut pirx wrote:

> gebe ich mit LIBMEM_DEBUG vor dem boot_page_erase ein debugging aus,
> wird ein nachfolgendes LIBMEM_DEBUG nicht mehr erreicht:

Wenn das LIBMEM_DEBUG in der RWW Sektion steht, muß diese natürlich erst 
noch enabled werden (siehe Datenblatt).


Peter

von kosmonaut pirx (Gast)


Lesenswert?

hallo,

>Wenn das LIBMEM_DEBUG in der RWW Sektion steht, muß diese natürlich erst
>noch enabled werden (siehe Datenblatt).

ein sehr guter hinweis. vielen dank peter.

das folgende läuft durch. aber die page wird nicht geschrieben:
1
boot_page_erase_safe(dest.pgm);
2
boot_spm_busy_wait();
3
boot_rww_enable();
4
boot_page_write_safe(dest.pgm);

nehme ich das "boot_rww_enable" raus, funktioniert das schreiben.
kann mir vielleicht zum abschluss noch jemand sagen, warum?

danke, bye kosmo

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.