Forum: Mikrocontroller und Digitale Elektronik MEGA32 & Bootloader


von Jan H. (janiiix3)


Lesenswert?

Guten Tag,

habe mir vor kurzem hier den Bootloader angeschaut
1
#include <string.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <avr/pgmspace.h>
5
#include <avr/boot.h>
6
7
#include "uart.h"
8
#include "hard_def.h"
9
10
#ifndef F_CPU
11
#define F_CPU 16e6
12
#endif
13
14
#include <util/delay.h>
15
16
#define BOOT_UART_BAUD_RATE     9600     /* Baudrate */
17
#define XON                     17       /* XON Zeichen */
18
#define XOFF                    19       /* XOFF Zeichen */
19
#define START_SIGN              ':'      /* Hex-Datei Zeilenstartzeichen */
20
21
/* Zustände des Bootloader-Programms */
22
#define BOOT_STATE_EXIT          0
23
#define BOOT_STATE_PARSER       1
24
25
/* Zustände des Hex-File-Parsers */
26
#define PARSER_STATE_START      0
27
#define PARSER_STATE_SIZE       1
28
#define PARSER_STATE_ADDRESS    2
29
#define PARSER_STATE_TYPE       3
30
#define PARSER_STATE_DATA       4
31
#define PARSER_STATE_CHECKSUM   5
32
#define PARSER_STATE_ERROR      6
33
34
35
36
37
void appStart(uint8_t rstFlags) {
38
  // save the reset flags in the designated register
39
  //  This can be saved in a main program by putting code in .init0 (which
40
  //  executes before normal c init code) to save R2 to a global variable.
41
  __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
42
43
  __asm__ __volatile__ (
44
  #ifdef VIRTUAL_BOOT_PARTITION
45
  // Jump to WDT vector
46
  "ldi r30,4\n"
47
  "clr r31\n"
48
  #else
49
  // Jump to RST vector
50
  "clr r30\n"
51
  "clr r31\n"
52
  #endif
53
  "ijmp\n"
54
  );
55
}
56
57
void program_page (uint32_t page, uint8_t *buf)
58
{
59
  uint16_t i;
60
  uint8_t sreg;
61
  
62
  /* Disable interrupts */
63
  sreg = SREG;
64
  cli();
65
  
66
  eeprom_busy_wait ();
67
  
68
  boot_page_erase (page);
69
  boot_spm_busy_wait ();      /* Wait until the memory is erased. */
70
  
71
  for (i=0; i<SPM_PAGESIZE; i+=2)
72
  {
73
    /* Set up little-endian word. */
74
    uint16_t w = *buf++;
75
    w += (*buf++) << 8;
76
    
77
    boot_page_fill (page + i, w);
78
  }
79
  
80
  boot_page_write (page);     /* Store buffer in flash page.    */
81
  boot_spm_busy_wait();       /* Wait until the memory is written.*/
82
  
83
  /* Reenable RWW-section again. We need this if we want to jump back */
84
  /* to the application after bootloading. */
85
  boot_rww_enable ();
86
  
87
  /* Re-enable interrupts (if they were ever enabled). */
88
  SREG = sreg;
89
}
90
91
static uint16_t hex2num (const uint8_t * ascii, uint8_t num)
92
{
93
  uint8_t  i;
94
  uint16_t val = 0;
95
  
96
  for (i=0; i<num; i++)
97
  {
98
    uint8_t c = ascii[i];
99
    
100
    /* Hex-Ziffer auf ihren Wert abbilden */
101
    if (c >= '0' && c <= '9')            c -= '0';
102
    else if (c >= 'A' && c <= 'F')       c -= 'A' - 10;
103
    else if (c >= 'a' && c <= 'f')       c -= 'a' - 10;
104
    
105
    val = 16 * val + c;
106
  }
107
  
108
  return val;
109
}
110
111
void write_page(uint32_t page, uint8_t *buf)
112
{
113
  uart_puts("P\n\r");
114
  _delay_ms(100);
115
  program_page(page, buf);
116
  memset(buf, 0xFF, sizeof(SPM_PAGESIZE));
117
}
118
119
int main()
120
{  
121
  /* Intel-HEX Zieladresse */
122
  uint32_t        hex_addr = 0,
123
  /* Intel-HEX Zieladress-Offset */
124
  hex_addr_offset = 0,
125
  /* Zu schreibende Flash-Page */
126
  flash_page = 0;
127
  /* Empfangenes Zeichen + Statuscode */
128
  uint16_t        c = 0,
129
  /* Intel-HEX Checksumme zum Überprüfen des Daten */
130
  hex_check = 0,
131
  /* Positions zum Schreiben in der Datenpuffer */
132
  flash_cnt = 0;
133
  /* temporäre Variable */
134
  uint8_t         temp,
135
  /* Flag zum steuern des Programmiermodus */
136
  boot_state = BOOT_STATE_EXIT,
137
  /* Empfangszustandssteuerung */
138
  parser_state = PARSER_STATE_START,
139
  /* Flag zum ermitteln einer neuen Flash-Page */
140
  flash_page_flag = 1,
141
  /* Datenpuffer für die Hexdaten*/
142
  flash_data[SPM_PAGESIZE],
143
  /* Position zum Schreiben in den HEX-Puffer */
144
  hex_cnt = 0,
145
  /* Puffer für die Umwandlung der ASCII in Binärdaten */
146
  hex_buffer[5],
147
  /* Intel-HEX Datenlänge */
148
  hex_size = 0,
149
  /* Zähler für die empfangenen HEX-Daten einer Zeile */
150
  hex_data_cnt = 0,
151
  /* Intel-HEX Recordtype */
152
  hex_type = 0,
153
  /* empfangene HEX-Checksumme */
154
  hex_checksum=0;
155
  /* Funktionspointer auf 0x0000 */
156
  void (*start)( void ) = (void*)0x0000;
157
  
158
  /* Füllen der Puffer mit definierten Werten */
159
  memset(hex_buffer, 0x00, sizeof(hex_buffer));
160
  memset(flash_data, 0xFF, sizeof(flash_data));
161
  
162
  /* Interrupt Vektoren verbiegen */
163
  temp = GICR;
164
  GICR = temp | (1<<IVCE);
165
  GICR = temp | (1<<IVSEL);
166
  
167
  /* Einstellen der Baudrate und aktivieren der Interrupts */
168
  uart_init( UART_BAUD_SELECT(BOOT_UART_BAUD_RATE,F_CPU) );
169
  sei();
170
171
  _delay_ms(500);    
172
  
173
  do
174
  {
175
    c = uart_getc();
176
    if( !(c & UART_NO_DATA) )
177
    {
178
      /* Programmzustand: Parser */
179
      if(boot_state == BOOT_STATE_PARSER)
180
      {
181
        switch(parser_state)
182
        {
183
          /* Warte auf Zeilen-Startzeichen */
184
          case PARSER_STATE_START:
185
          if((uint8_t)c == START_SIGN)
186
          {
187
            uart_putc(XOFF);
188
            parser_state = PARSER_STATE_SIZE;
189
            hex_cnt = 0;
190
            hex_check = 0;
191
            uart_putc(XON);
192
          }
193
          break;
194
          /* Parse Datengröße */
195
          case PARSER_STATE_SIZE:
196
          hex_buffer[hex_cnt++] = (uint8_t)c;
197
          if(hex_cnt == 2)
198
          {
199
            uart_putc(XOFF);
200
            parser_state = PARSER_STATE_ADDRESS;
201
            hex_cnt = 0;
202
            hex_size = (uint8_t)hex2num(hex_buffer, 2);
203
            hex_check += hex_size;
204
            uart_putc(XON);
205
          }
206
          break;
207
          /* Parse Zieladresse */
208
          case PARSER_STATE_ADDRESS:
209
          hex_buffer[hex_cnt++] = (uint8_t)c;
210
          if(hex_cnt == 4)
211
          {
212
            uart_putc(XOFF);
213
            parser_state = PARSER_STATE_TYPE;
214
            hex_cnt = 0;
215
            hex_addr = hex_addr_offset;
216
            hex_addr += hex2num(hex_buffer, 4);
217
            hex_check += (uint8_t) hex_addr;
218
            hex_check += (uint8_t) (hex_addr >> 8);
219
            
220
            uart_putc(XON);
221
          }
222
          break;
223
          /* Parse Zeilentyp */
224
          case PARSER_STATE_TYPE:
225
          hex_buffer[hex_cnt++] = (uint8_t)c;
226
          if(hex_cnt == 2)
227
          {
228
            uart_putc(XOFF);
229
            hex_cnt = 0;
230
            hex_data_cnt = 0;
231
            hex_type = (uint8_t)hex2num(hex_buffer, 2);
232
            hex_check += hex_type;
233
            switch(hex_type)
234
            {
235
              case 1: parser_state = PARSER_STATE_CHECKSUM; break;
236
              case 0:
237
              case 2:
238
              case 4: parser_state = PARSER_STATE_DATA;
239
              
240
              /* Berechnen der neue Flash-Page (abhängig von hex_type) */
241
              /* Liegen die Daten noch in der aktuellen Flash-Page? */
242
              if(!flash_page_flag && (flash_page != (hex_addr - hex_addr % SPM_PAGESIZE)) )
243
              {
244
                /* Wenn die Daten nicht in der aktuellen Flash-Page liegen, */
245
                /* wird die aktuelle Page geschrieben und ein Flag          */
246
                /* zum berechnen der neuen Page-Startadresse gesetzt        */
247
                write_page(flash_page, flash_data);
248
                flash_cnt = 0;
249
                flash_page_flag = 1;
250
              }
251
              
252
              /* Muss die Page-Startadresse neu berechnet werden? */
253
              if(flash_page_flag)
254
              {
255
                /* Berechnen der neuen Page-Startadresse */
256
                flash_page = hex_addr - hex_addr % SPM_PAGESIZE;
257
                
258
                /* Füllen des Flash-Puffers mit dem "alten" Inhalt der Page */
259
                memcpy_PF(flash_data, flash_page, SPM_PAGESIZE);
260
                
261
                /* Flag setzen um anzuzeigen das eine neue Adresse da ist */
262
                flash_page_flag = 0;
263
              }
264
              break;
265
              default: parser_state = PARSER_STATE_DATA; break;
266
            }
267
            uart_putc(XON);
268
          }
269
          break;
270
          /* Parse Flash-Daten */
271
          case PARSER_STATE_DATA:
272
          hex_buffer[hex_cnt++] = (uint8_t)c;
273
          switch(hex_type)
274
          {
275
            case 0:  /* Record Typ 00 - Data Record auswerten */
276
            if(hex_cnt == 2)
277
            {
278
              uart_putc(XOFF);
279
              uart_putc(c);
280
              hex_cnt = 0;
281
              flash_data[flash_cnt] = (uint8_t)hex2num(hex_buffer, 2);
282
              hex_check += flash_data[flash_cnt];
283
              flash_cnt++;
284
              hex_data_cnt++;
285
              if(hex_data_cnt == hex_size)
286
              {
287
                parser_state = PARSER_STATE_CHECKSUM;
288
                hex_data_cnt=0;
289
                hex_cnt = 0;
290
              }
291
              /* Puffer voll -> schreibe Page */
292
              if(flash_cnt == SPM_PAGESIZE)
293
              {
294
                write_page(flash_page, flash_data);
295
                flash_cnt = 0;
296
                flash_page_flag = 1;
297
              }
298
              uart_putc(XON);
299
            }
300
            break;
301
            case 2:   /* Record Typ 02 - Extended Segment Address auswerten */
302
            case 4:   /* Record Typ 04 - Extended Linear Address auswerten */
303
            if(hex_cnt == 4)
304
            {
305
              uart_putc(XOFF);
306
              uart_putc('J');
307
              hex_cnt = 0;
308
              
309
              /* Schreibe angfangene Flash-Page vor Segment-Sprung */
310
              write_page(flash_page, flash_data);
311
              flash_cnt = 0;
312
              flash_page_flag = 1;
313
              
314
              /* Berechnen der Offsetadresse */
315
              switch(hex_type)
316
              {
317
                case 2: hex_addr_offset = ((uint32_t)hex2num(hex_buffer, 4)) << 4; break;
318
                case 4: hex_addr_offset = ((uint32_t)hex2num(hex_buffer, 4)) << 16; break;
319
              }
320
              
321
              /* Addieren der empfangenen Werte für die Checksumme */
322
              hex_check += (uint8_t) hex2num(hex_buffer, 2);
323
              hex_check += (uint8_t) hex2num(hex_buffer + 2, 2);
324
              
325
              parser_state = PARSER_STATE_CHECKSUM;
326
              hex_data_cnt=0;
327
              hex_cnt = 0;
328
            }
329
            break;
330
            default:
331
            break;
332
          }
333
          break;
334
          /* Parse Checksumme */
335
          case PARSER_STATE_CHECKSUM:
336
          hex_buffer[hex_cnt++] = (uint8_t)c;
337
          if(hex_cnt == 2)
338
          {
339
            uart_putc(XOFF);
340
            hex_checksum = (uint8_t)hex2num(hex_buffer, 2);
341
            hex_check += hex_checksum;
342
            hex_check &= 0x00FF;
343
            /* Dateiende -> schreibe Restdaten */
344
            if(hex_type == 1)
345
            {
346
              write_page(flash_page, flash_data);
347
              boot_state = BOOT_STATE_EXIT;
348
            }
349
            /* Überprüfe Checksumme -> muss '0' sein */
350
            if(hex_check == 0) parser_state = PARSER_STATE_START;
351
            else parser_state = PARSER_STATE_ERROR;
352
            uart_putc(XON);
353
          }
354
          break;
355
          /* Parserfehler (falsche Checksumme) */
356
          case PARSER_STATE_ERROR:
357
          uart_putc('#');
358
          break;
359
          default:
360
          break;
361
        }
362
      }
363
      /* Programmzustand: UART Kommunikation */
364
      else if(boot_state != BOOT_STATE_PARSER)
365
      {
366
        switch((uint8_t)c)
367
        {
368
          case 'p':
369
          boot_state = BOOT_STATE_PARSER;
370
          uart_puts("paste .hex here\n\r");
371
          break;
372
          case 'q':
373
          boot_state = BOOT_STATE_EXIT;
374
          uart_puts("leave Booty\n\r");
375
          break;
376
          default:
377
          uart_putc((unsigned char)c);
378
          uart_puts("\n\r");
379
          break;
380
        }
381
      }
382
    }
383
  }
384
  while(boot_state!=BOOT_STATE_EXIT);
385
  
386
  uart_puts("*  ->Reset now!\n\r"           );
387
    uart_puts("***********************\n\r"       );
388
  _delay_ms(500);
389
  
390
  cli();
391
  
392
  UCSRA |= (1<<TXC);
393
  
394
  /* Interrupt Vektoren wieder gerade biegen */
395
  temp = GICR;
396
  GICR = temp | (1<<IVCE);
397
  GICR = temp & ~(1<<IVSEL);
398
  
399
  /* Reset */
400
  start();
401
  
402
  return 0;
403
}

