Forum: Mikrocontroller und Digitale Elektronik CCMRAM richtig einsetzen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von BinnenFreund (Gast)


Lesenswert?

Guten Abend,
ich spiele mit einem STM32F334. Mir ist aufgefallen das dieser µC einen 
CCMRAM hat. Leider verstehe ich nicht was ich Sinnhaftes damit machen 
kann.
Kann mir bitte jemand kurz erklären welchen Zweck dieses Ram erfühlt?
Danke für Eure Hilfe

von Walter T. (Gast)


Lesenswert?

BinnenFreund schrieb:
> Kann mir bitte jemand kurz erklären welchen Zweck dieses Ram erfühlt?

Es ist schneller als das andere SRAM angebunden.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Du kannst im CCRAM alles speichern, was nicht von DMA bedient werden 
muss.

von BinnenFreund (Gast)


Lesenswert?

Walter T. schrieb:
> BinnenFreund schrieb:
>> Kann mir bitte jemand kurz erklären welchen Zweck dieses Ram erfühlt?
>
> Es ist schneller als das andere SRAM angebunden.

Danke

Matthias S. schrieb:
> Du kannst im CCRAM alles speichern, was nicht von DMA bedient
> werden
> muss.

Und wie kann ich dem  CCMRam variablen zuweisen?
Danke für die Hilfe

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Angehängte Dateien:

Lesenswert?

BinnenFreund schrieb:
> Und wie kann ich dem  CCMRam variablen zuweisen?

Du musst dein Linkerskript leicht anpassen. Ich habe für die F3 Serie 
keines da, aber ich hänge dir mal eines für den F429ZI an, um zu zeigen 
wies gemacht wird.
Im Code kannst dann sowas schreiben:
1
char CCRAM buf[32];
2
uint32_t CCRAM maxA, maxB ;

von BinnenFreund (Gast)


Lesenswert?

Matthias S. schrieb:
> BinnenFreund schrieb:
>> Und wie kann ich dem  CCMRam variablen zuweisen?
>
> Du musst dein Linkerskript leicht anpassen. Ich habe für die F3 Serie
> keines da, aber ich hänge dir mal eines für den F429ZI an, um zu zeigen
> wies gemacht wird.
> Im Code kannst dann sowas schreiben:char CCRAM buf[32];
> uint32_t CCRAM maxA, maxB ;

Vielen Dank!
Wo finde ich das Linkerskript das ich anpassen muss?
Ich verwende das Atolic True Studio.
Sorry aber ich kenne mich nicht so gut aus!

von OMG (Gast)


Lesenswert?

BinnenFreund schrieb:
> Wo finde ich das Linkerskript das ich anpassen muss?

Im Datei-Verzeichnisbaum des Project Explorers. Was bitte hast
du bis jetzt gemacht dass du eine solche Frage stellen musst?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Das derzeitig benutzte Linkerskript findest du in den Einstellungen zum 
Projekt unter Tools->Linker-> Settings (oder so ähnlich). Kopiere dieses 
Skript und ergänze es mit den Erweiterungen zum CCMRAM. Wähle dann diese 
Kopie als neues Setting für den Linker.

von BinnenFreund (Gast)


Lesenswert?

Matthias S. schrieb:
> Das derzeitig benutzte Linkerskript findest du in den
> Einstellungen zum
> Projekt unter Tools->Linker-> Settings (oder so ähnlich). Kopiere dieses
> Skript und ergänze es mit den Erweiterungen zum CCMRAM. Wähle dann diese
> Kopie als neues Setting für den Linker.

oh danke für deine Hilfe! Werde es morgen ausprobieren!!!

von gfdgd (Gast)


Lesenswert?

im CCM sollte der Stack  sein ...
Das reduziert die zeit für den contextwechsel bei interrupts
oder bei verwendung eines RTOS
der stack aller Tasks sollte dann im CCM liegen


wenn auch ITCM RAM vorhanden ist  ist es gut  alle ISRs da reinzulegen

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

gfdgd schrieb:
> im CCM sollte der Stack  sein ...

Hey, gute Idee! Da bin ich noch gar nicht drauf gekommen :-P Logisch, 
das das was bringt. Und DMA braucht man da auch nicht...

von meckerziege (Gast)


