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
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.
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".
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 :)
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.
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?
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.
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.
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.
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.
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.
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__irqExakter_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:
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.
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.