Und wollte ihn jetzt auf meinem MEGA32 benutzen. Soweit so gut.
Musste das MCUCR Register umändern auf das GICR damit es funktioniert.

Nun.. Meine Hauptapplikation wird vom Bootloader in den Flash 
geschrieben und startet auch. Manchmal aber.. Kommen Zeichen aus dem 
UART oder aber auf dem GLCD, die zwar irgendwo in meiner Applikation 
vorkommen aber die ich an dieser Stelle überhaupt nicht benutze. Woher 
nimmt sich der Controller diese Werte wie kommt er darauf? Kann es sein 
das der Sprung vom Bootloader zum Hauptprogramm irgendwie anders 
verläuft als bei anderen Controllern?

Das Paradoxe daran ist, wenn ich meine Applikation auf den MEGA32 flashe 
ohne den Bootloader klappt alles wie es soll.

Bringt der Bootloader bei dem MEGA32 irgendwas durcheinander? Habe mir 
das .hex vom Bootloader angeschaut und es ist an der Adresse.: 0x3800 
wie ich es auch eingestellt habe.

Was kann das sein?

: Bearbeitet durch User
von Eric B. (beric)


Lesenswert?

Flash vom MEGA32 auslesen nachdem der Bootloader es geflasht hat und mit 
dem Original vergleichen. Wenn gleich, dann ist das Problem irgendwo in 
deinem Programm.

