Guten Tag,
beschäftige mich gerade mit einem Cortex M7 und dessen L1-(Daten)-Cache
in Form eines Atmel SAM E70.
Aufgefallen ist, dass das Beispiel zur SD-Karte von Atmel zwar läuft
aber die Daten nicht korrekt auslesen kann. Problem ist nach einiger
Überlegung klar: Die Daten werden per DMA gelesen und mit zuvor
geschriebenen Daten verglichen. Nur weiß der Cache nichts vom DMA-
Controller und liefert zum Teil eben nicht die richtigen Daten. Folglich
muss der Typ vor dem Monitor ran um das gerade zu biegen, nur wie?
- DCache deaktivieren
+ funktioniert sicher, immer und überall
+ kein Aufwand, kein Wissen des Programmierers erforderlich
- unnötiger Leistungsverlust
- Cache clean und Cache invalidate Befehle
+ funktioniert auch ;-)
- muss jedes Mal explizit beachtet werden
- zusätzlicher Overhead durch invalidate/clean Operationen
- Deaktivieren des Caches für einen Speicherbereich, DMA Buffer dann in
diesen Bereich legen
+ nur einmal Aufwand, nicht bei jeder Operation
- Verwaltungsaufwand dann im Linker-Script
- Cache nicht aktiv
- (SAM E70 Spezifisch: DAM Buffer in DTCM legen, der wird nie gechacht
ist aber so schnell angebunden, dass es keine Performance-Nachteile
gibt.)
+ nur einmal Aufwand, nicht bei jeder Operation
- Verwaltungsaufwand dann im Linker-Script
Was ist die "best practice"? Oder gibts noch Alternativen?
Haltet Ihr das lieber aus der Anwendung raus und dafür im Linker-Skript
etc oder lieber explizit im Treiber?
Viele Grüße
Karl
Üblicherweise gibt es bei Controllern, bei denen solche Effekte
auftreten können, mehrere gespiegelte Adressräume mit unterschiedlichen
Eigenschaften bzgl. Caching und Reordering etc. Genau deswegen.
Google erster Treffer: https://community.st.com/thread/18611> There are some conclusions:> 1) before you send something via DMA from memory - a need to do a Cache > Clean
maintenance operation - force to let update the memory with cache > content
> 2) when something was received in memory via DMA - a need to do Cache> Invalidate maintenance operation - force to let update caches again> with memory content to see the changes
Scheinbar kann man irgendwie den Cache invalidieren.
Von der gleichen Seite:
> But, I think there is a faster (and easier way): use the DTCM memory> region:> If you manage to have the buffers for DMAs on DTCM then you should be> fine: there is not the DCACHE involved, it is tightly coupled for MCU> and DMA has dedicated path to it as well.> On this DTCM you will have 'coherency', no need to deal with cache> maintenance.> Regular memories with DCACHE 'in between' might look like 'some data> missing' (not coherent).
Hätte mich auch gewundert, wenn das ein unbekanntes Problem gewesen wäre
:-)
Mampf F. schrieb:> Scheinbar kann man irgendwie den Cache invalidieren.
Die oben gestellte Frage ist eher, ob man Probleme durch geeignete
Adressierung von vorneherein vermeiden will, indem der betreffende
Bereich nie über Cache genutzt wird. Oder ob man Cache zulassen will,
aber an jeder Stelle sorgfältig drauf achtet, dass man nicht ins
Fettnäpfchen tritt.
A. K. schrieb:> Üblicherweise gibt es bei Controllern, bei denen solche Effekte> auftreten können, mehrere gespiegelte Adressräume mit unterschiedlichen> Eigenschaften bzgl. Caching und Reordering etc. Genau deswegen.
Ja, die MPU des M7 kann das Caching-Verhalten für jede (frei
definierbare) Region getrennt regeln.
Mampf F. schrieb:> Scheinbar kann man irgendwie den Cache invalidieren.>> Hätte mich auch gewundert, wenn das ein unbekanntes Problem gewesen wäre
Will nicht undankbar erscheinen, aber hast Du meine Fragen gelesen und
verstanden? Dass es diese Möglichkeiten gibt weiß ich und googel kann
ich auch halbwegs bedienen. Mich interessiert, wie man aus den
vielfältigen Möglichkeiten die beste herauspickt bzw. welche mir noch
nicht bekannten Nebenwirkungen lauern. Die DTCM-Lösung ist z.B. im
Allgemeinen reichlich kurz gesprungen, weil es auch Implementierungen
gibt, bei denen der DMA controller keinen Zugriff auf die TCMs hat.
A. K. schrieb:> Die oben gestellte Frage ist eher, ob man Probleme durch geeignete> Adressierung von vorneherein vermeiden will, indem der betreffende> Bereich nie über Cache genutzt wird. Oder ob man Cache zulassen will,> aber an jeder Stelle sorgfältig drauf achtet, dass man nicht ins> Fettnäpfchen tritt.
Genau. Mich würde z.B. auch interessieren, ob man Cache maintainance
eher "by address" macht oder eher die way/set Register verwendet. Bei
ersteren braucht man schon etliche Operationen (immer nur 32 Bytes/ 1
Cachline pro Maintainance Operation, letztere hab ich ehrlich noch nicht
ganz kapiert. (Wie) kann man wissen welchen way und welches set man
invalidieren muss?
Karl schrieb:> DAM Buffer in DTCM legen, der wird nie gechacht> ist aber so schnell angebunden, dass es keine Performance-Nachteile> gibt.
Ah stimmt, tut mir leid ... Du hattest invalidieren und DTCM schon
erwähnt :)
Aber wenn DTCM nicht gecached wird, schnell angebunden ist und es keine
Performance Nachteile gibt, weshalb verwendest du das nicht? :)
Generell:
Caching bringt natürlich nur dann was, wenn die CPU(s) mehrfach auf die
Daten zugreifen müssen. In allen anderen Fällen ist Caching bestenfalls
nur nicht schädlich.
Mampf F. schrieb:> Aber wenn DTCM nicht gecached wird, schnell angebunden ist und es keine> Performance Nachteile gibt, weshalb verwendest du das nicht? :)
Sag ich ja nicht, dass ich das nicht tun werde ;)
Ein Nebeneffekt bei sam e70 ist, dass man RAM verschwendet wenn mann
den itcm nicht braucht.
Quarx schrieb:> Generell:> Caching bringt natürlich nur dann was, wenn die CPU(s) mehrfach auf die> Daten zugreifen müssen. In allen anderen Fällen ist Caching bestenfalls> nur nicht schädlich.
Sehe ich nicht so. Eine cache line ist 32 bytes. Es bringt immer dann
was, wenn ich in der Nähe eines Zugriffs nochmal zugreifen muss. Die
Latenzen für folgende Zugriffe sind beinahe geschenkt und können hinter
anderen Instruktionen versteckt werden.
Ich hab den Controller auch nicht gewählt weil er den M7 hat, sondern
weil er interessante Peripherie hat. Ein M3 @ 100 MHZ hätte auch
gereicht. Aber das heißt ja nicht, dass man sich nicht weiterbilden darf
und es so gut wie möglich machen will. Ich versuche auch für das nächste
Projekt zu lernen.