Forum: Mikrocontroller und Digitale Elektronik STM32 Probleme durch Flash-Latency?


von STM32-Programmierer (Gast)


Lesenswert?

Hallo zusammen,
ich betreibe einen STM32F446 bei 180 MHz und hab die Flash-Latency auf 5 
laut Reference-Manual gestellt.

Ich hatte folgendes Problem:
Ich hatte eine Code-Sektion in der ein IRQ deaktiviert sein musste um 
Anomalien zu vermeiden. Während dieser Code ausgeführt wurde, ist ein 
IRQ-Event aufgetreten, also nach enable des entsprechenden IRQs ist 
dieser sofort nach Aktivierung in die entsprechende IRQ gesprungen 
(siehe Pseudo-Code).
In der IRQ wurde das IRQ-enable-Bit deaktiviert (wird durch eine 
Variablen-Abfrage nur einmal ausgeführt und kann danach nicht mehr 
wiederholt deaktiviert werden).

Falls ich nun im normalen Programmablauf direkt nach der 
IRQ-Aktivierung-Befehlszeile eine Zeile eingefügt habe, in welcher auf 
dasselbe Register zugegriffen wird, wurde der IRQ einfach wieder 
aktiviert (scheinbar wurde einfach der alte Registerwert vorher vom 
Prefetch-Controller gesichert und hergenommen) und der IRQ in einer 
Dauerschleife ausgeführt:

1
Regulärer Programmablauf:
2
3
irgendein Code;
4
Register = enable-IRQ;
5
              <----------|
6
Register = enable-IRQ;   |
7
                         |
8
                         |
9
                hier tritt IRQ auf

Fehlt die zweite Zeile mit enable-IRQ funktioniert alles ohne Probleme.
Hattet ihr schonmal ähnliche Probleme?

von STM32-Programmierer (Gast)


Lesenswert?

Noch eine Ergänzung...
Es ist egal was man bei der zweiten Registeroperation macht.
Mit "Register" ist hier das selbe Register gemeint.
1
Regulärer Programmablauf in welcher IRQ-Event auftritt;
2
3
Register = enable-IRQ;
4
              <---------------|
5
Register = Registerzugriff;   |
6
                              |
7
                              |
8
                    hier tritt IRQ auf

von Jim M. (turboj)


Lesenswert?

STM32-Programmierer schrieb im Beitrag #4874079:
> dasselbe Register zugegriffen wird, wurde der IRQ einfach wieder
> aktiviert (scheinbar wurde einfach der alte Registerwert vorher vom
> Prefetch-Controller gesichert und hergenommen) und der IRQ in einer
> Dauerschleife ausgeführt:

Klingt komisch. Zeig mal den Source Code, und eventuell auch den 
Assembler der vom Compiler erzeugt wurde.

Normales Read-Modify-Write hat genau Deine beobachteten Probleme,
eventuell können LDREX/STREX oder Bitband Zugriffe das auflösen.

Falls die Latenz nicht zu wichtig ist, könnte man auch einfach ein paar 
Takte lang die Interrupts global sperren.

von Jim M. (turboj)


Lesenswert?

Übrigens haben die meisten Cortex M genaus aus diesem Grund immer 
Bitsetz- und Bitlöschregister. Damit tritt das Problem so wie ich es 
verstanden habe nicht auf.

von Tassilo H. (tassilo_h)


Lesenswert?

Keine Ahnung ob das hier der Fall ist (zu viel Beschreibung von 
Pseudocode statt echtem Code!), aber:
Wenn der Interrupt von irgendeiner Peripherie ausgelöst wird, ist darauf 
zu achten, daß der entsprechende Interrupt-Request nicht gerade als 
allerletztes vor dem Return aus der Interruptroutine zurückgesetzt wird!
Wegen des geringeren Taktes der Peripherie ist das nämlich nach dem 
Rücksprung evtl. noch gar nicht wirksam, so daß derselbe Interrupt 
nochmal ausgelöst wird.

von STM32-Programmierer (Gast)


Lesenswert?

Hallo zusammen,

erstmal Danke für die Antworten!
Hab das Problem inzwischen entdeckt...
Es war in der Tat ein Read-Modify-Write-Problem.
Dieses wird leider nicht atomar ausgeführt (waren 5 Assembler-Befehle) 
und es kam zu den oben genannten Problemen.

von Uwe Bonnes (Gast)


Lesenswert?

Interrupts beim Cortex global zu sperren ist sofort wirksam. Interrupts 
über die Enablefunktion der Perpherie zu sperren braucht ein besonders 
Vorgehen, da im NCVIC der Interrupt schon gesetzt sein kann. Wie man da 
richtig vorgeht,  musst Du nachlesen....

von Ruediger A. (Firma: keine) (rac)


Lesenswert?

STM32-Programmierer schrieb im Beitrag #4881532:
> Hallo zusammen,
>
> erstmal Danke für die Antworten!
> Hab das Problem inzwischen entdeckt...
> Es war in der Tat ein Read-Modify-Write-Problem.
> Dieses wird leider nicht atomar ausgeführt (waren 5 Assembler-Befehle)
> und es kam zu den oben genannten Problemen.

Zwei mögliche Lösungsansätze:

1. Wenn es bei dem R-M-W Problem darum geht, dass verschiedene bits in 
demselben byte durch Racekonditionen nicht synchron gehalten werden, 
hilft bit banding (da kannst Du atomar Operationen auf einzelnen bits 
ausführen, ohne die Anderen Bits im selben byte mit zu beeinträchtigen).

2. Möglicherweise kommst du mit einer ISB weiter (wenn ein 
Interruptrequest bereits einen prefetch cycle in die Pipeline abgelegt 
hat, bevor das Unterdrücken gesetzt worden ist).

Details findest Du in Kapiteln 2 bzw. 6 meines Buches, oder natürlich 
direkt in der ARM Doku.

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.