von Jan H. (janiiix3)


Lesenswert?

Eric B. schrieb:
> Flash vom MEGA32 auslesen nachdem der Bootloader es geflasht hat und mit
> dem Original vergleichen. Wenn gleich, dann ist das Problem irgendwo in
> deinem Programm.

Wieso funktioniert mein Programm, wenn ich es ohne den Bootloader an 
Board drauf habe? Das ist doch Paradox..

von Marco H. (damarco)


Lesenswert?

Nö weil sein Programm nicht sauber läuft. Zeiger,Speicher usw. dort 
würde ich suchen. Geht es hier um Strings?

: Bearbeitet durch User
von Jan H. (janiiix3)


Lesenswert?

Marco H. schrieb:
> Nö weil sein Programm nicht sauber läuft. Zeiger,Speicher usw. dort
> würde ich suchen. Geht es hier um Strings?

Ja. Nur wieso klappt es ohne dem Bootloader im Flash?

von Stefan E. (sternst)


Lesenswert?

Jan H. schrieb:
> Ja. Nur wieso klappt es ohne dem Bootloader im Flash?

Weil der RAM-Inhalt nicht der Gleiche ist. Wenn du nur das Programm 
brennst und ohne Power-Cycle dazwischen laufen lässt, hat das RAM Nullen 
als Default-Inhalt. Beim Start über den Bootloader steht dort der vom 
Bootloader zurückgelassene "Müll".

