Forum: Mikrocontroller und Digitale Elektronik STM32F4 Bitbanding-Problem


von Rangi J. (rangi)


Lesenswert?

Hallo Forum,
gleich noch ein Bug im STM32F4xx, vermutlich auch im F2 und F1 !
Ich habe zum bitweisen Zugriff auf verschiedene Register Makros gebaut, 
welche die Bitbanding Adressen berechnen. Damit lassen sich Bits lesen 
und auch schreiben.
Folgender Fehler tritt dabei auf: Ich habe verschiedene EXTI-Interrupts 
aktiviert. In der ISR bei EXTI15-10 oder EXTI5-9 muss logischerweise 
abgefragt werden, welcher Pin es nun war. Dazu ist das EXTI_PR da. Um 
den Interrupt zu quittieren schreibt man einfach eine 1. "This bit is 
set when the selected edge event arrives on the external interrupt line. 
This bit is
cleared by writing a 1 to the bit". Dazu habe ich Bitbanding verwendet. 
Treten nun gleichzeitigen zwei Unterschiedliche EXTIs auf, werden die 
ISR auch in der Priorität aufgerufen. Jedoch wird das EXTI_PR durch den 
Schreibzugriff ersten scheinbar komplett gelöscht. In der 2. ISR ist 
dann kein Bit mehr gesetzt und es kann nicht ausgewertet werden, welcher 
5..9 oder 10..15 es war.
Ohne Bitbanding, EXTI_PR=(1<<10); , funktioniert alles bestens.

MfG
Rangi

von Steel (Gast)


Lesenswert?

glaube ich nicht, zeig doch mal deine Makros, schätze mal, mit denen 
stimmt was nicht.

von Rangi J. (rangi)


Lesenswert?

Hm, was soll mit denen nicht stimmen? Im allgemeinen funktioniert ja 
alles, ist ja nicht so, das garnichts funktionieren würde.
z.B. das EXTI_PR, Bit 10
1
#define STM32_EXTI_PR_PR10   (*(volatile u32 *) (PERIPH_BB_BASE | (((u32)(&STM32_EXTI->PR) - PERIPH_BASE) << 5) | ((10) << 2)))
Nach meiner Rechnung kommt da raus:
0x422782A8 = 0x42000000 | (0x00013C14 * 0x20) | (0xA * 4 )

richtig?

von A. B. (funky)


Lesenswert?

äh ich kann deine ausgerechnetes makro da zwar nicht nachvollziehen, da 
ich zu faul bin die speicheradressen nachzuvollziehen, aber müsste es 
nicht:

EXTI_PR |= (1<<10)

anstatt

EXTI_PR = (1<<10)

heissen? Auch wenn du sagst es würde so funktionieren. Aber letztendlich 
willst du ja nur ein Bit manipulieren und nicht alle.

von (prx) A. K. (prx)


Lesenswert?

Rangi Jones schrieb:
> gleich noch ein Bug im STM32F4xx, vermutlich auch im F2 und F1 !

Der Bug sitzt hier vor der Tastatur.

Bitbanding arbeitet auf Ebene der Buszyklen genauso mit 
read-modify-write, wie C das auch ohne Bitbanding tun würde. Nur eben 
atomar, als Teil der Schreiboperation.

Mit Bitbanding wird also bei den nicht adressierten Bits das zurück 
geschrieben, was vorher drin stand. Somit werden alle gesetzten Bits 
zurück gesetzt.

Um in EXTI_PR etwas zurückzusetzen darf man kein Bitbanding einsetzen, 
sondern schreibt in das gewünschte Bit eine 1 und in alle anderen Bits 
eine 0.

> Ohne Bitbanding, EXTI_PR=(1<<10); , funktioniert alles bestens.

Eben. So ist das auch gedacht. Bitbanding ist hier nicht nur 
überflüssig, sondern dafür nicht einsetzbar. Kein Bug, sondern by 
design.

Bitbanding ist im Grunde wie EXTI_PR|=(1<<10) und genau das geht bei 
diesem Register in die Hose.

von Rangi J. (rangi)


Lesenswert?

A. K. du hast recht, ich habs auch gefunden in der Doku:
"For writes, it converts the write to an atomic read-modify-write 
operation."
Mist, da wird einem vorgegaukelt, dass man ein Bit setzen oder löschen 
kann ohne die anderen Bits zu beeinflussen, aber das ist halt nicht so.
Also muss man ganz genau aufpassen, wo und wie man die Bit-Banding 
Funktion einsetzt oder nicht.

Danke

von Uwe Bonnes (Gast)


Lesenswert?

Natuerlich kannst Du mit Bitbanding genau ein Bit setzen oder loeschen.

Wie nutzt Du denn Dein Macro? Es sollte mit
 STM32_EXTI_PR_PR10 = 1
das Bit setzten und mit
  STM32_EXTI_PR_PR10 = 0
das Bit loeschen. Es kommt auf das Bit 0 an, dass man schreibt.

Tschuess

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.