PROGMEM an bestimmte adresse ?

Gast #758331
Lesenswert?

Hallo,

wie bekomme ich eine Tabelle an eine bestimmte Adresse im Flash ?

Konkret:
Ich habe vier uint8_t tabellen mit - jeweils - einer Größe von 512 
Bytes.
Wie bekomme ich die Tabellen hinter die Interrupt-Tabelle an "runde" 
Adressen ?
Also z.b. 0x100, 0x300, 0x500, 0x700 ?

Das Programm könnte dahinter beginnen. Oder Umgegekehrt, erst das 
Programm, dann die Tabellen.
Ich benötige das für einen optimierten Zugriff auf diese Tabellen.
Gast #758360
Lesenswert?

Habe jetzt mit einer  zus#tzlichen Dummy-Tabelle "getrickst":
1
const uint8_t dummy_tab [0x100-_VECTORS_SIZE] PROGMEM= {0x0};
2

3
const prog_uint8_t sine_tab   [512] PROGMEM= {0x0....

So beginnt sine_tab an 0x100.

Das ist nur für mich, wird nie veröffentlicht, und ein vermutlich wird 
es auch nie ein Update mit anderem Compiler geben.

Aber trotzdem: Das mss doch irgendwie eleganter gehen ?
Gast #758511
Lesenswert?

Eigene sections:

Im C-Quellcode z.B.:

char xyz[] MY_SECTION = {1, 2, 3};

Dem Linker werden Sections wie folgt mitgeteilt:

LDFLAGS=-Wl,-section-start=.MY_SECTION=0xfd00

OBJCOPY benoetigt natuerlich auch die Informatrion welche sections es 
z.B. ins hex File verwursten soll.

$(OBJCOPY)  -j .text -j .MY_SECTION -O $(FORMAT) $< $@

Gruss,
Ludger

P.S.

Wenn man C und Assembler mischt, und die page aligned Daten im Assembler 
definiert, kann man einfach mit:

.align 8
xyz:

xyz auf eine gerade Seitenadresse (0x100 * n) ausrichten.
Gast #758522
Lesenswert?

Ui..danke für den Link.

Genau um sowas geht es :-)

Warum soll ich nicht tricksen ? Alternativ könnte ich Assembler 
programmieren, aber das Ergebnis ist genausowenig portabel.

Der Compiler kann mir das nicht optimieren (glaube ich). Wenn die 
Tabelle an einer "schiefen" adresse Beginnt, ist eine Addition mehr 
fällig. Oder ein zustzliches "IF" wenn die Adresse wieder auf 0 springen 
soll. Bei glatten Adressen reicht ein "and".

Die Tabelle soll im Interrupt von Anfang bis Ende ausggeben werden, und 
das ganze soll danach wieder von vorn beginnen.
Wie würdet Ihr das optimal , ohne Assembler, lösen ?
#758530
Lesenswert?

@ Bastler (Gast)

>soll. Bei glatten Adressen reicht ein "and".

Schon klar, aber.

>Die Tabelle soll im Interrupt von Anfang bis Ende ausggeben werden, und
>das ganze soll danach wieder von vorn beginnen.

Glaub ja nicht, dass der GCC so ultrakompakte Interrupts generiert wie 
man es in ASM kann. Allein schon die Pointerspeicherung in exklusiben 
Registern etc. ist nur mit tierischen verrenkungen drin. Da wird einiges 
an Overhead reingebaut. Da spielt eine Pointerberechnung/ Addition keine 
Rolle mehr. Wenn es wirklich auf hohe Leistung getrimmt werden soll, 
nimm ASM. Ist einfacher und im Ergebnis schneller als alle 
Compilertricks.

MfG
Falk
Moderator Persönliche Seite #758777
Lesenswert?

Du kannst ja auch nur die ISR im Assembler programmieren und den Rest
in C.

Sinnvoller ist es übrigens, die Tabelle per eigener section und
-Wl,--section-start ans obere Ende des Flashs zu legen (ggf. unter
den Bootloader, falls du einen hast), dann kollidierst du am
wenigsten mit der Allokation des Flashs durch den Linker, die ja
von unten beginnt.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren