Forum: Mikrocontroller und Digitale Elektronik Interrupt Handler definieren bei STM32


von Neu bei ST (Gast)


Lesenswert?

Hi,

ich bin derzeit bemüht von dem geschlosenen PIC System Microchips auf 
die STM32 Reihe von ST umzusteigen. Dazu verwende ich das bekannte und 
sehr günstige BluePill Board (mit echtem STM32 :) ). Was mir allerdings 
noch nicht so ganz klar ist ist, wie ich die ISR definieren kann.
Bei PICs verwendet man ja einfach die Syntax:

void interrupt ISR(void){}

,bzw den entsprechenden Namen des Vektors im Funktionskopf. Wie genau 
das bei den STM32 funktioniert ist mir trotz Recherche noch nicht so 
ganz klar, würde es funktionieren wenn ich z.B. die ISR eines Timers so 
definiere:

void TIM2_IRQHandle(void){} ?

Und wenn nein, wie dann? Bzw. wenn ja was, was gehört noch dazu? Ausser 
dem zurück setzen der Flag? ST bietet einem in dieser Hinsicht doch 
deutlich mehr Möglichkeiten als PIC es tut.

MfG

von Jim M. (turboj)


Lesenswert?

Bei ARM Cortex-M werden die Interrupt Handler wie ganz normale 
Funktionen behandelt und also auch über den Funktionsnamen aufgerufen. 
Genauer: Der Linker löst den Funktionsnamen auf und packt die Adresse in 
die Vektor Tabelle rein.

Kann man sich im "Startup Code" anschauen, der ist meistens in 
Assembler.

von Unverbesserlicher Coronaleugner (Gast)


Lesenswert?

Z.B:
1
void TIM2_IRQHandler() {
2
  TIM2->SR &= ~TIM_SR_UIF;
3
}

Das Flag muss manuell zurückgesetzt werden. Das steht im Reference 
Manual.

Die Vectoren stehen bei mir im .s File, das ST mir generiert hat, unter 
"g_pfnVectors:", z.B. "startup_stm32f302cbtx.s".

von Neu bei ST (Gast)


Lesenswert?

Unverbesserlicher Coronaleugner schrieb:
> Die Vectoren stehen bei mir im .s File, das ST mir generiert hat, unter
> "g_pfnVectors:", z.B. "startup_stm32f302cbtx.s".

Ach da stehen die also. Ich hab mich schon dumm gesucht...
Verwendet man die HALs bei PIC wird ein separater .c file mit 
"Interrupt" erstellt.
Allerdings bin ich jetzt bereits von den ST µC überzeugt.

Danke für die Hilfe :)

von Unverbesserlicher Coronaleugner (Gast)


Lesenswert?

Wie gesagt musst du drauf achten, dass
a) Manche Interrupts den selben Vector benutzen
b) manche Iinterrupts-Flags manuel zurück gesetzt werden müssen.

von Johannes S. (Gast)


Lesenswert?

und das extern "C" nicht vergessen wenn man die ISR in C++ Quellen 
verwendet.

von John Doe (Gast)


Lesenswert?

Unverbesserlicher Coronaleugner schrieb:
> Wie gesagt musst du drauf achten, dass
> a) Manche Interrupts den selben Vector benutzen
> b) manche Iinterrupts-Flags manuel zurück gesetzt werden müssen.

Du meinst: Man sollte das Ref-Manual (und Programming Manual) lesen.
Eigentlich selbstverständlich, oder?

von Max Mustermann (Gast)


Lesenswert?

John Doe schrieb:
> Du meinst: Man sollte das Ref-Manual (und Programming Manual) lesen.
> Eigentlich selbstverständlich, oder?

Genau. Warum ne einfache Frage stellen wenn man auch zig Seiten 
unübersichtlich geschriebenes Ref- Manual lesen kann. Du bist 
wahrscheinlich Rentner und hast sonst nichts besseres zu tun, oder?
Warum überhaupt noch was fragen, steht doch eh "alles" irgendwie 
irgendwo drin.

Dein Kommentar -> sinnbefreit.
Die Lebenszeit dafür hättest du dir sparen können.

von Max Mustermann (Gast)


Lesenswert?

Eigentlich selbstverständlich, oder?

von John Doe (Gast)


Lesenswert?

Max Mustermann schrieb:
> Du bist wahrscheinlich Rentner und hast sonst nichts besseres zu tun, oder?

Die Tatsache, dass Du völlig unanagemessen persönlich ausfällig wirst, 
zeigt, dass ich ins Schwarz getroffen habe.

Aber wenn Du schon der Meinung bist, dass man sich das Lesen der Manuals 
schenken soll, dann schreib doch bitte, welche Interrupts des STM32F103 
vom Bluepill Board sich den Interrupt Vector teilen. Denn mit so einer 
allgemeinen Aussage ("a) Manche Interrupts den selben Vector benutzen") 
muss man ja doch wieder das Manual lesen.

von Max Mustermann (Gast)


Lesenswert?