Ich tippe auf eine vergessene String-Terminierung.

von Jan H. (janiiix3)


Lesenswert?

Stefan E. schrieb:
> Jan H. schrieb:
>> Ja. Nur wieso klappt es ohne dem Bootloader im Flash?
>
> Weil der RAM-Inhalt nicht der Gleiche ist. Wenn du nur das Programm
> brennst und ohne Power-Cycle dazwischen laufen lässt, hat das RAM Nullen
> als Default-Inhalt. Beim Start über den Bootloader steht dort der vom
> Bootloader zurückgelassene "Müll".
>
> Ich tippe auf eine vergessene String-Terminierung.

Muss ich überhaupt einen String, den ich der Funktion übergebe, 
terminieren?
Sprich uart_puts("Ich bin nicht terminiert")

Das macht doch der Compiler automatisch oder etwa nicht?

von Stefan E. (sternst)


Lesenswert?

String-Literale enthalten bereits eine Terminierung.

von Jan H. (janiiix3)


Lesenswert?

Stefan E. schrieb:
> String-Literale enthalten bereits eine Terminierung.

Also sollte es daran nicht liegen. Kann ich den RAM irgendwie löschen?

von Stefan E. (sternst)


Lesenswert?

Jan H. schrieb:
> Kann ich den RAM irgendwie löschen?

