Hallo
ich will einige Funktionen (arm-gcc) ins Ram kopieren, um deren
Ausführzeiten zu beschleidnigen. Das Flash ist nur mit 16bit verbunden.
Unter http://www.embeddedrelated.com/groups/lpc2000/show/5031.php habe
ich eine Diskussion über das Thema gefunden. Dort taucht folgender
Abschnitt auf:
So to summarize, to get and use a function in RAM you only need to do
three things:
(1) Have an init in the startup code for the .data section.
(2) Use the __attribute__((section(".data"))) on the functions.
(3) Define function pointer variables for the functions and make
indirect calls using those.
Zu Punkt 1:
In meinem Startup-Code gibt es folgenden Abschnitt:
1
/* copy initialized variables .data section (Copy from ROM to RAM) */
Ich hab von Assembler nicht viel Ahnung. Wenn ich den Code richtig
verstehe, wird die data Section hier ins Ram kopiert.
Zu Punkt 2:
Das ganze sollte also so aussehen:
1
voidfoo(void)__attribute__((section("data")));
Soweit verstehe ich das ganze noch. Mit dem Attribut der der Compiler
angewiesen, die Funktion in dem Bereich abzulegen, in dem die Variablen
im Ram liegen. Im Startup-Code wird dann die Funktion vom Flash ins Ram
kopiert.
Zu Punkt 3:
Es soll ein Pointer verwendet werden, um die Funktion anzusprechen, also
z.B.:
1
void*foopointer=&foo;
2
foopointer();
So, jetzt meine Fragen:
Funktioniert das ganze so wirklich?
Wofür wird der Umweg über den Pointer benötigt?
Vielen Dank,
Tilo
Das beantwortet Karl Olsen in der gleichen Diskussion:
Nice trick of just locating the RAM function in .data.
With main() in flash and IAP_Test() in RAM, they are ~1GB apart, and
a normal BL instruction can only handle distances of up to +/- 32 MB.
Try calling it indirectly:
static void (*pramfunc)(void) = IAP_Test;
(*pramfunc)();
Dirch den Funktionszeiger soll Maschinencode erzeugt werden, der sog.
long calls ermöglicht. Nicht die üblichen, platzsparenderen short calls
innerhab der üblichen Flash-Adressbereiche.
dac.c:96: error: conflicting types for 'DAC_Aquiredata'
dac.h:6: error: previous declaration of 'DAC_Aquiredata' was here
So, nun bin ich etwas verwirrt. Unter
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index.html#gcc_ramfunc
habe ich ei Beispiel gefunden. Ich verwende einen aduc, das Beispiel ist
für einen lpc. Sollte aber dem GCC egal sein.
In diesem Beispiel wurde das so gemacht:
Das funktioniert so bei mir auch. Leider gibt der Compiler eine Warnung
aus:
Warning: ignoring changed section attributes for .data
Laut http://www.spinics.net/lists/arm-kernel/msg24864.html ist das so,
da in diesem Bereich kein Code ausgeführt werden darf. Das kann ich in
diesem Fall dann acuh nachvollziehen. Ich weiß aber nicht, warum das so
ist. Muss irgend wo noch markiert werden, welcher Code ausgeführt werden
darf?
Ich hab die von mir verwendete Datei, in der die Sektionen definiert
sind, angehängt. Sieht da einr von euch etwas dran?
Fehlt eine Option in der Makefile?
Danke, Tilo
Hallo
Also ich hab keine speziellen Parameter in der Makefile drin. (GCC
4.2.2)
Ich wollte einen Sinus (DSS) über einen DAC ausgeben. Auf dem Oszi hat
man deutlich gesehen, dass (bei mir) SRAM deutlich schneller als FLASH
ist.
-mlong-calls is meines Wissens in "pauschales" _attribute_ (long_call)
für alle Funktionen und dürfte ein wenig an der Performance knabbern.
Ist allerdings die simpelste Lösung, um um die Sprungweitenbegrenzung
herumzuarbeiten. Selektiver mit dem o.g. Ansatz.
BTW: in einem der Beträge oben:
>dac.c:96: error: conflicting types for 'DAC_Aquiredata'>dac.h:6: error: previous declaration of 'DAC_Aquiredata' was here
sieht nach Unterschied in Deklaration (.h) und Definition (.c) der
Funktion aus. Aber Problem hat sich ja schon vor längerem in
wohlgefallen aufgelöst.