Lesenswert?

gfdgd schrieb:
> im CCM sollte der Stack  sein ...
> Das reduziert die zeit für den contextwechsel bei interrupts
> oder bei verwendung eines RTOS
> der stack aller Tasks sollte dann im CCM liegen

Nein. Das ist falsch. Du kannst das machen, aber es bringt dir nix.
Das interne SRAM und das CCMRAM lassen sich beide ohne wait states 
ansteuern.

Du hast nur einen Vorteil wenn du Code im CCMRAM ausführst. Dadurch hast 
du zero-waitstate fetches und der Code läuft etwas schneller. Sinnvoll 
kann das z.b. bei ISR Routinen sein.

Erwarte aber keine Wunder. Das ist ein nettes Feature bringt etwas 
Performance

von m.n. (Gast)


Lesenswert?

meckerziege schrieb:
> Erwarte aber keine Wunder. Das ist ein nettes Feature bringt etwas
> Performance

Es ist schon etwas mehr als nett.
Wie der Name schon sagt, hat der Prozessor direkten Zugriff auf das RAM. 
Damit entfallen ggf. Wartezeiten über die Busmatrix und Zugriffe können 
parallel ausgeführt werden. Das trifft für den F334 zu.

Bei neueren Controllern mit AXI können auch Wartezyklen auf AXI-SRAM 
eingefügt sein. Mit CCM als Standard für den Stack und allgemeine 
Variablen liegt man sicher auf der schnelleren Seite.

von gfdgd (Gast)


Lesenswert?

richtig ..
keine wunder...

aber bei mir reicht ein M7 für MJPEG streaming inkl SW decoding für 
25fps
ohne diese features liegt die bildrate bei knappen 10fps

so gesehen ...  jedes bisschen hilft irgendwo
warum also nicht mitnehmen


hatte das auch mal gemessen.
stack im SRAM und vergleich dazu im CCM
der CCM war nicht viel  aber immer schneller

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

... vor allem ist es einfach praktisch, wenn der Stack aus dem Weg ist. 
CCMRAM ist zwar meist nicht viel da, aber ehe der brachliegt, ist der 
Stack da gut aufgehoben.
Hier noch mal ein ausführliches Topic zum CCMRAM:
https://www.openstm32.org/Using%2BCCM%2BMemory

: Bearbeitet durch User
von BinnenFreund (Gast)


Angehängte Dateien:

Lesenswert?

Guten Morgen,
ich habe mir jetzt mal das existierende Linker File angesehen.
Und darin sind bereits CCMRAM Sachen enthalten.
Reicht dies aus?
1
char CCRAM buf[32];
2
3
uint32_t CCRAM maxA, maxB ;
Wird noch nicht richtig kompiliert.
Danke für die Hilfe

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

BinnenFreund schrieb:
> Wird noch nicht richtig kompiliert.

Nee, da fehlt noch das Makro zum Umschnurzeln von
1
 __attribute__((section(".ccmram")))
in den vereinfachten Ausdruck, den ich benutze. Moment, ich suche das 
mal...
Ahh, habs gefunden - das steht bei mir in der main.h:
1
#ifndef CCRAM
2
#define CCRAM __attribute__((section(".ccmram")))
3
#endif
Sorry für das Versäumnis.

: Bearbeitet durch User
von BinnenFreund (Gast)


Lesenswert?

Matthias S. schrieb:
> Nee, da fehlt noch das Macro zum Umschnurzeln von
> __attribute__((section("ccmram")))
> in den vereinfachten Ausruck, den ich benutze. Moment ich suche das
> mal...
> Ahh, habs gefunden - das steht bei mir in der main.h:#ifndef CCRAM
> #define CCRAM __attribute__((section(".ccmram")))
> #endif
> Sorry für das Versäumnis.

Super Danke!
Kompilieren geht!
Also variablen die ich mit dem DMA nicht verwende kann ich nun in das 
CCMRam legen? Oder muss ich noch andere Sachen beachten?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

BinnenFreund schrieb:
> Oder muss ich noch andere Sachen beachten?

Eigentlich nicht. Beachte die Hinweise bei den opemstm32 Jungs, dann 
kannst du auch den Stack da rein legen. Der CCMRAM liegt eben nicht auf 
dem internen Bussystem, deswegen kann die Peripherie nicht direkt da 
reinschreiben oder -lesen (also auch der ADC). Aber sonst gibts wenig 
Beschränkung.

