Forum: Compiler & IDEs xmega: Parameter aus Applikation an Bootloader übergeben


von Wolfgang (Gast)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wolfgang schrieb:
> dass einer der
> Gurus hier den goldenen Tipp für mich hat.

Alles mal mit einem Debugger verfolgen.

Der Code sieht sinnvoll aus, die Gurke muss woanders liegen.

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.