Hallo! eine kurze frage zum Thema bootlaoder: Wenn ich ein programm in den bootsektor des controllers schreibe, und am ende des programms an die adresse 0x0000 springe - was ppasiert? a) wenn kein programm im nicht-bootsektor vorhanden ist b) ein programm vorhanden ist Beim CVAVR ist mir auch noch etwas unklar: reicht es, beim program.type infach bootloader-1024words einzustellen, damit der compiler das richtig macht? hab in der hilfe leider nichts dazu gefunden. zum nächsten :) wenn ich einen bootloader per isp auf den chip gespeichert habe, wie kann ich ich den nicht-boot bereich ein programm laden? einfach bootprotect fuses setzen und dann hex file drauf? Danke!
>Wenn ich ein programm in den bootsektor des controllers schreibe, und am >ende des programms an die adresse 0x0000 springe - was ppasiert? a) der Controller läuft durch den Flash, bis er wieder beim Bootloader ankommt. Zu erkennen an den ResetFlags=$00 b) das Hauptprogramm läuft an >wenn ich einen bootloader per isp auf den chip gespeichert habe, wie >kann ich ich den nicht-boot bereich ein programm laden? >einfach bootprotect fuses setzen und dann hex file drauf? Die Hauptaufgabe des Bootloaders ist es doch gerade, den Programmcode laden zu können. Und zwar über ein Hardware-Interface oder eine reine Softwarelösung an einem oder mehreren Pins des Controllers. Zum Testen kann man aber auch erst den Bootloader flashen, dann "Chip Erase before Flash" abschalten und dann den Programmcode hinterherflashen. Die beiden Speicherbereiche von Bootloader und Programm dürfen sich in dem Fall seitens der *.hex-Files nicht überlappen.
danke für deine hilfe. hab jetz grad 2 testprogramme geschrieben - und kann per uart befehl vom bootloader ins "normale" programm springen. jetz gehts ans SPM :) hast du /jemand anders evtl einen tip für eine gute erklärung des intel hex formats? also der daten, die ich in den speicher schreiben muss. Danke!
hier meine nächste frage: hab grade versucht, den unteren teil des
speichers zu löschen (0-7BFF). der controller braucht zwar eine zeit
dafür (grob geschätzt ~500ms), aber wenn ich den speicher wieder
auslese, steht noch das selbe drin wie vor dem löschen.
hier der sourcecode
//load the lower address byte of the Z-pointer with 00
#asm("ldi r30, 0x00");
for(page_address=start_address;page_address<stop_address;page_address++)
{
#asm
mov r31, r6 ;//move CurrentAddress to Z
pointer
#endasm
//set up SPMCS register
SPMCSR = PAGE_ERASE;
//call the spm
#asm("spm");
//wait for the erase operation to be finished
while((SPMCSR&0x01)==1);
}
konfiguration:
PAGE_ERASE = 0x03
r6 = page_address
start_address = 0
stop_address = 123 (0x7B)
sieht jemand einen fehler in diesem code?
@winfried: danke, genau sowas hab ich gemeint
nun zum aktuellen problem: ich kann keine daten in den flash
programmieren (löschen funktioniert).
hier der sourcecode:
//----------------------------------------------------------------------
-------
//function loads the page buffer
void loadPageBuffer(unsigned int *data, unsigned char count)
{
unsigned char word_counter;
for(word_counter=0;word_counter<count;word_counter++)
{
//load the actual word
page_data = data[word_counter];
//laod the actual address
page_address = word_counter;
//wait for the erase operation to be finished
while((SPMCSR&0x01)==1);
//write word to buffer
#asm
movw r30, r6 //move CurrentAddress to Z
pointer
movw r0, r2 //move current data
#endasm
//setup SPMCSR
SPMCSR = STORE_WORD;
//call the spm
#asm("spm");
}
}
//----------------------------------------------------------------------
-------
//function stores a page to the flash of the mcu
void writePage(unsigned char write_address)
{
page_address = write_address; //page_addres @ r4
page_address = page_address<<8;
//erase page
#asm
mov r31, r4 ;//move CurrentAddress to Z
pointer
#endasm
//set up SPMCS register
SPMCSR = PAGE_ERASE;
//call the spm
#asm("spm");
//wait for the erase operation to be finished
while((SPMCSR&0x01)==1);
//write page
#asm
mov r31, r4 ;//move CurrentAddress to Z pointer
#endasm
//set up SPMCS register
SPMCSR = PAGE_WRITE;
//call the spm
#asm("spm");
//wait for the erase operation to be finished
while((SPMCSR&0x01)==1);
}
zuerst wird loadPageBuffer() aufgerufen, und ein array aus 0 übergeben.
count = 230
dann wird writePage() aufgerugen
write_Address = 230
nach dem auslesen steh bis zur adresse des bootlaoders alelrdings immer
FF - also flash ist noch gelöscht.
korrigiert mich bitte, falls ich mich irre:
Zuerst lade ich die zu schreibenden daten in den temporären buffer
(addressiert über Z-pointer)
dann schreibe ich eine page (page adresse per z-pointer h-register)
nun sollte der wert doch drin stehn oder?
Ich arbeite zwar schon 2 Jahre mit CVAVR aber den Bootlader habe ich noch nie benötigt. Sorry, das wird vielleicht ein nächstes Projekt.
Und ich kann´s leider nur in ASM. Trotzdem noch eine schönen Heiligabend!
so update:
ich kann jetz immer das 1. word einer page beschreiben, der rest der
apge bleibt aber auf FF.
hier nochmal der code:
//----------------------------------------------------------------------
-------
//function loads the page buffer
void loadPageBuffer(unsigned int *data, unsigned char count)
{
unsigned char word_counter;
for(word_counter=0;word_counter<count;word_counter++)
{
//load the actual word
page_data = data[word_counter];
//laod the actual address
page_address = word_counter;
//wait for the operation to be finished
while((SPMCSR&0x01)==1);
//write word to buffer
#asm
mov r30, r4 //move CurrentAddress to Z
pointer
mov r0, r2 //move current data LB
mov r1, r3 //move current data UB
#endasm
//setup SPMCSR
SPMCSR = STORE_WORD;
//call the spm
#asm("spm")
}
}
//----------------------------------------------------------------------
-------
//function stores a page to the flash of the mcu
void writePage(unsigned char write_address)
{
page_address = write_address; //page_addres @ r4
page_address = page_address<<8;
//wait for the operation to be finished
while((SPMCSR&0x01)==1);
//erase page
#asm
movw r30, r4 ;//move CurrentAddress to Z
pointer
#endasm
//set up SPMCS register
SPMCSR = PAGE_ERASE;
//call the spm
#asm("spm")
//wait for the operation to be finished
while((SPMCSR&0x01)==1);
//write page
#asm
movw r30, r4 ;//move CurrentAddress to Z pointer
#endasm
//set up SPMCS register
SPMCSR = PAGE_WRITE;
//call the spm
#asm("spm")
//wait for the operation to be finished
while((SPMCSR&0x01)==1);
//re-enable RWW
SPMCSR = ENABLE_RWW;
//call the spm
#asm("spm")
//wait for the operation to be finished
while((SPMCSR&0x01)==1);
}
ich vermute, der fehler liegt irgendwo in der funktion loadPageBuffer(), da das erste program word jeder page geschrieben wird, und gelesen werden kann.
so, ich hab mir jetzt in der funktion loadPageBuffer() alle werte, die
in den puffer geschrieben werden samt dazugehöriger adresse auf die uart
geschickt. alle werte sind korrekt. Im flash des controllers landet aber
trotzdem immer nur das 1. word.
wo kann hier nur der fehler liegen?
for(word_counter=0;word_counter<count;word_counter++)
{
//load the actual word
page_data = data[word_counter];
//laod the actual address
page_address = word_counter<<1;
//wait for the operation to be finished
while((SPMCSR&0x01)==1);
UDR0 = page_address;
while((UCSR0A & 0b00100000) == 0); //wait for the
transmitbuffer to be empty
UDR0 = page_data;
while((UCSR0A & 0b00100000) == 0); //wait for the
transmitbuffer to be empty
//write word to buffer
#asm
movw r30, r4 //move CurrentAddress to Z
pointer (only the LB)
movw r0, r2 //move current data as word
#endasm
//setup SPMCSR
SPMCSR = STORE_WORD;
//call the spm
#asm("spm")
}
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.