Das würde bestenfalls die Symptome kaschieren.

Suche die eigentliche Ursache des Problems.

von Jan H. (janiiix3)


Lesenswert?

Stefan E. schrieb:
> Jan H. schrieb:
>> Kann ich den RAM irgendwie löschen?
>
> Das würde bestenfalls die Symptome kaschieren.
>
> Suche die eigentliche Ursache des Problems.

Ich bin schon alles durchgegangen. Bin am verzweifeln. Weiß echt nicht 
mehr weiter was es noch sein kann.

von Stefan E. (sternst)


Lesenswert?

Jan H. schrieb:
> Ich bin schon alles durchgegangen. Bin am verzweifeln. Weiß echt nicht
> mehr weiter was es noch sein kann.

Jan H. schrieb:
> Manchmal aber.. Kommen Zeichen aus dem
> UART oder aber auf dem GLCD

Diese Zeichen erscheinen ja wohl kaum zufällig.
Also stelle fest, an welcher Stelle der Programmausführung sie 
erscheinen, dann hast du auch einen Ausgangspunkt für die Fehlersuche.

von c-hater (Gast)


Lesenswert?

Jan H. schrieb:

> Wieso funktioniert mein Programm, wenn ich es ohne den Bootloader an
> Board drauf habe? Das ist doch Paradox..

