STM32F4 CCM / OpenOcd issue

OP #6137767
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
#6137804
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.
Gast #6138563
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.
OP #6141502
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
Gast #6141547
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
Gast #6141571
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
(Firma: fritzler-avr.de) #6141579
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.