Hallo,
ich versuche folgendes Problem zu lösen: Meine Applikation hat einen
Parameter (SessionID), dieser soll an den Bootloader übergeben, damit
dieser nahtlos die Session übernehmen kann. Aus der Applikation springe
ich folgendermaßen weg (ATxmega 128A1, ich übergebe die ID 'as is' und
im high byte zusätzlich negiert):
1 | void jump_to_bootloader(uint8_t node)
|
2 | {
|
3 | #include <avr/io.h>
|
4 | t_data16 para;
|
5 | cli(); // Interrupts blockieren
|
6 |
|
7 | void (*bootloader)(uint16_t temp) = (void*) 0;
|
8 | // Funktionspointer auf 0x0000, aber mit EIND wird das 0x10000 (word);
|
9 |
|
10 | para.low8 = node;
|
11 | para.high8 = ~node;
|
12 | EIND = 1;
|
13 | bootloader(para.as_uint16); // Jump Bootloader
|
14 | }
|
Der Compiler baut daraus dann:
1 | void jump_to_bootloader(uint8_t node)
|
2 | {
|
3 | 18c0: 98 2f mov r25, r24
|
4 | #include <avr/io.h>
|
5 | t_data16 para;
|
6 | cli(); // Interrupts blockieren
|
7 | 18c2: f8 94 cli
|
8 |
|
9 | void (*bootloader)(uint16_t temp) = (void*) 0; // Funktionspointer auf 0x0000, aber mit EIND wird das 0x10000 (word);
|
10 |
|
11 | para.low8 = node;
|
12 | para.high8 = ~node;
|
13 | EIND = 1;
|
14 | 18c4: 81 e0 ldi r24, 0x01 ; 1
|
15 | 18c6: 8c bf out 0x3c, r24 ; 60
|
16 | bootloader(para.as_uint16); // Jump Bootloader
|
17 | 18c8: 89 2f mov r24, r25
|
18 | 18ca: 90 95 com r25
|
19 | 18cc: e0 e0 ldi r30, 0x00 ; 0
|
20 | 18ce: f0 e0 ldi r31, 0x00 ; 0
|
21 | 18d0: 19 95 eicall
|
22 | }
|
23 | 18d2: 08 95 ret
|
Im Bootloader habe ich dann eine init0 section und eine uninitialisierte
Variable angelegt:
1 | t_data16 check __attribute__ ((section (".noinit")));;
|
2 | int my_init (int16_t idid) __attribute__ ((naked)) __attribute__ ((section (".init0")));
|
3 | int my_init(int16_t idid)
|
4 | {
|
5 | check.as_int16 = idid;
|
6 | }
|
Und wieder das Result des Compilers:
1 | 00020000 <__vectors>:
|
2 | 20000: 0d 94 fa 00 jmp 0x201f4 ; 0x201f4 <my_init>
|
3 | ...
|
4 | 000201f4 <my_init>:
|
5 | t_data16 check __attribute__ ((section (".noinit")));;
|
6 | int my_init (int16_t idid) __attribute__ ((naked)) __attribute__ ((section (".init0")));
|
7 | int my_init(int16_t idid)
|
8 | {
|
9 | check.as_int16 = idid;
|
10 | 201f4: 80 93 57 25 sts 0x2557, r24
|
11 | 201f8: 90 93 58 25 sts 0x2558, r25
|
12 | 201fc: 11 24 eor r1, r1
|
13 | 201fe: 1f be out 0x3f, r1 ; 63
|
14 | 20200: cf ef ldi r28, 0xFF ; 255
|
15 | usw.
|
D.h. der Code liegt sofort nach dem Resetvektor und sollte eigentlich
die Parameter ins RAM speichern. Nur da kommt kein komplementäres
Pärchen :-( Ich habe mir in der main.c vom bootloader die Variable check
in eeprom gesichert, da steht dann z.B. 0x82 0x07 drin. Jetzt bin ich da
etwas ratlos, habe auch hier schon gesucht und hoffe, dass einer der
Gurus hier den goldenen Tipp für mich hat.
Danke, Wolfgang