Nein. Deine Anwendung geht von einem System aus, wie es sich nach einem 
Hardware-Reset präsentiert. Der Sprung von Bootloader in das Programm 
ist aber eben kein solcher Hardware-Reset.

D.h.: die Ausgangsbedingungen unterscheiden sich. Bei fehlerfreiem 
Programm UND fehlerfreiem Bootloader sollte sich kein Unterschied im 
Verhalten der Anwendung ergeben (mit einer einzigen Ausnahme: Code, der 
das Hardware-Register zur Ursache eines Resets auswertet, da darf und 
muss sich das Ergebnis unterscheiden).
Existiert eine solche Fallunterscheidung bezüglich der Resetursache im 
Code der Anwendung nicht und ergibt sich wider Erwarten wie in deinem 
Fall trotzdem ein Unterschied im Verhalten der Anwendung, ist 
logischerweise mindestens eine der beiden Komponenten fehlerhaft, 
möglicherweise auch beide...

Ich aber würde aber eindeutig auf dein Programm tippen...

von Jan H. (janiiix3)


Lesenswert?

c-hater schrieb:
> Jan H. schrieb:

> D.h.: die Ausgangsbedingungen unterscheiden sich. Bei fehlerfreiem
> Programm UND fehlerfreiem Bootloader sollte sich kein Unterschied im
> Verhalten der Anwendung ergeben (mit einer einzigen Ausnahme: Code, der
> das Hardware-Register zur Ursache eines Resets auswertet, da darf und
> muss sich das Ergebnis unterscheiden).
> Existiert eine solche Fallunterscheidung bezüglich der Resetursache im
> Code der Anwendung nicht und ergibt sich wider Erwarten wie in deinem
> Fall trotzdem ein Unterschied im Verhalten der Anwendung, ist
> logischerweise mindestens eine der beiden Komponenten fehlerhaft,
> möglicherweise auch beide...
>
> Ich aber würde aber eindeutig auf dein Programm tippen...

Was muss ich in meiner Applikation beachten nach dem Sprung vom 
Bootloader? Muss ich irgendwelche Register löschen oder deaktivieren?

von c-hater (Gast)


Lesenswert?

Jan H. schrieb:

> Was muss ich in meiner Applikation beachten nach dem Sprung vom
> Bootloader? Muss ich irgendwelche Register löschen oder deaktivieren?

Nicht, wenn der Bootloader fehlerfrei ist...

Dein Problem dürfte sich aber eher in Bereichen abspielen, wo nur der 
gnädige Gott Zufall die erwünschte Reaktion der Anwendung ermöglicht: 
Sprich: da sind sehr wahrscheinlich Bugs drin, die sich nur zufällig im 
Normalfall nicht offensichtlich schädlich bemerkbar machen, aber 
reproduzierbar mit dem Speicherinhalt, den der Bootloader hinterläßt. 
Das ist aber dann KEIN Bug des Bootloaders!

