Forum: Mikrocontroller und Digitale Elektronik AVR und 32Bit-Adressen


von Frank Roggel (Gast)


Lesenswert?

Hallo zusammen,

ich rechne eine CRC über meinen Programmcode und hab dazu eine 
Dummy-Section angelegt, deren Adresse mir anzeigt, wo der Programmcode 
aufhört:
1
const uint16_t  Dummy        __attribute__((section (".dummy"      ), used, unused)) = 0xAAAA;
2
const uint16_t  AddresseVonDummy  __attribute__((section (".addressevondummy"  ), used, unused)) = (uint16_t)&Dummy;
Der Wert AddresseVonDummy liegt an einer fixen Adresse im Hexfile, damit 
ich den Wert im Bootloader auslesen kann.

Das funktioniert einwandfrei, aber nur mit 16Bit-Adressen.

Wenn ich ganze für einen ATMega1284 bauen will, bräuchte ich 
32Bit-Adressen.
Wenn ich nun folgendes probiere
1
const uint16_t  Dummy        __attribute__((section (".dummy"      ), used, unused)) = 0xAAAA;
2
const uint32_t  AddresseVonDummy  __attribute__((section (".addressevondummy"  ), used, unused)) = (uint32_t)&Dummy;
steht in AddresseVonDummy immer noch 0x00000000 drinn.

Wie geht das?

von (prx) A. K. (prx)


Lesenswert?

Eine Funktion, die eine CRC auf einen Datenblock im RAM berechnet, ist 
auf einem AVR  nicht für ROM einsetzbar. Das musst du Byte für Byte 
berechnen, indem du mit einem Pointer ins ROM jedes Byte holst.

: Bearbeitet durch User
von Frank Roggel (Gast)


Lesenswert?

A. K. schrieb:
> Eine Funktion, die eine CRC auf einen Datenblock im RAM berechnet,
> ist
> auf einem AVR  nicht für ROM einsetzbar. Das musst du Byte für Byte
> berechnen, indem du mit einem Pointer ins ROM jedes Byte holst.

Sicher, aber das hat nichts mit meinem Problem zu tun.

Mir geht es nur darum, wie ich auf einem AtMega1284 den Adressen 
jenseits der 64kByte darstellen kann.

von Jim M. (turboj)


Lesenswert?

Wir lösen auf:

Dein ATMega1284 Build nutzt ein anderes Linker Skript, dass keine 
"dummy" Section kennt. Daher landet dummy an Addresse Null.

Schau also mal bei den entsprechenden Linker Skripten nach.

von Peter D. (peda)


Lesenswert?


: Bearbeitet durch User
von Frank Roggel (Gast)


Lesenswert?

Jim M. schrieb:
> Wir lösen auf:
Schön wär's.


Ich hab folgenden Code:
1
const uint16_t  Dummy        __attribute__((section (".dummy"      ), used, unused)) = 0xAAAA;
2
const uint32_t  AddresseVonDummy32  __attribute__((section (".addressevondummy32"  ), used, unused)) = (uint32_t)&Dummy;
3
const uint16_t  AddresseVonDummy16  __attribute__((section (".addressevondummy16"  ), used, unused)) = (uint16_t)&Dummy;

Den kann ich auf einem ATMega644 oder auf einem ATMega1284 erzeugen, und 
es gibt immer das gleiche Ergebnis:
In AddresseVonDummy16 stehen die korrekten unteren 16Bit der Adresse von 
Dummy drinn.
In AddresseVonDummy32 steht 0x00000000 drinn.

Siehe Hexfile vom ATMega128P:
Dummy liegt an Adresse 0x0000050A.
AddresseVonDummy32 liegt an Adresse 0x1F7F4 und enthält 0x00000000.
AddresseVonDummy16 liegt an Adresse 0x1F7F8 und enthält 0x050A.
1
(...)
2
:02050A00AAAA9B
3
:020000021000EC
4
:04F7F4000000000011
5
:02F7F8000A0500
6
:00000001FF

von Frank Roggel (Gast)


Lesenswert?

Peter D. schrieb:
> http://www.avrfreaks.net/sites/default/files/morepgmspace.h

Danke, aber hilft leider auch nicht.

GET_FAR_ADDRESS() ist ja AVR Code.
In meinem Fall müßte ja der Linker die Adresse von Dummy ausfüllen.

von Stefan E. (sternst)


Lesenswert?

Frank Roggel schrieb:
> Wenn ich ganze für einen ATMega1284 bauen will, bräuchte ich
> 32Bit-Adressen.

Ich würde dafür einfach eine kleine Assembler-Datei in das Projekt 
integrieren:
1
  .global  AddresseVonDummy
2
  .section  .addressevondummy,"a",@progbits
3
  .type  AddresseVonDummy, @object
4
  .size  AddresseVonDummy, 4
5
AddresseVonDummy:
6
  .byte  lo8(Dummy)
7
  .byte  hi8(Dummy)
8
  .byte  hh8(Dummy)
9
  .byte  0


Kleiner Hinweis am Rande:
Es heißt eigentlich "Adresse" (mit einfachem d).

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Frank Roggel schrieb:
> const uint16_t  Dummy        __attribute__((section (".dummy"      ),

Schlecht, vermutlich eine Orphan Section.  Deren Position wird als durch 
implizite Regeln von ld für entsprechende Sections bestimmt.

Besser: definier ein eigenes Symbol in deinem Linker Skript.  Hat zudem 
den Vorteil, dass der CRC nicht nur über Code geht sondern auch über die 
Daten, welche zur Initialisierung des SRAM verwendet werden (also für 
.data und .rodata).

An die Adresse kommt man dann z.B. so:
1
#include <stdint.h>
2
3
extern uint8_t __data_load_end; // defined in ld script
4
5
uintptr_t getp (void)
6
{
7
    return (uintptr_t) &__data_load_end;
8
}
9
10
uint32_t getp32 (void)
11
{
12
    uint32_t addr;
13
    __asm ("ldi %A0, lo8(%1)" "\n\t"
14
           "ldi %B0, hi8(%1)" "\n\t"
15
           "ldi %C0, hh8(%1)"
16
           : "=d" (addr) : "i" (&__data_load_end));
17
    return addr;
18
}
19
20
extern const __memx uint8_t p24_memx[] __asm ("__data_load_end");
21
22
const __memx uint8_t* getp24_memx (void)
23
{
24
    return p24_memx;
25
}

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.