Forum: Compiler & IDEs PROGMEM an bestimmte adresse ?


von Bastler (Gast)


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.

von Falk B. (falk)


Lesenswert?

@ Bastler (Gast)

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

Muss man irgendwie dem Linker verclickern. Keine Ahnung.

>Ich benötige das für einen optimierten Zugriff auf diese Tabellen.

Solche Tricks würde ich mir in C verkneifen.

MFG
Falk

von Bastler (Gast)


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 ?

von Mark .. (mork)


Lesenswert?

Du musst eine neue Section im Linkerscript anlegen und sie an der 
erwünschten Adresse beginnen lassen. Dann legst Du die Tabelle einfach 
in diese Section.

MfG Mark

von Bastler (Gast)


Lesenswert?

Ups...gibts es dazu irgendwo im Netz ein Tutorial ?

von holger (Gast)


Lesenswert?

>>Ich benötige das für einen optimierten Zugriff auf diese Tabellen.
>Solche Tricks würde ich mir in C verkneifen.

Ich auch ! Der Compiler optimiert für dich. Wahrscheinlich
besser als du selber das kannst.

Die unvermeidliche Frage: Wozu soll das gut sein ?

von Falk B. (falk)


Lesenswert?

@ holger (Gast)

>Die unvermeidliche Frage: Wozu soll das gut sein ?

Ich tippe mal auf Soft-DDS. So wie hier.

http://www.myplace.nu/avr/minidds/index.htm

MFG
Falk

von Ludger (Gast)


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.

von Bastler (Gast)


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 ?

von Bastler (Gast)


Lesenswert?

@Ludger:

Danke !!!

von Falk B. (falk)


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

von Bastler (Gast)


Lesenswert?

@Falk
Ich probier's trotzdem mal :-)

Ich poste das Ergebnis dann hier... ich befürchte aber, Du hast recht 
und ich programmiere anschliessend die Assembler-Version ;-)

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


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.

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.