Forum: Mikrocontroller und Digitale Elektronik Bootloader ATmega 2561


von Matthias E. (meckoldt123)


Lesenswert?

Habe einen BootLoader für den 2561 programmiert. Soweit alles klar und 
"läuft" - nur er brennt die Daten nicht in den Flash! Alle Bytes werden 
von SD-Card richtig eingelesen (TEST-Sektion im Code), Page-Adresse ist 
auch stets korrekt (TEST-Sektion), BootLoader wird vom Hauptprog korrekt 
angesprungen, läuft ohne Fehler etc. durch, danach korrekter Rücksprung 
ins Hauptprog - aber eben er brennt (das Update von der SD-Card) nicht. 
Habe auch kontrolliert ob evtl. falscher Speicherbereich beschrieben 
wird - nix! Kein einziges Byte! Habe auch die boot.h dahingehend 
manipuliert, dass ganz zwingend von den boot_page_XX - Funktionen stets 
die extended-Variante aufgerufen wird.
Bin kein Neuling beim Programmieren - alles andere klappt auf meinem 
ATmega! Habe aber keinen Plan woran es liegt. Brauch HILFE!!!
Hier der Codeausschnitt:
1
#define TEST1
2
#define TEST2
3
#define TEST3
4
#define TEST4
5
#define TEST5
6
7
uint16_t i;
8
uint8_t sreg;
9
uint8_t k;
10
char z[10];
11
12
void boot_program_page( uint32_t page, uint8_t *buf )
13
{
14
  sreg = SREG;                // Interrupt-Status merken
15
  cli();                    // Interrupts aus
16
  
17
  boot_spm_busy_wait();            // okay?
18
  eeprom_busy_wait();
19
20
  boot_page_erase( page );
21
  boot_spm_busy_wait();            // Wait until the memory is erased.
22
23
  #ifdef TEST2
24
  ultoa( page,z,16 );              // Ausgabe page-Adresse
25
  LCD_Print( z ,1,160, black,white );
26
  #endif
27
28
  for (i=0; i<SPM_PAGESIZE; i+=2)      // SPM_PAGESIZE = 256 (Byte)
29
  {
30
    uint16_t w = *buf++;          // Set up little-endian word.
31
    w += (*buf++) << 8;
32
    boot_page_fill( page+i, w );
33
    
34
    #ifdef TEST3
35
    utoa( w,z,16 );              // Ausgabe Datenword
36
    LCD_Box( 1,k*13,24,k*13+9,white);
37
    LCD_Print( z ,1,k*13, black,white );
38
    if (++k == 8) k=0;
39
    delay_ms( 2000 );
40
    #endif      
41
  }
42
43
  boot_page_write( page );          // Store buffer in flash page.
44
  boot_spm_busy_wait();            // Wait until the memory is written.
45
  boot_rww_enable();              // Reenable RWW-section again
46
47
  SREG = sreg;  // Re-enable interrupts (if they were ever enabled).
48
}
49
50
int main(void)
51
{
52
  LCD_Init();                  // Display initialisieren
53
  #ifdef TEST1
54
  LCD_Box( 0,0,131,175, dark_green );
55
  #endif
56
57
  SD_DDR |= BL(SD_CS);            // SD-CS als Ausgang einstellen
58
  SD_DDR |= BL(SD_3S);            // SD-3S als Ausgang einstellen
59
60
  pop_var2ep();                // SD-FAT/MMC-Variablen einlesen
61
  uint32_t adr = 0;              // Flash-Adresse (byteweise)
62
63
  for (uint8_t a=167; a>7; a-=10)      // 16 Durchläufe x
64
  for (uint8_t b=30; b<92; b++)        // 62 Durchläufe = 992 Aufrufe
65
  {
66
    _LCD_DONE; _SD_TALK;
67
      FileRead();              // Block á 256Byte aus Datei in data[] einlesen
68
    _SD_DONE;
69
    
70
    boot_program_page( adr,data );
71
    
72
    LCD_Box( b,a-10,b+1,a, yellow );    // Linie zeichnen
73
        
74
    adr += SPM_PAGESIZE;          // Adresse weiterzählen
75
  }
76
77
  #ifdef TEST5
78
  delay_ms( 5000 );        // nur zum TEST
79
  #endif
80
81
  start_app();
82
  while (1);
83
  return 0;
84
}

