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
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.
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.
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
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.