Hallo, bei meinen Versuchen den Flash eines ATMega8 über einen Bootloader zu beschreiben, bin ich über folgendes Phänomen gestossen: Die Funktion "boot_program_page" wie sie in der WinAVR-Doku beschrieben ist, funktioniert erst richtig, wenn zuvor die Funktion "boot_page_erase" mit einer beliebigen Page aufgerufen wurde. So zum Beispiel steht nach einem Aufruf von memset( data, 0, SPM_PAGESIZE ); boot_program_page( 0, data ) in den ersten 64 Bytes des Flashs immernoch "0xFF". Wobei dieser Aufruf: boot_page_erase(64); boot_program_page( 0, data ); in den ersten 64 Bytes die korrekten Nullen reinschreibt. Ganz kurios ist die Tatsache, dass sich die Page, die das erste Mal mit "boot_page_erase" bearbeitet wurde, nicht mehr beschreiben lässt, d.h. der Aufruf: boot_page_erase(0); boot_program_page( 0, data ); liefert immernoch "0xff" in der Page. Als Workaround nehmen ich momentan immer die nicht existierende Page "-1": boot_page_erase(-1); boot_program_page( 0, data ); Hatte einer von euch schonmal dasselbe Problem? Ich benutze das AVRStudio 4 mit der WinAVR Version vom 10.01.2010 (die Version 10.06.2008 hab ich auch getestet). Anbei der follständige Code (Bootloader ist 2k groß, Fuses sind auf dem ATMega8 entsprechen gesetzt): #include <avr/io.h> #include <avr/interrupt.h> #include <avr/boot.h> void boot_program_page(uint32_t page, uint8_t* buf) { uint16_t i; uint8_t sreg; /* Disable interrupts.*/ sreg = SREG; cli(); eeprom_busy_wait(); boot_page_erase(page); boot_spm_busy_wait(); /* Wait until the memory is erased. */ for (i=0; i<SPM_PAGESIZE; i+=2) { /* Set up little-endian word. */ uint16_t w = *buf++; w += (*buf++) << 8; boot_page_fill(page + i, w); } boot_page_write(page); /* Store buffer in flash page. */ boot_spm_busy_wait(); /* Wait until the memory is written.*/ /* Reenable RWW-section again. We need this if we want to jump back */ /* to the application after bootloading. */ boot_rww_enable(); /* Re-enable interrupts (if they were ever enabled). */ SREG = sreg; } int main() { uint16_t page; /* Interrupt Vektoren des bootloaders verwenden */ char sregtemp = SREG; cli(); temp = GICR; GICR = temp | (1<<IVCE); GICR = temp | (1<<IVSEL); SREG = sregtemp; sei(); /* boot_program_page funktioniert erst korrekt nach einem Aufruf von boot_page_erase */ boot_page_erase(-1); uint8_t data[SPM_PAGESIZE]; memset( data, 0, SPM_PAGESIZE ); boot_program_page( 0, data ); /* Interrupt Vektoren der Applikation verwenden */ cli(); temp = GICR; GICR = temp | (1<<IVCE); GICR = temp & ~(1<<IVSEL); return 0; }
Lesen bildet: Wichtige Regeln - erst lesen, dann posten! Wenn Du willst, daß sich das jemand anguckt, benutze die Formatierung oder poste die Source als Anhang. Peter
Gast
#2559542
> Wenn Du willst, daß sich das jemand anguckt, benutze die Formatierung > oder poste die Source als Anhang. Bevor die fehlende Formatierung noch mehr potentielle Antworter abschreckt: Hier mit Formatierung :-)
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
Gast
#2559698
Flash-Speicher muss immer zuerst gelöscht werden (sprich auf 0xFF zurückgesetzt werden) bevor etwas rein geschrieben werden kann (Schreiben im Flash geht nur in eine Richtung von 1 nach null)
Ja, der Flash Speicher wird in der Funktion "boot_program_page" vor jedem Schreiben gelöscht. In meinem Fall muss ich jedoch zuerst die Funktion "boot_page_erase" mit einer beliebigen Seite beim Starten einmal ausführen damit das Schreiben überhaupt funktioniert.
Gast
#2560495
Leider kann ich das Problem nicht nachstellen bzw. bei mir funktioniert alles mit WinAVR-20100110 (und auch mit AVR-Toolchain-4.7.0-2012-02-19) Die wesentlichen Dateien sind im Anhang. Die Batchfiles sind nur zur Anschauung und bei mir für die AVR Fuses "2K Bootloader" (Linker Option -Ttext=0x1800) "Atmega8 bei 12 MHz externer Quarz" und stk200 Programmieradapter an lpt1 eingestellt.
Gast
#2560526
>in den ersten 64 Bytes des Flashs immernoch "0xFF". Gelöschtes Flash hat in den Zellen ja auch 0xFF. Das ist völlig in Ordnung. >Wobei dieser Aufruf: > >boot_page_erase(64); >boot_program_page( 0, data ); > >in den ersten 64 Bytes die korrekten Nullen reinschreibt. Dann ist das Flash nicht gelöscht sondern mit Null programmiert. Dein Problem ist also keins.
> Gelöschtes Flash hat in den Zellen ja auch 0xFF. > Das ist völlig in Ordnung. Ich hab auch nichts anderes behauptet. > Dann ist das Flash nicht gelöscht sondern mit Null programmiert. Da hab ich auch geschrieben, dass das korrekt ist. Mein Problem ist der initiale Aufruf von boot_page_erase auf IRGENDEINE Page beim Starten des Controllers damit ich dann eine ANDERE Seite korrekt Löschen und beschreiben kann. @Krapao: Danke für deine Recherche. Mit deinen HEX-Files hab ich den gleichen Effekt. So langsam glaube ich, dass mein Controller defekt ist. Ich werd das mal mit einem neuen testen.