von Johannes S. (Gast)


Lesenswert?

BinnenFreund schrieb:
> Also variablen die ich mit dem DMA nicht verwende kann ich nun in das
> CCMRam legen? Oder muss ich noch andere Sachen beachten?

Zur Sicherheit ins Datenblatt schauen, da gibt es eine Matrix mit der 
Busübersicht.

von foobar (Gast)


Lesenswert?

> Kann mir bitte jemand kurz erklären welchen Zweck dieses Ram erfühlt?

Beim CCM geht es hauptsächlich um deterministische Laufzeiten - eine 
bestimmte Codesequenz braucht immer exakt die gleiche Anzahl Taktzyklen. 
Was bei den 8-Bittern oft selbstverständlich ist, ist bei komplexeren 
und schnelleren 32-Bittern oft schwierig zu erreichen.

Insbesondere Zugriffe aufs Flash benötigen bei höheren Taktfrequenzen 
Waitstates und werden typischerweise durch einen kleinen Cache 
beschleunigt.  Dies führt zu einem nicht-deterministischen 
Laufzeitverhalten - je nach Cache-Inhalt oder Lage des Codes im Flash 
ändert sich dessen Laufzeit (wenn's blöd läuft Faktor 2!).

Das kann man umgehen, indem man kritische Codefragmente ins RAM kopiert 
und von dort ausführt.  Das führt allerdings zum nächsten Problem: 
konkurierende Einheiten, die ebenfalls aufs RAM zugreifen wollen (z.B. 
DMA oder andere Cores), können die CPU ausbremsen und man hat wieder 
keine garantierte Laufzeit.  Die Lösung: dediziertes RAM für jeden Core. 
Das kann wie z.B. beim RP2040 mehrere, parallel ansprechbare 
Speicherbänke an der Busmatrix sein oder einfacher, ein direkt an den 
Core angebunder RAM-Block, das Core-Coupled-Memory.

Wenn man dann noch sicherstellt, dass die Datenzugriffe (inkl Stack!) 
ebenfalls nur auf dem lokalen Speicher stattfinden, hat man endlich sein 
Ziel erreicht (z.B. jitterfreies Bit-banging oder Interruptbehandlung).

von mitlesa (Gast)


Lesenswert?

foobar schrieb:
> Beim CCM geht es hauptsächlich um deterministische Laufzeiten
> .......

Das war ja mal eine schöne und erleuchtende Erklärung, Danke dafür.

von mitlesa (Gast)


Lesenswert?

Jetz wäre meine Frage was denn die Designer von STM dazu
bewegt hat ein CCM vorzusehen.

Anders herum gefragt: welche ernsthafte moderne Anwendung
für 32-Bit Controller hatten die STM-Designer im Auge
um CCM zu implementieren. Oder ist das ein Feature das
schon von ARM im Core vorgesehen ist, aber wofür?

Also für's timing-getreue synchrone Bitbanging wird man
es wohl nicht gedacht haben ....

von BinnenFreund (Gast)


Lesenswert?

Matthias S. schrieb:
> Eigentlich nicht. Beachte die Hinweise bei den opemstm32 Jungs, dann
> kannst du auch den Stack da rein legen. Der CCMRAM liegt eben nicht auf
> dem internen Bussystem, deswegen kann die Peripherie nicht direkt da
> reinschreiben oder -lesen (also auch der ADC). Aber sonst gibts wenig
> Beschränkung.

Hmm ist das Stack auslagern eine Sichere Sache? Hatte mal vor langer 
Zeit auf einem ATTiny26 das Problem das ich mir den Stack während der 
Laufzeit überschrieben habe....Das war nicht Lustig.
Wie lagert man den Stack aus?

Johannes S. schrieb:
> Zur Sicherheit ins Datenblatt schauen, da gibt es eine Matrix mit der
> Busübersicht.

Ok hast du ein Beispiel damit ich weiß nach was ich suchen soll.
Danke

foobar schrieb:
> Wenn man dann noch sicherstellt, dass die Datenzugriffe (inkl Stack!)
> ebenfalls nur auf dem lokalen Speicher stattfinden, hat man endlich sein
> Ziel erreicht (z.B. jitterfreies Bit-banging oder Interruptbehandlung).

Das klingt ja sehr gut Danke für deine Erklärung.

von foobar (Gast)


Lesenswert?

> Oder ist das ein Feature das schon von ARM im Core vorgesehen ist,
> aber wofür?

Das ist ein Design-Feature der Cortex-M-Familie, eine extra für 
Steuerungsaufgaben optimierte Version ihrer CPUs und da möchte man schon 
definierte, jitterfreie Laufzeiten haben (sonst fängt der Motor an zu 
brummen, der DC/DC-Wandler erzeugt Rauschen, der externe ADC verpasst 
Samples, das Bild wackelt, etc).  Klar, man versucht so weit wie möglich 
die dedizierten HW-Blöcke zu verwenden, aber häufig genug passen die 
nicht (insb Interfaces zu Custom-HW, FPGAs etc).  Einige Hersteller 
gehen so weit, selbst die GPIO-Ports direkt an die Cores zu hängen (die 
hängen normalerweise asynchron an der Bus-Matrix) um Jitter weiter zu 
minimieren.

von Johannes S. (Gast)


Lesenswert?

BinnenFreund schrieb:
> Ok hast du ein Beispiel damit ich weiß nach was ich suchen soll.
> Danke

genauer im Reference Manual, bei ST sind die Beschreibungen ja auf 
Datasheet / RefMan aufgeteilt: RM0364, Kapitel 2, da ist gleich die 
Übersicht.
https://www.st.com/resource/en/reference_manual/rm0364-stm32f334xx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
Wie hier schon geschrieben wurde ist es bei anderen STM Serien noch 
aufwändiger, da gilt es nicht pauschal 'mit CCM geht kein DMA'.

von mitlesa (Gast)


Lesenswert?

foobar schrieb:
> (die hängen normalerweise asynchron an der Bus-Matrix)
... war mir klar.

foobar schrieb:
> Einige Hersteller
> gehen so weit, selbst die GPIO-Ports direkt an die Cores zu hängen (die
> hängen normalerweise asynchron an der Bus-Matrix) um Jitter weiter zu
> minimieren.

Das hätte ich jetzt nicht erwartet ... kannst du mir Beispiele von
Controllern nennen bei denen die Direktkopplung vom Core zum GPIO
realisiert ist? Ich dachte immer das macht kein Schwein ...

von foobar (Gast)


Lesenswert?

Ergänzung: wenn ich von deterministischen Laufzeiten spreche geht es 
nicht nur im einen Takt plus/minus.  Wenn mein Sinus/FFT/Filter nicht 
1000 Taktzyklen sondern durch einen DMA plötzlich 1200 Zyklen braucht, 
kann mir das u.U. den gesamten Programmablauf durcheinander werfen.

von mitlesa (Gast)


Lesenswert?

BinnenFreund schrieb:
> Kompilieren geht!
> Also variablen die ich mit dem DMA nicht verwende kann ich nun in das
> CCMRam legen? Oder muss ich noch andere Sachen beachten?

Es könnte sein dass - ja nach IDE oder sonstigem Environment -
der Startup-Code nicht die Initialisierung von Variablen
die im CCM angelegt sind, mit erledigt. Vielleicht muss man
da seine eigene Kreation einbringen, oder im eigentlichen
C-Code nach dem Startup sicherstellen dass diese Variablen
initialisiert werden.

von m.n. (Gast)


Lesenswert?

foobar schrieb:
> (sonst fängt der Motor an zu
> brummen, der DC/DC-Wandler erzeugt Rauschen, der externe ADC verpasst
> Samples, das Bild wackelt, etc).

Hauptsächlich ging es wohl darum, bei Audioanwendungen einen räumlichen 
Klang zu erzielen.

mitlesa schrieb:
> Es könnte sein dass - ja nach IDE oder sonstigem Environment -
> der Startup-Code nicht die Initialisierung von Variablen
> die im CCM angelegt sind, mit erledigt.

Das ist ja eine üble Falle.

Kinders, heute ist Sonntag und nicht Freitag. Bleibt mal auf dem Teppich 
statt hier rumzuspinnen.
Wenn Euch schnelle Controller überfordern, bleibt bei den AVRs!

von BinnenFreund (Gast)


Lesenswert?

m.n. schrieb:
> Kinders, heute ist Sonntag und nicht Freitag. Bleibt mal auf dem Teppich
> statt hier rumzuspinnen.
> Wenn Euch schnelle Controller überfordern, bleibt bei den AVRs!

Ich versuche was zu lernen ;-)