von Marco H. (damarco)


Lesenswert?

Stefan E. schrieb:
> String-Literale enthalten bereits eine Terminierung.

und eine Adresse die der Funktion übergeben wird und da kann es mit 
Bootloader Probleme geben wenn der Code falsch gelinkt wurde bzw. er 
diese Adressen beim Hochladen verschiebt.

Dann übergibt er Müll in die Funktion.

von Jan H. (janiiix3)


Angehängte Dateien:

Lesenswert?

Mein Programm habe ich jetzt bis auf ein paar UART Ausgaben zurück 
geschraubt. Es ist keine Änderung zu sehen.
Auf dem Bild sieht man es klar und deutlich.
1
int main(void)
2
{
3
  uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,16e6));
4
  sei();
5
6
  while (1)
7
  {    
8
    uart_puts("************************************\r\n");
9
    uart_puts("* J.H-Elec. - Booty\r\n");
10
    uart_puts("* reset AVR and hold \"p\" for flash\r\n");
11
    uart_puts("************************************\r\n");
12
13
    if (uart_getc() == 'p')
14
    {
15
      bootloader();
16
    }
17
    
18
    _delay_ms(1500);        
19
  }
20
}
21
22
/* live the CPU?*/
23
ISR(TIMER1_COMPA_vect)
24
{
25
}

Das ist der Code der die Ausgabe verursacht. Wie gesagt, flashe ich nur 
die Applikation drauf ohne Bootloader klappt es wunderbar.

von Marco H. (damarco)


Lesenswert?

Der Code ist schon sehr .....

Ok du willst also beim starten ein Char Abfragen um den Bootloader 
aufzurufen. Mit Bootloader und Code kommt auf die Usart was anderes als 
erwartet.

Na sagte ich doch was passiert, genau das passiert auch. Du links deinen 
Code ohne den Bootloader zu berücksichtigen der irgend wo im Speicher 
ist. Der Funktion wird ein Pointer übergeben der nun auf etwas anderes 
Zeigt. Da du die Adressen vermutlich verschiebst.

Warum nutzt du keinen Timer um eine Zeit X zu warten ob ein Char 
übergeben wird und prüft es. Beim Ablauf startest du dein Programm.

Noch besser ist einfach zu schauen von wo der Reset kam. Power on oder 
der Reset Extern wurde ausgelöst. Dann braucht man den Kram nicht und 
verzögert auch den Start nicht unnötig.

Schau dir andere Bootloader an wie die das machen und in die Referenz 
wie der mega32 mit einen Bootloader umgeht bzw. wo dieser im Flash sein 
sollte.

von Marco H. (damarco)


Lesenswert?

Das mit den gedrückt halten ist auch selten dämlich ehrlich gesagt....

von Jan H. (janiiix3)


Lesenswert?

Marco H. schrieb:
> Der Code ist schon sehr ....

> Warum nutzt du keinen Timer um eine Zeit X zu warten ob ein Char
> übergeben wird und prüft es. Beim Ablauf startest du dein Programm.
>
> Noch besser ist einfach zu schauen von wo der Reset kam. Power on oder
> der Reset Extern wurde ausgelöst. Dann braucht man den Kram nicht und
> verzögert auch den Start nicht unnötig.
>
> Schau dir andere Bootloader an wie die das machen und in die Referenz
> wie der mega32 mit einen Bootloader umgeht bzw. wo dieser im Flash sein
> sollte.

Woher willst du wissen das meine Applikation an der falschen Stelle 
steht? Linker?

von Karim Rezapasand (Gast)


Lesenswert?

Hi friends
instead of
       void (*start)( void ) = (void*)0x0000;
must be
       void (*start)( void ) = 0x0000;

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.