von Hans W. (hans_wurst)


Lesenswert?

Eigentlich schaut das ganz ok aus, in deinem Code. Nur der Wert für 
"Data" ist im Codeschnipsel nicht zu sehen wo er her kommt und ob es 
wirklich ein Zeiger ist.
1
boot_program_page( adr,data );

Hast du den Flash mal mit dem AVR-Studio ausgelesen? Was steht denn in 
den ersten paar Adressen drinn (lauter Nullen, lauter 0xFF)?

Um sicher zu gehen, könntest du ja auch (zum Test erstmal) einen festen 
Wert für die Daten nehmen.

von Stefan E. (sternst)


Lesenswert?

Sicher, dass der Bootloader auch an der richtigen Stelle steht?
Zeig mal die entsprechende Link-Option.

von Hans W. (hans_wurst)


Lesenswert?

...ach ja... noch was, versuch doch mal erst mal nur eine Page zu 
beschreiben (am besten einfach nur page 0). Nicht, dass du eventuell 
eine zuvor geschriebene Page mit einem nachvolgenden boot_page_erase() 
wieder löscht. (in dem Fall könnte der Wert für SPM_PAGESIZE falsch 
sein. Ist ein wenig verwirrend im Datenblatt.)

von Matthias E. (meckoldt123)


Lesenswert?

1. Mit festem Wordwert habe ich auch schon gearbeitet - nix!! 
Flash-Inhalt wird nicht geändert - war er leer (FF) bleibt er leer, ist 
schon ein Prog drin bleibt es unverändert (verify über mein mkII). Der 
Code für boot_program_page(..) ist aus der boot.h und sollte richtig 
sein. Die Abschnitte TEST2 und TEST3 dokomentieren korrekte Werte und 
Adresse.
2. Denke doch, dass der Bootloader korrekt in den Flash geschrieben wird 
(verify über mein mkII) und steht auch an der richtigen Stelle. Und er 
läuft durch (alle Display-Ausgaben sind korrekt) - nur er brennt 
nicht!!!! Hier noch mal die (etwas gekürzte) lss-Datei:
1
atmega2561/4Dboot.elf:     file format elf32-avr
2
3
Sections:
4
Idx Name          Size      VMA       LMA       File off  Algn
5
  0 .data         00000256  00800200  0001fbd6  00000c6a  2**0
6
                  CONTENTS, ALLOC, LOAD, DATA
7
  1 .text         00000bd6  0001f000  0001f000  00000094  2**1
8
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
9
  2 .bss          00000546  00800456  00800456  00000ec0  2**0
10
                  ALLOC
11
  3 .debug_aranges 00000070  00000000  00000000  00000ec0  2**0
12
                  CONTENTS, READONLY, DEBUGGING
13
  4 .debug_pubnames 0000027c  00000000  00000000  00000f30  2**0
14
                  CONTENTS, READONLY, DEBUGGING
15
  5 .debug_info   00000db3  00000000  00000000  000011ac  2**0
16
                  CONTENTS, READONLY, DEBUGGING
17
  6 .debug_abbrev 00000274  00000000  00000000  00001f5f  2**0
18
                  CONTENTS, READONLY, DEBUGGING
19
  7 .debug_line   0000089b  00000000  00000000  000021d3  2**0
20
                  CONTENTS, READONLY, DEBUGGING
21
  8 .debug_frame  000000c0  00000000  00000000  00002a70  2**2
22
                  CONTENTS, READONLY, DEBUGGING
23
  9 .debug_str    0000037d  00000000  00000000  00002b30  2**0
24
                  CONTENTS, READONLY, DEBUGGING
25
 10 .debug_loc    0000077b  00000000  00000000  00002ead  2**0
26
                  CONTENTS, READONLY, DEBUGGING
