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.
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".
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.
und das extern "C" nicht vergessen wenn man die ISR in C++ Quellen verwendet.
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 __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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.