von mitlesa (Gast)


Lesenswert?

m.n. schrieb:
> Kinders, heute ist Sonntag und nicht Freitag.

Wie soll man denn das verstehen?

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

mitlesa schrieb:
> Wie soll man denn das verstehen?

Er ist einfach nur ein Troll, einfach ignorieren.

von foobar (Gast)


Lesenswert?

> kannst du mir Beispiele von Controllern nennen bei denen die
> Direktkopplung vom Core zum GPIO realisiert ist? Ich dachte
> immer das macht kein Schwein ...

Bei den Cortex-M0 verbreitet, nennt sich Cortex-M0+ single-cycle IOBUS. 
Beispielsweise SAMD11, LPC83, RP2040, ...

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

BinnenFreund schrieb:
> Hmm ist das Stack auslagern eine Sichere Sache? Hatte mal vor langer
> Zeit auf einem ATTiny26 das Problem das ich mir den Stack während der
> Laufzeit überschrieben habe....Das war nicht Lustig.

Hahaha, das ist ein STM32, kein Tiny26. Wer sich das Linkerskript mal 
anguckt, sieht schnell, das 64kByte mehr als genug für Stack und 
reichlich Variable sind:
1
/* Highest address of the user mode stack */
2
_estack = 0x10010000;    /* end of CCM RAM */
3
4
/* Generate a link error if heap and stack don't fit into RAM */
5
_Min_Heap_Size = 0x400;      /* required amount of heap  */
6
_Min_Stack_Size = 0x800; /* required amount of stack */
7
8
 /* User_heap_stack section, used to check that there is enough RAM left */