27
 11 .debug_ranges 000001b8  00000000  00000000  00003628  2**0
28
                  CONTENTS, READONLY, DEBUGGING
29
30
Disassembly of section .text:
31
32
0001f000 <__vectors>:
33
// return   -
34
//-------------------------------------------------------------------------------
35
void LCD_Wait( void )
36
{  //waits for SPI transfer is done
37
  while (!(SPSR & (_BV(SPIF))));
38
}
39
   1f000:  0c 94 66 f8   jmp  0x1f0cc  ; 0x1f0cc <__ctors_end>
40
   1f004:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
41
   1f008:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
42
   1f00c:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
43
   1f010:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
44
   1f014:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
45
   1f018:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
46
   1f01c:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
47
   1f020:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
48
   1f024:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
49
   1f028:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
50
   1f02c:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
51
   1f030:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
52
   1f034:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
53
   1f038:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
54
   1f03c:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
55
   1f040:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
56
   1f044:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
57
   1f048:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
58
   1f04c:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
59
   1f050:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
60
   1f054:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
61
   1f058:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
62
   1f05c:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
63
   1f060:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
64
   1f064:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
65
   1f068:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
66
   1f06c:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
67
   1f070:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
68
   1f074:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
69
   1f078:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
70
   1f07c:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
71
   1f080:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
72
   1f084:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
73
   1f088:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
74
   1f08c:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
75
   1f090:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
76
   1f094:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
77
   1f098:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
78
   1f09c:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
79
   1f0a0:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
80
   1f0a4:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
81
   1f0a8:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
82
   1f0ac:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
83
   1f0b0:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
84
   1f0b4:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
85
   1f0b8:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
86
   1f0bc:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
87
   1f0c0:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
88
   1f0c4:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
89
   1f0c8:  0c 94 87 f8   jmp  0x1f10e  ; 0x1f10e <__bad_interrupt>
90
91
0001f0cc <__ctors_end>:
92
   1f0cc:  11 24         eor  r1, r1
93
   1f0ce:  1f be         out  0x3f, r1  ; 63
94
   1f0d0:  cf ef         ldi  r28, 0xFF  ; 255
95
   1f0d2:  d1 e2         ldi  r29, 0x21  ; 33
96
   1f0d4:  de bf         out  0x3e, r29  ; 62
97
   1f0d6:  cd bf         out  0x3d, r28  ; 61
98
   1f0d8:  00 e0         ldi  r16, 0x00  ; 0
99
   1f0da:  0c bf         out  0x3c, r16  ; 60
100
101
0001f0dc <__do_copy_data>:
102
   1f0dc:  14 e0         ldi  r17, 0x04  ; 4
103
   1f0de:  a0 e0         ldi  r26, 0x00  ; 0
104
   1f0e0:  b2 e0         ldi  r27, 0x02  ; 2
105
   1f0e2:  e6 ed         ldi  r30, 0xD6  ; 214
106
   1f0e4:  fb ef         ldi  r31, 0xFB  ; 251
107
   1f0e6:  01 e0         ldi  r16, 0x01  ; 1
108
   1f0e8:  0b bf         out  0x3b, r16  ; 59
109
   1f0ea:  02 c0         rjmp  .+4        ; 0x1f0f0 <__do_copy_data+0x14>
110
   1f0ec:  07 90         elpm  r0, Z+
111
   1f0ee:  0d 92         st  X+, r0
112
   1f0f0:  a6 35         cpi  r26, 0x56  ; 86
113
   1f0f2:  b1 07         cpc  r27, r17
114
   1f0f4:  d9 f7         brne  .-10       ; 0x1f0ec <__do_copy_data+0x10>
115
116
0001f0f6 <__do_clear_bss>:
117
   1f0f6:  19 e0         ldi  r17, 0x09  ; 9
118
   1f0f8:  a6 e5         ldi  r26, 0x56  ; 86
119
   1f0fa:  b4 e0         ldi  r27, 0x04  ; 4
120
   1f0fc:  01 c0         rjmp  .+2        ; 0x1f100 <.do_clear_bss_start>
