Hallo,
ich möchte von meinem Bootloader nach erfolgtem Flashen in die Anwendung
springen. Das Problem ist aber, dass das nicht so recht funktioniert.
Ich arbeite wie in der Application Note von Atmel gezeigt mit einem
Funktionszeiger auf die Adresse 0x0000. Vorher werden noch die
Interrupts wieder auf den Applikationsbereich umgebogen:
1 | void (*jump_to_main_application)( void ) = 0x0000;
|
2 |
|
3 | void main()
|
4 | {
|
5 |
|
6 | ...
|
7 | uint8_t temp;
|
8 | cli();
|
9 |
|
10 | // Get MCUCR
|
11 | temp = MCUCR;
|
12 |
|
13 | // Enable change of Interrupt Vectors
|
14 | MCUCR = (temp | (1<<IVCE));
|
15 |
|
16 | // Move interrupts to App Flash section
|
17 | MCUCR = (temp & ~(1<<IVSEL));
|
18 |
|
19 | jump_to_main_application();
|
20 |
|
21 | }
|
Wenn der Code ausgeführt wird, springt der AVR aber immer wieder in den
Bootloader, der dann in einer Endlosschleife immer wieder ausgeführt
wird. Hier noch Ausschnitte aus den lss und lst Dateien (bin leider des
Assemblers noch nicht so recht mächtig, um die Sprungadresse zu deuten):
1 | jump_to_main_application();
|
2 | 3e4e2: e0 91 06 02 lds r30, 0x0206
|
3 | 3e4e6: f0 91 07 02 lds r31, 0x0207
|
4 | 3e4ea: 19 95 eicall
|
5 | 3e4ec: a6 cf rjmp .-180 ; 0x3e43a <main+0x102>
|
6 |
|
7 |
|
8 | 1411 03d0 E091 0000 lds r30,jump_to_main_application
|
9 | 1412 03d4 F091 0000 lds r31,(jump_to_main_application)+1
|
10 | 1413 03d8 1995 eicall
|
11 | 1414 03da 00C0 rjmp .L144
|
12 |
|
13 | 1430 .global jump_to_main_application
|
14 | 1431 .global jump_to_main_application
|
15 | 1434 jump_to_main_application:
|
16 | 1435 0006 0000 .skip 2,0
|
Irgend eine Idee, was verkehrt läuft?
Die Anwendung, die geflasht wurde, funktioniert. Wenn ich die Fuse
BOOTRST lösche, wird die vom Bootloader geflashte Anwendung korrekt
ausgeführt).
Grüße, Jan