Forum: Mikrocontroller und Digitale Elektronik STM32: Interrupt zu langsam


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 lars (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich entwickle ein Projekt auf einem Nucleo STM32F722 und möchte auf eine 
fallende Flanke an einem bestimmten Eingangspin reagieren. Dazu habe ich 
einen Interrupt und einen Handler angelegt.
1
static void MX_GPIO_Init(void)
2
{
3
  // ...
4
  GPIO_InitStruct.Pin = GPIO_PIN_1;
5
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
6
  GPIO_InitStruct.Pull = GPIO_NOPULL;
7
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
8
}
9
10
void EXTI1_IRQHandler(void)
11
{
12
  __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);
13
14
  // check something (required)
15
  if ((GPIOA->IDR & 0x00f0) != 0x0070)
16
    return;
17
18
  // signal start of handler (for scope)
19
  GPIOE->BSRR = 0x0001;
20
21
  // ...
22
}

Der STM32F722 läuft mit 128 MHz (siehe Clock Config im Anhang).

Im Oszilloskop sieht man, daß zwischen Flanke und ausgelöstem Signal 0,7 
us vergehen. Das halte ich für viel zu lang - da wäre Pollen ja 
schneller.

Gibt es eine Möglichkeit, den Handler zu beschleunigen? Bspw. spart die 
Verwendung von BSRR gegenüber HAL_GPIO_WritePin 0,2-0,3 us ein.

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
lars schrieb:
> Bspw. spart die Verwendung von BSRR gegenüber HAL_GPIO_WritePin 0,2-0,3
> us ein.

Wie siehts mit der Ersetzung von
1
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);

aus?

von (prx) A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
lars schrieb:
> Bspw. spart die
> Verwendung von BSRR gegenüber HAL_GPIO_WritePin 0,2-0,3 us ein.

Man kann lange drüber streiten, ob so ein HAL im Normalfall den Job 
vereinfacht oder nicht. Aber in zeitkritischem Code hat sowas nichts 
verloren, wenn es nicht bloss Makros sind, aus denen am Ende der gleiche 
Code rauskommt.

