AVR-gcc: strukturen mit Funktions-pointern im progmem liefert falsche pointer

OP #2944799
Lesenswert?
• ▲
▼
Hallo!

Habe da einen seltsamen "Effekt" bei meinem neuen Projekt:

Der folgende Code-schnipsel:
1
void loop4ever(uint16_t *t);
2
typedef struct test {
3
        void (*init)(uint16_t* t);
4
} test_t;
5
const test_t mytest __attribute__((progmem)) __attribute__((aligned (8))) = {
6
        .init=&loop4ever,
7
};
8
void loop4ever(uint16_t *t) { while(1) { t++;} }

produziert im gedumpten elf (avr-objdump -Dz main.elf):
1
...
2
00000088 <mytest>:
3
  88:   a6 00           .word   0x00a6  ; ????
4
  8a:   00 00           nop
5
  8c:   00 00           nop
6
  8e:   00 00           nop
7
...
8
0000014c <loop4ever>:
9
 14c:   ff cf           rjmp    .-2             ; 0x14c <loop4ever>

man sieht, daß der Pointer in mytest eindeutig an eine falsche Adresse 
zeigt (0x00a6 und nicht an 0x014c) - und ja, ich sehe es auch wenn ich 
mir die Adresse von meinem Code auf USART ausgeben lasse...

Sitze ich da einem compiler/linker bug auf?
Denn IMO sollte der code eigentlich ja korrekte Pointer produzieren...

Hat jemand schon ein ähnliches Problem gehabt und auch vielleicht auch 
gelöst?

Danke,
        Martin

P.s: und das nicht funktionierende Alignment in C mit progmem sei hier 
nur eine Randnotiz

P.s: der avr-gcc ist 4.7.0
Persönliche Seite #2944975
Lesenswert?
• ▲
▼
Martin Sperl schrieb:
> Hallo!
>
> Der folgende Code-schnipsel:
>
> void loop4ever(uint16_t *t);
> typedef struct test {
>         void (*init)(uint16_t* t);
> } test_t;
> const test_t mytest __attribute__((progmem)) __attribute__((aligned
> (8))) = {
>         .init=&loop4ever,
> };
> void loop4ever(uint16_t *t) { while(1) { t++;} }

Tu dir einen Gefallen und formatiere den Code :-)

> P.s: und das nicht funktionierende Alignment in C mit progmem sei hier
> nur eine Randnotiz

Wieso? mytest ist doch auf 8 Bytes aligned?

> P.s: der avr-gcc ist 4.7.0

Nicht wirklich empfohlen, insbesondere wenn du Xmega oder Devices mit 
8-Bit SP verwendest.  Immer die Release Notes lesen!!!

http://gcc.gnu.org/gcc-4.7/changes.html

Seit mehreren Monaten gibt es avr-gcc 4.7.2.

Mit 4.7 brauchst du auch kein progmem mehr.  Wenn mytest im Flash liegt 
willst du wahrscheinlich auch irgendwann drauf zugreifen?
1
#include <stdint.h>
2

3
typedef struct 
4
{
5
    void (*init)(uint16_t*);
6
} test_t;
7

8
static void loop4ever (uint16_t *t)
9
{
10
    (void) t;
11
    while(1);
12
}
13

14
const __flash test_t mytest __attribute__((aligned(8))) =
15
{
16
    .init = loop4ever
17
};
18

19
void runtest (const __flash test_t *t, uint16_t *val)
20
{
21
    t->init (val);
22
    mytest.init (0);
23
}
 
Das ergibt:
 
1
loop4ever:
2
.L2:
3
  rjmp .L2
4

5
runtest:
6
  movw r30,r24
7
  lpm r0,Z+
8
  lpm r31,Z
9
  mov r30,r0
10
  movw r24,r22
11
  icall
12
.L4:
13
  rjmp .L4
14

15
.global  mytest
16
  .section  .progmem.data,"a",@progbits
17
  .p2align  3
18
  .type  mytest, @object
19
  .size  mytest, 2
20
mytest:
21
  .word  gs(loop4ever)
22
  .ident  "GCC: (GNU) 4.7.2"
 
Wie man sieht ist da auch das gewünschte .p2align 3.
OP #2945041
Lesenswert?
• ▲
▼
Auf das mit dem align bin ich auch gekommen, daß es geht - bin über den 
Unterschied im align parameter zwischen gas und gcc gestolpert...

Das update mit dem Compiler ist nett - ich mache mich einmal auf die 
Suche nach neuen deb gcc-avr Paketen für den RPI... (updates dafür gibt 
es leider nicht im "Standard"...)

Danke nochmals allen Helfern!
Martin

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.