Ich habe nichts per se gegen das Lesen des Manuals und meine Frage bezog 
sich auch nicht auf einen speziellen Vector. Es war eine allgemeine 
Frage, wie die ISR bei STM32 Controllern aussehen bzw. definiert werden.

Zu meiner Reaktion:
Was erwartest du denn, wenn du hier passiv aggressiv deinen Senf abgibst 
ohne auch nur ein Fünkchen zur Frage bei zu steuern ?
Das du dafür noch nen Orden bekommst oder was ?

Nochmal:
Spar dir deine Lebenszeit und lass es einfach. So wie ich mir Lebenszeit 
dadurch gespart habe, einfach Mal freundlich nach zu fragen als 
stundenlang ein zig Seiten langes Manual für eine allgemeine Frage zu 
wälzen.

von John Doe (Gast)


Lesenswert?

Max Mustermann schrieb:
> Ich habe nichts per se gegen das Lesen des Manuals und meine Frage bezog
> sich auch nicht auf einen speziellen Vector. Neu bei ST Es war eine allgemeine
> Frage, wie die ISR bei STM32 Controllern aussehen bzw. definiert werden.

OK, also gibt es keinen geteilten und Du wolltest Neu bei ST nur 
irritieren.

> Zu meiner Reaktion:
> Was erwartest du denn, wenn du hier passiv aggressiv deinen Senf abgibst
> ohne auch nur ein Fünkchen zur Frage bei zu steuern ?
> Das du dafür noch nen Orden bekommst oder was ?

Du solltest richtig lesen. Wo war ich hier passiv aggressiv?
Im Übrigen ist das Ref-Manual nicht unübersichtlich. Im Kapitel 
"Interrupts und events" steht die Vector-Tabelle schön übersichtlich 
drin. Hat man nach spätestens 5 Sekunden Lebenszeit gefunden. Schneller 
als ein Post hier im Forum.
Hättest Du da mal reingeschaut, wüsstest Du das.

> Nochmal:
> Spar dir deine Lebenszeit und lass es einfach. So wie ich mir Lebenszeit
> dadurch gespart habe, einfach Mal freundlich nach zu fragen als
> stundenlang ein zig Seiten langes Manual für eine allgemeine Frage zu
> wälzen.

Wenn man nicht weiss, wie man ein Manual liest, sollte man besser an 
seiner Lesekompetenz arbeiten. Man muss - wie oben bereits dargestellt - 
nicht stundenlang lesen, um an die Informationen zu kommen.

von Stefan F. (Gast)


Lesenswert?

John Doe schrieb:
> Wenn man nicht weiss, wie man ein Manual liest, sollte man besser an
> seiner Lesekompetenz arbeiten.

Leute, haltet mal den Ball flach.

Die minimalen Informationen die man für das Arbeiten mit diesem 
Mikrocontroller benötigt, sind über mehr als 1000 Seiten verteilt. Viele 
Funktionen hängen von anderen ab, die hunderte Seiten entfernt 
beschrieben sind. Und selbst diese Zusammenhänge stehen oft nicht klar 
im Text. Man muss schon eine gewisse Erfahrung mit STM32 und deren 
Dokumentation haben, um damit ohne Hilfe klar zu kommen.

Wenn das Referenzhandbuch+Datenblatt so schön strukturiert und 
ausführlich geschrieben wäre wie beim ATmega328, dann wäre es bestimmt 
2000 Seiten groß.

Gerade diese Sache, wann man genau welches Flag in einer ISR 
zurücksetzen muss ist alles andere als trivial. Manche Flags muss man 
ganz am Anfang zurück setzen. Andere wiederum darf man nicht so schnell 
zurück setzen. Dann gibt es wiederum welche, bei denen ganz am Ende zu 
späte wäre.

Dass man in der ISR überhaupt Flags zurück setzen muss, das ist für 
Leute die vorher mit AVR gearbeitet haben, alles andere als 
selbstverständlich. Alle schrieben immer, dass die STM32 Controller so 
super schnell sein würden. Aber wenn ich STM32 und AVR bei gleicher 
Taktfrequenz miteinander vergleiche, dann sind die AVR Programme fast 
immer deutlich kompakter und schneller. Nicht nur im Maschinencode, 
sondern auch im C Quelltext.

Das Einzige, was ich bei STM32 sehr angenehm finde ist, dass er 32bit 
Integer praktisch genau so effizient verarbeiten kann, wie kleinere 
Formate.

von W.S. (Gast)


Lesenswert?

Neu bei ST schrieb:
> Was mir allerdings
> noch nicht so ganz klar ist ist, wie ich die ISR definieren kann.

Sei froh, daß du es bei den Cortex-Architekturen deurlich einfacher 
hast als bei den klassischen ARM Architekturen.

Zu deinem Verständnis:

1. Am Anfang des Adreßraumes, also ab Adresse 0 gibt es bei den Cortexen 
eine Tafel aus 32 Bit Adressen (also Zeigern bzw. Vektoren je nach 
Gusto), die auf die diversen Interrupthandler zeigen. Dabei sind Vektor 
0 und 1 (also auf adresse 0 und 4, da 32 bittig) für die Start-Adresse 
des Stacks und den Kaltstart des Controllers vorgesehen. Dann folgen die 
Exception-Vektoren und dann die diversen ISR der Peripherie. Soweit 
klar?

