Forum: Mikrocontroller und Digitale Elektronik ST: CCM, DTCM, ITCM


von Speicherli (Gast)


Lesenswert?

Hallo!

Bei meinen Arbeiten mit dem STM32F4 habe ich den CCM (Core Coupled 
Memory) kennengelernt. Ein Speicherbereich, von dem ausschließlich von 
der Core aus zugegriffen werden kann (kein Peripherie-Zugriff, z.B. DMA) 
möglich.
Dafür ist der Zugriff schneller, was durchaus hilfreich sein kann.
Bei der Speicherverwendung muss man also schon etwas darauf achten, 
welche Speicherbereiche für was verwendet werden.

Bei der neuen STM32F7-Familie gibt es nun den DTCM (Data Tighly Coupled 
Memory) und ITCM (Instruction Tighly Coupled Memory).
Deren Sinn erschließt mich mir noch nicht.
Kann mir da jemand bitte auf die Sprünge helfen?

Danke & Grüße
Jürgen

von UweBonnes (Gast)


Lesenswert?

Der Sinn von ITCM ist klar. Dort kommen die schnellen Funktionen rein 
und man spart sich die Flash Latenz, Beim STM32H7 laeuft DTCM und ITCM 
mit 400MHz, waerend das restliche RAM nur 200 MHz kann.

von Andreas M. (amesser)


Lesenswert?

Der Vorteil der speziellen Speicherbereiche liegt nicht nur unbedingt 
darin, dass diese besonders schnell sind (also meist mit vollem CPU 
Takt) sondern dass diese über eigenständige Busse an die CPU angekoppelt 
sind. Beim ARMv5 spricht man von "Ports". Die ARM966 Cpu hat zum 
Beispiel drei Ports:

"System": Hier hängt normalerweise die ganze Peripherie, Flash und RAM 
dran

"Data": An diesen Port kann man z.B. einen TCM Speicher anschließen oder 
einen Cache (wie bei der ARM926). Theoretisch kann man den Port aber 
auch an den selben Bus wie "System" anschließen - das macht z.B. Sinn 
wenn der System-Bus als Switch und nicht als einfacher Bus ausgeführt 
ist.

"Instruction": Für diesen Port gilt das gleiche wie den Data Port, mit 
der Ausnahme das am Instruction Port nicht geschrieben werden kann (Die 
entsprechenden Signale fehlen)

Ein großer Geschwindigkeitsbonus besteht auch darin, dass alle Busse 
parallel genutzt werden können. So kann z.B. die Instruktion über den 
"I" port geladen und parallel dazu Daten über die "System" und "Data" 
Ports geladen oder gschrieben werden. Wenn alles nur über einen Port 
geht, dann müssen die einzelnen Schritte jeweils nacheinander gemacht 
werden.

Welchen der Ports die ARM benutzt, wird mittels der Zugriffsadresse 
ausgewählt. So kann es z.B. sein das man auf den selben physischen 
Speicher über verschiedene Addressbereiche zugreifen kann und je nach 
Addressbereich ein anderer Port benutzt wird. Hier kommt dann das 
Linkerscript mit ins Spiel.

von Speicherli (Gast)


Lesenswert?

UweBonnes schrieb:
> Der Sinn von ITCM ist klar. Dort kommen die schnellen Funktionen
> rein
> und man spart sich die Flash Latenz, Beim STM32H7 laeuft DTCM und ITCM
> mit 400MHz, waerend das restliche RAM nur 200 MHz kann.

Andreas M. schrieb:
> Hier kommt dann das
> Linkerscript mit ins Spiel.

Dann ist das mit dem ITCM so wie ich vermutet habe.
Effektiv nutzen, für Variablen, kann ich diesen Speicher nicht.
Was da rein geladen wird bestimmt dann zum Schluss der automatisch der 
Linker, oder?

Danke & Grüße
Jürgen

von Cyblord -. (cyblord)


Lesenswert?

Speicherli schrieb:
> Was da rein geladen wird bestimmt dann zum Schluss der automatisch der
> Linker, oder?

Nein man sagt dem Linker explizit dass er bestimmte Funktionen da rein 
packen soll.

von Andreas M. (amesser)


Lesenswert?

Genau, was reingeladen werden soll bestimmt man selbst, indem man im 
Linkerscript das ITCM als eigenständigen Speicher deklariert. z.B.
(Achtung Adressen sind hier exemplarisch muss natürlich zum 
Microcontroller passen)
1
MEMORY
2
{
3
...
4
        FLASHrwx)    : ORIGIN = 0x00000000, LENGTH = 64K
5
        ITCM(rwx)    : ORIGIN = 0x00200000, LENGTH = 8K
6
...
7
}

Da fällt mir grad auf, klar kann man ins ITCM rein schreiben, sonst 
würde das ja gar nicht funktionieren. Ich glaube beim DTCM kann man 
keinen Code ausführen, so war das wohl :-)

Jedenfalls, dann die Sektion befüllt
1
...
2
.itcm :
3
{
4
   *muldi3*(.text .rodata)
5
   *memcpy*(.text .rodata)
6
   ...
7
} >ITCM AT>FLASH
8
9
/* symbole definieren um die positionen für relokierung
10
 * zu kennen */
11
PROVIDE (itcm_start           = ADDR(.itcm));
12
PROVIDE (itcm_load_start = LOADADDR(.itcm));
13
PROVIDE (itcm_load_end   = LOADADDR(.itcm) + SIZEOF(.itcm));
14
...

Und dann Ganz wichtig, bevor irgend ein code aus dem ITCM ausgeführt 
wird,
am besten direkt im Reset Handler

1. ITCM aktivieren (falls notwendig)
2.
1
extern uint32_t itcm_start, itcm_load_start, itcm_load_end;
2
uint32_t *dst, *src;
3
4
/* Daten von Flash nach ITCM kopieren */
5
dst = &itcm_addr;
6
src = &itcm_load_start;
7
8
while(src < &itcm_load_end)
9
  *(dest++) = *(src++);

Den letzten Schritt nennt man relokieren. Das muss gemacht werden bevor 
auch nur eine Funktion aus dem ITCM genutzt wird, deswegen auch manuelle 
Umsetzung des Memcopy.

von S. R. (svenska)


Lesenswert?

Andreas M. schrieb:
> Das muss gemacht werden bevor auch nur eine Funktion aus
> dem ITCM genutzt wird, deswegen auch manuelle Umsetzung des Memcopy.

Wenn der Compiler das erkennt, darf er einen Funktionsaufruf für 
memcpy() oder memmove() erzeugen. Am besten, du erzeugst die Kopie mit 
Inline-Assembler oder verbietest explizit die entsprechende Optimierung.

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.