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
BinnenFreund schrieb: > Kann mir bitte jemand kurz erklären welchen Zweck dieses Ram erfühlt? Es ist schneller als das andere SRAM angebunden.
Du kannst im CCRAM alles speichern, was nicht von DMA bedient werden muss.
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
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 ; |
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!
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?
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.
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!!!
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
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...
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
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.
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
... 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
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
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
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?
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.
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.
> 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).
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.
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 ....
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.
> 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.
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'.
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 ...
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.
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.
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!
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 ;-)
mitlesa schrieb: > Wie soll man denn das verstehen? Er ist einfach nur ein Troll, einfach ignorieren.
> 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, ...
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.
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.