2. Natürlich MUSS in jedem Vektor irgendwas stehen, weswegen es 
normalerweise im Startupcode einen Dummy-Handler dafür gibt.

3. Natürlich will man selbst auch seine ISR dort vermerkt haben, 
weswegen es einen Linker-Trick gibt: Der Dummy-Handler bekommt das 
Attribut [WEAK]. Wenn nun ein exakt gleichnamiger Handler in einem 
anderen zu linkenden Objectfile vorhanden ist, dann überschreibt dieser 
den betreffenden Vektor.

Normalerweise braucht man also nur seine ISR etwa so zu schreiben:
1
void __irq Exakter_Name_des_IRQHandlers (void)
2
{ ...
3
}
Dabei MUSS der Name exakt mit demjenigen im Startupcode übereinstimmen. 
So geht das.
Nochwas: _irq ist eigentlich _DER gebräuchliche Modifier für ISR auf 
den verschiedensten Plattformen. Nur der GCC brät sich mal wieder eine 
Extrawurst. Da ist dann etwa so etwas nötig:
1
#if defined (GCC)
2
#define __irq  __attribute__ ((interrupt("IRQ")))
3
#endif

W.S.

von W.S.H. (Gast)


Lesenswert?

W.S. erzählt wieder vom Pferd!
Bei den Cortex-M IRQ braucht es die IRQ direktive nicht.
Denn der NVIC sichert selbst die wichtigen Register.

von W.S. (Gast)


Lesenswert?

John Doe schrieb:
> Wenn man nicht weiss, wie man ein Manual liest, sollte man besser an
> seiner Lesekompetenz arbeiten. Man muss - wie oben bereits dargestellt -
> nicht stundenlang lesen, um an die Informationen zu kommen.

Das ist - mit Einschränkungen - rein sachlich durchaus richtig. 
Allerdings gibt es mehrere Anmerkungen dazu:

1. Es sind gerade die 32 bittigen µC keine simplen Chips. Deshalb gehört 
schon etwas Sachkompetenz dazu, selbige einzusetzen. Wer die nicht hat, 
muß sie erwerben und zwar durch Lesen.

2. Weiter oben wurde es ja schon angesprochen: anstatt durch Lesen 
selbst kompetent zu werden, fragen manche Leute lieber einfach den 
anderen ein Loch in den Bauch. So etwas mißfällt mir und anderen, weil 
es egoistisch ist. Man will nicht selber lernen, sondern erwartet, daß 
da jemand mit dem Nürnberger Trichter vorbeikommt und es einem macht.

3. In fast allen Manuals aller Hersteller findet man hie und da vor, daß 
deren Autoren manche Dinge für derart selbstverständlich halten, daß sie 
gar nicht daran denken, selbige dort zu erwähnen, wo dies eigentlich 
notwendig wäre. Manchmal wissen die Autoren auch selbst zuwenig und 
manchmal werden die Teile des Dokuments von verschiedenen Autoren 
verfaßt, wo ein jeder meint, daß der jeweils andere die Erklärung zu 
schreiben hätte.

4. Gerade bei den Interrupts, die hier ja Thema sind, genügt es nicht, 
nur das Kapitel über den Interruptcontroller zu lesen (was oftmals gar 
nicht vorhanden ist, da es ja zu den Dokumenten von ARM gehört), sondern 
auch aufmerksam die Beschreibung des jeweiligen Peripherie-Cores zu 
lesen, weil eben manche Interrupts zustandsgesteuert sind und andere 
flankengesteuert und wie deren Rückstellung zu erfolgen hat.

Ich hacke ja nicht grundlos auf dem ewigen Thema "Lowlevel-Treiber" 
herum, sondern deshalb, weil man damit auch solche 
Interrupt-Angelegenheiten nur einmal gründlich erledigen muß und später 
eben diesen Treiber benutzen kann, ohne sich um all diese Dinge noch 
einmal kümmern zu müssen. Aber dazu ist eben auch ein anderes 
Grundkonzept vonnöten, als es sowas wie Cube und Konsorten bieten. Das 
muß ein jeder begreifen und sich dann entscheiden, welchen Weg er 
selber gehen will.

W.S.

von W.S. (Gast)


Lesenswert?

W.S.H. schrieb:
> Bei den Cortex-M IRQ braucht es die IRQ direktive nicht.

Eine ISR als solche mit dem üblichen Attribut zu versehen, ist der Weg 
des sauberen Programmierens - ganz egal, ob das beim GCC benötigt wird 
oder nicht.

Mit demselben strohdummen Argument "braucht man nicht" könnte man auch 
gegen Kommentare, sinnvolle Namen und übersichtliches Quellformat 
lamentieren.

Daß das verkehrt ist, weiß eigentlich jeder.

W.S.

von W.S.H. (Gast)


Lesenswert?

W.S. schrieb:
> ist der Weg
> des sauberen Programmierens

Rede nicht über Dinge, die du selber nicht kannst.

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.