121
122
0001f0fe <.do_clear_bss_loop>:
123
   1f0fe:  1d 92         st  X+, r1
124
125
0001f100 <.do_clear_bss_start>:
126
   1f100:  ac 39         cpi  r26, 0x9C  ; 156
127
   1f102:  b1 07         cpc  r27, r17
128
   1f104:  e1 f7         brne  .-8        ; 0x1f0fe <.do_clear_bss_loop>
129
   1f106:  0e 94 60 fa   call  0x1f4c0  ; 0x1f4c0 <main>
130
   1f10a:  0c 94 e9 fd   jmp  0x1fbd2  ; 0x1fbd2 <_exit>
131
132
0001f10e <__bad_interrupt>:
133
   1f10e:  0c 94 00 f8   jmp  0x1f000  ; 0x1f000 <__vectors>
134
135
0001f112 <LCD_SPI_Int>:
136
void LCD_SPI_Int( uint16_t Value ) 
137
{  // send int by SPI 
138
   1f112:  28 2f         mov  r18, r24
139
  SPCR |= _BV(SPE);
140
   1f114:  8c b5         in  r24, 0x2c  ; 44
141
   1f116:  80 64         ori  r24, 0x40  ; 64
142
   1f118:  8c bd         out  0x2c, r24  ; 44
143
  SPDR = (uint8_t)(Value >> 8);
144
   1f11a:  9e bd         out  0x2e, r25  ; 46
145
// param  ...    zu sendende Daten
146
// return   -
147
//-------------------------------------------------------------------------------
148
void LCD_Wait( void )
149
{  //waits for SPI transfer is done
150
  while (!(SPSR & (_BV(SPIF))));
151
   1f11c:  0d b4         in  r0, 0x2d  ; 45
152
   1f11e:  07 fe         sbrs  r0, 7
153
   1f120:  fd cf         rjmp  .-6        ; 0x1f11c <LCD_SPI_Int+0xa>
154
void LCD_SPI_Int( uint16_t Value ) 
155
{  // send int by SPI 
156
  SPCR |= _BV(SPE);
157
  SPDR = (uint8_t)(Value >> 8);
158
  LCD_Wait();
159
  SPCR |= _BV(SPE);
160
   1f122:  8c b5         in  r24, 0x2c  ; 44
161
   1f124:  80 64         ori  r24, 0x40  ; 64
162
   1f126:  8c bd         out  0x2c, r24  ; 44
163
  SPDR = (uint8_t)(Value & 0xff);
164
   1f128:  2e bd         out  0x2e, r18  ; 46
165
// param  ...    zu sendende Daten
166
// return   -
167
//-------------------------------------------------------------------------------
168
......
169
......
170
0001fb72 <__eerd_blraw_m2561>:
171
   1fb72:  fc 01         movw  r30, r24
172
   1fb74:  f9 99         sbic  0x1f, 1  ; 31
173
   1fb76:  fe cf         rjmp  .-4        ; 0x1fb74 <__eerd_blraw_m2561+0x2>
174
   1fb78:  06 c0         rjmp  .+12       ; 0x1fb86 <__eerd_blraw_m2561+0x14>
175
   1fb7a:  f2 bd         out  0x22, r31  ; 34
176
   1fb7c:  e1 bd         out  0x21, r30  ; 33
177
   1fb7e:  f8 9a         sbi  0x1f, 0  ; 31
178
   1fb80:  31 96         adiw  r30, 0x01  ; 1
179
   1fb82:  00 b4         in  r0, 0x20  ; 32
180
   1fb84:  0d 92         st  X+, r0
181
   1fb86:  41 50         subi  r20, 0x01  ; 1
182
   1fb88:  50 40         sbci  r21, 0x00  ; 0
183
   1fb8a:  b8 f7         brcc  .-18       ; 0x1fb7a <__eerd_blraw_m2561+0x8>
184
   1fb8c:  08 95         ret
185
186
0001fb8e <__udivmodsi4>:
187
   1fb8e:  a1 e2         ldi  r26, 0x21  ; 33
188
   1fb90:  1a 2e         mov  r1, r26
189
   1fb92:  aa 1b         sub  r26, r26
190
   1fb94:  bb 1b         sub  r27, r27
191
   1fb96:  fd 01         movw  r30, r26
192
   1fb98:  0d c0         rjmp  .+26       ; 0x1fbb4 <__udivmodsi4_ep>
193
194
0001fb9a <__udivmodsi4_loop>:
195
   1fb9a:  aa 1f         adc  r26, r26
196
   1fb9c:  bb 1f         adc  r27, r27
197
   1fb9e:  ee 1f         adc  r30, r30
198
   1fba0:  ff 1f         adc  r31, r31
199
   1fba2:  a2 17         cp  r26, r18
200
   1fba4:  b3 07         cpc  r27, r19
201
   1fba6:  e4 07         cpc  r30, r20
202
   1fba8:  f5 07         cpc  r31, r21
203
   1fbaa:  20 f0         brcs  .+8        ; 0x1fbb4 <__udivmodsi4_ep>
204
   1fbac:  a2 1b         sub  r26, r18
205
   1fbae:  b3 0b         sbc  r27, r19
206
   1fbb0:  e4 0b         sbc  r30, r20
207
   1fbb2:  f5 0b         sbc  r31, r21
208
209
0001fbb4 <__udivmodsi4_ep>:
210
   1fbb4:  66 1f         adc  r22, r22
211
   1fbb6:  77 1f         adc  r23, r23
212
   1fbb8:  88 1f         adc  r24, r24
213
   1fbba:  99 1f         adc  r25, r25
214
   1fbbc:  1a 94         dec  r1
215
   1fbbe:  69 f7         brne  .-38       ; 0x1fb9a <__udivmodsi4_loop>
216
   1fbc0:  60 95         com  r22
217
   1fbc2:  70 95         com  r23
218
   1fbc4:  80 95         com  r24
219
   1fbc6:  90 95         com  r25
220
   1fbc8:  9b 01         movw  r18, r22
221
   1fbca:  ac 01         movw  r20, r24
222
   1fbcc:  bd 01         movw  r22, r26
223
   1fbce:  cf 01         movw  r24, r30
224
   1fbd0:  08 95         ret
225
226
0001fbd2 <_exit>:
227
   1fbd2:  f8 94         cli
228
229
0001fbd4 <__stop_program>:
230
   1fbd4:  ff cf         rjmp  .-2        ; 0x1fbd4 <__stop_program>
Defintionen zum Aufruf bootLoaders bzw. Programm:
1
#define start_app()  asm volatile ( "jmp 0x00000" )
2
#define start_boot()  asm volatile ( "jmp 0x1F000" )

3. Nur eine einzelne Page zu schreiben war auch erfolglos. Außerdem 
(siehe Code) kann es nicht passieren dass eine Page beschrieben und 
gleich wieder gelöscht wird.

von Stefan E. (sternst)


Lesenswert?

Matthias Eckoldt schrieb:
> steht auch an der richtigen Stelle.

Nein, steht er nicht. Der Befehl SPM funktioniert nur in der 
Bootloader-Section, und die beginnt (je nach BOOTSZ) frühestens bei 
0x3e000.

von Matthias E. (meckoldt123)


Lesenswert?

da liest man sich alles 10mal durch und überlegt 20 mal ....

Das BOOTSZ-Fuse hat mich auf die 0x1F000 gebracht. Okay, der 
Befehlscounter beim ATmega ist auf Word eingestellt - Speicheradresse 
ist das doppelte also 0x3E000.

Also in der makedatei muss ich jetzt bei
1
BOOTLOADERSTARTADR = 0x1F000
2
....
3
LDFLAGS  += -Wl,--section-start=.text=$(BOOTLOADERSTARTADR)
nur die Adresse ändern - ich probiers.

von Matthias E. (meckoldt123)


Lesenswert?

So, letzter Kommentar (hätt ich fast vergessen): BootLoader klappt 
jetzt! Danke an Ernst für den Hinweis!!!

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.