9
  ._user_heap_stack :
10
  {
11
    . = ALIGN(4);
12
    PROVIDE ( end = . );
13
    PROVIDE ( _end = . );
14
    . = . + _Min_Heap_Size;
15
    . = . + _Min_Stack_Size;
16
    . = ALIGN(4);
17
  } >CCMRAM
Ich habe gestern mal eins meiner komplexeren Programme so kompiliert. 
Keine Probleme soweit.

von m.n. (Gast)


Lesenswert?

mitlesa schrieb:
> m.n. schrieb:
>> Kinders, heute ist Sonntag und nicht Freitag.
>
> Wie soll man denn das verstehen?

Daß hier herumgesponnen wird, um dem CCM "alternative Wahrheiten" 
anzudichten.
Wenn bei einer Anwendung der Motor brummt oder rauscht, dann liegt das 
nicht am RAM-Zugriff sondern u.U. an der falschen Timerprogrammierung.
Welche RAM-Bereiche initialisiert werden oder nicht, liegt am 
startup-Code. Die Initialisierung ist alleinige Sache des Programmieres 
und hat absolut garnichts mit CCM zu tun.

Mw E. schrieb:
> mitlesa schrieb:
>> Wie soll man denn das verstehen?
>
> Er ist einfach nur ein Troll, einfach ignorieren.

Warum soll "mitlesa" ein Troll sein?

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Angehängte Dateien:

Lesenswert?

Hier ist die Matrix der Busübersicht "Figure 1".
Der CCM RAM kann nur vom Prozessor aus angesteuert werden, nicht vom 
DMA.
Damit kann der DMA zeitgleich auf den SRAM die Daten kopieren und der 
Prozessor im CCM RAM zugreifen.
Zudem ist der CCM RAM auch vor falsches Überschreiben aus der DMA 
geschützt, da der da einfach nicht hin kommt.
Schlussendlich macht es Sinn alle Variablen und den Stack in den CCM RAM 
zu legen, vor allem wenn man den DMA nutzt. Damit hat man auch mehr 
Platz für den DMA Speicher.
Man kann das Linkerscript auch so aufbauen, dass per Default alle 
Variablen im CCM RAM landen und nicht im SRAM.

: Bearbeitet durch User
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.