Hallo Mikrocontroller-Forum,
mein STM32F405RGTx verfügt über 64K CCMRAM und das möchte ich gerne
nutzen:
Linker Script:
...
MEMORY
{
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
CCMRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K
}
...
SECTIONS {
...
.ccmram_bss (NOLOAD) : {
*(.ccmram_bss*)
. = ALIGN(4);
} >CCMRAM
...
Define:
#define CCMRAM_BSS __attribute__((section(".ccmram_bss")))
Main cpp:
...
CCMRAM_BSS Ecg ecg[DacInternal::Channels];
...
In der Systemconfig rufe ich außerdem noch
rcc_periph_clock_enable(RCC_CCMDATARAM);
auf (jep, ich benutze libopencm3), aber das ist möglicherweise auch
nicht nöitg.
Ich habe 2 unterschiedliche Probleme mit dieser Konfiguration.
Problem 1:
So wie hier beschrieben funktioniert das Programm garnicht mehr. Nehme
ich in der main cpp jedoch die Deklaration "CCMRAM_BSS" wieder weg, so
dass das Objekt im "normalen" SRAM liegt, ist alles in Ordnung.
Problem 2:
Nehme ich im Linker-Skript (NOLOAD) weg (so findet es sich in den
meisten Forenbeiträgen), dann schläg das Flashen mit OpenOCD fehl:
Error: checksum mismatch - attempting binary compare
diff 0 address 0x10000000. Was 0xb4 instead of 0x00
diff 1 address 0x10000001. Was 0x01 instead of 0x00
diff 2 address 0x10000004. Was 0xb4 instead of 0x00
...
Es hat entweder den Anschein, dass OpenOCD Probleme hat, auf 0x10000000
zuzugreifen oder aber der CCMRAM-Mechanismus funktioniert noch nicht wie
er soll.
Als weiteren Test habe ich eine Variable als einzigen Member von CCMRAM
einkompiliert
...
static CCMRAM_BSS volatile const uint32_t meinsuperwert = 204;
...
und nach dem Flashen (nun wieder mit (NOLOAD)) die Speicheradresse
geprüft. Diese blieb jedoch unverändert (0x01b4, wie oben im Error-Log).
Hat jemand vielleicht einen Tip für mich, wie ich das hinbekomme?
Besten Dank,
Oliver
Oliver W. schrieb: > dann schläg das Flashen mit OpenOCD fehl: Flashen kann man offensichtlich nur Flash Memory - und nicht den RAM. Hint: Schau Dir das Linker Script mal ganz genau an - das Datensegment landet nämlich im Flash (hinter dem Code). Da kannste das CCRAM auch hin packen, musst dann aber manuell kopieren oder den Startup Code ändern.
Oliver W. schrieb: > Hat jemand vielleicht einen Tip für mich, wie ich das hinbekomme? Wenn Du das CCM nicht im Startupcode initialisierst, dann steht da natürlich noch Müll drin. Sofern Du dort nur Variablen hinlegst, die mit 0 initialisiert werden sollen, kannst Du den ganzen Bereich einfach im Startup nullen. Sollen anders vorinitialisierte Variablen rein, muß eine Kopierschleife ähnlich der fürs SRAM vorhandenen auch fürs CCM in den Startupcde.
Hallo Jim, Nop, liebe Community,
tatsächlich sind mir die Initialisierungswerte nicht wichtig, da diese
in einer separaten init()-Methode gesetzt werden. Dennoch habe ich
folgendes ausprobiert:
Definition im Linker-Skript angepasst:
_siccmram = LOADADDR(.ccmram_bss);
.ccmram_bss : {
. = ALIGN(4);
_sccmram_bss = .; /* create a global symbol at ccmram_bss start */
*(.ccmram_bss)
*(.ccmram_bss*)
. = ALIGN(4);
_eccmram_bss = .; /* create a global symbol at ccmram_bss end */
} >CCMRAM AT> ROM
So klappt es schonmal mit dem Flashen und OpenOCD ohne NOLOAD. Gute
Sache!
Dann Initialisierung(-sversuch) mit folgendem Code:
...
extern unsigned _sccmram_bss, _eccmram_bss, _siccmram;
static void init_ccmram_bss(void) {
unsigned *src = &_siccmram;
unsigned *dst = &_sccmram_bss;
while (dst < &_eccmram_bss) {
*dst++ = *src++;
}
}
__attribute__((used)) __attribute__((section(".preinit_array"))) static
void (*g_handler[])(void) = { &init_ccmram_bss };
...
Ist jetzt nicht alles auf meinem Baum gewachsen wie man sich vorstellen
kann, aber kompiliert sauber durch und kann auf den Prozessor geflasht
werden.
Leider nach wie vor das gleiche Problem: die Objekt-Instanzen, die ich
in den CCM gehoben habe (siehe Ecg array oben), arbeiten nicht.
Wie sollte ich eurer Meinung nach weiter vorgehen?
Besten Dank,
Oliver
Also ich bin nicht ganz sicher, ob ich verstehe, was Du machen willst aber... Im Blockschaltbild (https://www.st.com/resource/en/datasheet/stm32f405rg.pdf Seite 19) siehst Du, dass die CPU nur über den D-Bus aufs CCM zugreifen kann, nicht über den I- und S-Bus. Du kannst also nur Daten, keinen Code ins CCM verlagern. Ich wollte mal Code ins CCM verlagern und das ging natürlich (wie mir der IAR-Support dann erklärt hatte) nicht. - Martin
Hallo Martin, das ist in Ordnung. Der Code der Methoden ist nach meinem Verständnis im ROM und der Prozessor verarbeitet die Klasseneigenschaften über den dort bereitgestellten Code. Es geht mir vielmehr um einen möglichst effizienten Zugriff auf diese Eigenschaften, da es sich um DSP-Code handelt, die innerhalb von Interrupt-Routinen möglichst effizient verarbeitet werden sollen. Man liest hier von teils 30% Geschwindigkeitszuwachs. Ich bin inzwischen auch soweit, dass ich wieder Leben im Programm habe. Die Ecg-Objekte befinden sich nachvollziehbar an der Adresse 0x10000000 aufwärts. Ich kann allerdings nicht mehr nachvollziehen, warum es eben noch, als ich meinen zweiten Post verfasst habe, nicht funktioniert hat. Das ist natürlich nur so mittel hilfreich für das Forum. Aber die Code-Schnipsel oben sind dbei unverändert geblieben. Von daher kann ich bestätigen, dass dies tatsächlich der richtige Weg ist. Danke nochmal und viele Grüße, Oliver
Ein make clean all wirkt manchmal wunder ;) Aber wenn du die CCMRAM section initialisieren willst, dann nenn die bitte nicht _bss, das suggeriert einen pre init ausschließlich mit Nullen. _data ist das was du willst. Wenn du später mal ind en Code guckst und as bss heißt dann kommen dir sicherlich die Fragezeichen über die Stirn.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.