: Bearbeitet durch User
von disasm (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Zeig doch mal den die relevante Ausgaben von objdump..

von lars (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Das __HAL_GPIO_EXTI_CLEAR_IT ist nur ein Makro für (EXTI->PR = 
(_EXTI_LINE_)), also wohl schnell.

Das die HAL langsam ist, ist mir klar, darum verwende ich sie ja auch 
nicht im Handler. Dennoch ist der Interrupt zu langsam.

Welche Ausgaben von objdump sind denn relevant? Oder willst Du letztlich 
den generierten Assembler-Code?

Ist die Clock Config denn korrekt, oder benötigt APB1 einen höheren 
Takt?

von Olli (Gast)


Bewertung
0 lesenswert
nicht lesenswert
lars schrieb:
> Der STM32F722 läuft mit 128 MHz (siehe Clock Config im Anhang).
>
> Im Oszilloskop sieht man, daß zwischen Flanke und ausgelöstem Signal 0,7
> us vergehen. Das halte ich für viel zu lang - da wäre Pollen ja
Das wären ca. 90 Takte. An welchem APB hängt der GPIO?
Die APB können m.E. nicht mit dem Core-Takt laufen. ich weiß aber auch 
nicht über welchen Weg der Interrupt gemeldet wird.

von (prx) A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
lars schrieb:
> Welche Ausgaben von objdump sind denn relevant? Oder willst Du letztlich
> den generierten Assembler-Code?

Es geht um den Code des Handlers, zumindest bis zum Messpunkt.

> Ist die Clock Config denn korrekt,

Messen?

: Bearbeitet durch User
von Andreas M. (amesser)


Bewertung
0 lesenswert
nicht lesenswert
- Laut STM erreicht man die 12 Zyklen ISR Latenz nur dann wenn man ITCM 
und DTCM benutzt.
- Gemischte Zugriffe auf Device Memory (also auf Peripherien) können 
extrem teuer werden, weil der vorherige Zugriff zuerst ausgeführt werden 
muss bevor der nächste Zugriff gemacht werden kann, da die CPU 
Seiteneffekte nicht kennt. Hier bringt dich die längere Pipeline um 
deine Takte. Du machst WRITE, READ, WRITE. Ich vermute es wäre besser 
wenn du zuerst GPIOA->IDR in eine lokale variable liest, dann den 
Interrupt bestätigst, dann die if prüfung mit der variable und dann den 
write auf die GPIO. (READ, WRITE, WRITE). Man kann da wohl mit der MPU 
was machen.
- Sind Caches aktiviert?

von lars (Gast)


Bewertung
0 lesenswert
nicht lesenswert
*TCM ist ein sehr guter Hinweis, sonst laufe ich ja mit 4 Wait States 
(wobei 120 MHz geschickter als 128 MHz wären).

Deine Hinweise bzgl. GPIO-Zugriff sind auch sehr praktisch.

Aber selbst im optimalen Fall halte ich 12 Zyklen (das sind ca. 94 ns) 
für mich für etwas zu viel. Mit Polling
1
while (GPIOE->IDR & 0x0002);

schaffe ich das geschätzt in 3-4 Zyklen (und PE1 bleibt hinreichend 
lange aktiv).

von Jim M. (turboj)


Bewertung
0 lesenswert
nicht lesenswert
lars schrieb:
> Mit Polling
> while (GPIOE->IDR & 0x0002);
>
> schaffe ich das geschätzt in 3-4 Zyklen (und PE1 bleibt hinreichend
> lange aktiv).

Aber nur wenn keine Interrupts auftreten. Und wenn der externe Trigger 
ausbleibt, dann hängt das Programm an der Stelle fest.

Das gehört für mich in die Kategorie: "Spätere Kundenwünsche werden von 
der Rechtsabteilung bearbeitet." SCNR ;-)


Welches Problem wolltest Du eigentlich lösen? Eventuell sind 
Capture-Timer oder getriggertes DMA eine bessere Variante. Bei komplexen 
µC lagert man (echt-)zeitkritisches lieber an spezialisierte Hardware 
aus.

von lars (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Jim M. schrieb:
> Aber nur wenn keine Interrupts auftreten. Und wenn der externe Trigger
> ausbleibt, dann hängt das Programm an der Stelle fest.

Das wäre in meinem Fall OK, da das Programm sonst nichts zu tun hat.

> Welches Problem wolltest Du eigentlich lösen?

Ich möchte (zumindest experimentell) einen ca. 2 MHz Bus bedienen, also 
für bestimmte Adressen einen berechneten Wert zurückliefern. Der Read 
Enable löst den Interrupt aus, dann muß ich aber noch auf die Adresse 
prüfen.

Natürlich bietet sich dafür ein FPGA an, ich will aber schauen, ob ein 
STM32 auch dafür geeignet ist. Ein F1/F2 wäre eigentlich ausreichend, 
aber ich benötige den FMC des F7.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Bewertung
0 lesenswert
nicht lesenswert
Hast Du Dir den FMC angeschaut?

von lars (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Uwe B. schrieb:
> Hast Du Dir den FMC angeschaut?

Nur grob bisher, wieso?

von Olli (Gast)


Bewertung
0 lesenswert
nicht lesenswert
lars schrieb:
> Ich möchte (zumindest experimentell) einen ca. 2 MHz Bus bedienen, also
> für bestimmte Adressen einen berechneten Wert zurückliefern. Der Read
> Enable löst den Interrupt aus, dann muß ich aber noch auf die Adresse
> prüfen.
Das wollte ich auch schonmal machen (Z80-Bus). Ich habe mich dann damit 
begnügt einen Bussniffer zu haben, der blockweise scannt und das 
Ergebnis auf dem Display darstellt.
Möglicherweise wäre was gegangen, wenn mit /WAIT arbeitet.
Hier scheint der FPGA-Einsatz gerechtfertigt.
Ein Controller mit integrierter parametrierbarer PIO wäre was...

von (prx) A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
lars schrieb:
> Ich möchte (zumindest experimentell) einen ca. 2 MHz Bus bedienen, also
> für bestimmte Adressen einen berechneten Wert zurückliefern. Der Read
> Enable löst den Interrupt aus, dann muß ich aber noch auf die Adresse
> prüfen.

Da wär ausnahmsweise ein oller ARM7/ARM9 im Verteil (oder ganz andere 
Architekturen). Die Cortex-M haben zwar eine deutliche Optimierung bei 
Interrupts vorzuweisen, aber gegen den separaten halben Registersatz der 
FastIRQs der klassischen ARMs sind sie chancenlos.

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.