Hallo, weiß einer wie ich beim Cortex M4 (genauer ein XMC4500) die Interrupts an und ausschalten habe. Ich habe folgendes Problem ich muss für einen Funktionsaufruf die Interrupts disablen und danach wieder enablen. disable_irq(); fubar(); enable_irq(); als Beispiel. Bei AVR geht das ja mit sei(); und cil(); Ich hab für den M4 so was ähnliches auch schon gefunden __enable_irq() und __disable_irq() das problem nur ist die beiden Funktionen sind für den ARM GCC Compiler den ich benutzen muss nicht verfügbar. Wisst ihr ob es für den GCC Compiler auch solche Funktionen gibt? Vielen Dank schon mal. Viele Grüße Thomas
Musst du absolut alle Interrupts ausschalten, oder nur bestimmte? Bestimmte Interrupts lassen sich über den NVIC abschalten, und der zulässige IRQ-Level lässt sich elegant mit BASEPRI/BASEPRI_MAX steuern. Für die Interrupts insgesamt müsste es was im CMSIS geben. Edit: Das ist ebd. __disable_irq. CMSIS gibts auch für GCC.
A. K. schrieb: > Musst du absolut alle Interrupts ausschalten, oder nur bestimmte? > > Bestimmte Interrupts lassen sich über den NVIC abschalten, und der > zulässige IRQ-Level lässt sich elegant mit BASEPRI/BASEPRI_MAX steuern. > > Für die Interrupts insgesamt müsste es was im CMSIS geben. Edit: Das ist > ebd. __disable_irq. CMSIS gibts auch für GCC. Ich bin mir nicht sicher ob ich alle müsste oder ob nur bestimmte reichen würden. Das ist ein altes Projekt dass ich portieren soll auf den XMC4500. Dort werden alle Interrupts deaktiviert. Hab mir auch schon gedacht, dass ich einfach die NVIC routinen verwende und mir einfach dort dann alle Interrupts einzeln abschalte. Ich hab die CMSIS Includs schon durch sucht, dass einzige was ich dort gefunden habe war in der Datei core_cmFunc.h __disable_irq und die sind dort nur verfügbar wenn ein define __CC_ARM gesetzt ist also wenn man den RealView Compiler verwendet. Mehr hab ich leider noch nicht gefunden bzw.ich land eimmer wieder bei den __disable_irq. Wenn die für ARM GCC verfügbar sind hab ich noch nicht herausgefunden was ich includieren muss, damit ich die verwenden kann.
Thomas schrieb: > man den RealView Compiler verwendet. Es gibt schon seit vielen Jahren ein CMSIS mit Unterstützung von GCC.
Glaub ich dir ja. Ich hab gerade weiter gesucht nach dieser Beschreibung http://www.keil.com/pack/doc/cmsis/Core/html/_templates_pg.html sind das genau die 2 Funktionen die ich schon gefunden habe. Ich hab jetzt nur das Problem wie verwende ich diese Funktionen. Schau ich mir die Headerdatei core_cmFunc.h an in dem diese Funktionen enthalten sind sind dort all Funktionen von #if defined (__CC_ARM) /*----------RealView Compiler-----------*/ /*arm armcc speicific functions */ . . . #end if umschlossen und damit "ausgegraut". Ich hab nur gerade überhaupt keinen Plan wie ich die jetzt verwenden kann. Kann auch sein das ich gerade einfach nur auf der Leitung sitze.
Ist Keil wirklich die beste Quelle für GCC? NB: Um welchen GCC handelt es sich? Zig Firmen verwenden den in ihren jeweiligen verschiedenen Entwicklungsumgebungen.
CMSIS, core_cmFunc.h:
1 | #elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ |
2 | /* GNU gcc specific functions */
|
3 | |
4 | /** \brief Enable IRQ Interrupts
|
5 | |
6 | This function enables IRQ interrupts by clearing the I-bit in the CPSR.
|
7 | Can only be executed in Privileged modes.
|
8 | */
|
9 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) |
10 | {
|
11 | __ASM volatile ("cpsie i" : : : "memory"); |
12 | }
|
13 | |
14 | |
15 | /** \brief Disable IRQ Interrupts
|
16 | |
17 | This function disables IRQ interrupts by setting the I-bit in the CPSR.
|
18 | Can only be executed in Privileged modes.
|
19 | */
|
20 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) |
21 | {
|
22 | __ASM volatile ("cpsid i" : : : "memory"); |
23 | }
|
Thomas schrieb: > disable_irq(); > fubar(); > enable_irq(); Stelle deine Programmlogik lieber so um, daß du sowas überhaupt nicht brauchst. Ich hatte ganz früher auch mal geglaubt, daß man das temporäre Ausschalten von Interrupts brauchen würde, aber das stimmt nicht. Keiner braucht sowas wirklich - wenn (ja WENN) man umsichtig und sinnvoll programmiert. Und wenn du ein altes Projekt auf neuer Hardware portieren mußt, dann ist mit Sicherheit noch viel mehr an Umstellung erforderlich. W.S.
W.S. schrieb: > Stelle deine Programmlogik lieber so um, daß du sowas überhaupt nicht > brauchst. Ich hatte ganz früher auch mal geglaubt, daß man das temporäre > Ausschalten von Interrupts brauchen würde, aber das stimmt nicht. Keiner > braucht sowas wirklich - wenn (ja WENN) man umsichtig und sinnvoll > programmiert. > > Und wenn du ein altes Projekt auf neuer Hardware portieren mußt, dann > ist mit Sicherheit noch viel mehr an Umstellung erforderlich. > > W.S. Die Programmlogik umzustellen würde alles viel zu viel Zeit verbrauchen. Die Portierung ist Teil meiner Abschlussarbeit, aber ein sehr unwichtiger teil wenn es um die Benotung geht, aber leider ein sehr Zeitaufwendiger, darum will ich den Teil einfach ziemlich schnell hintermich bringen damit ich mich um den "wichtigen" Teil intensiver kümmen kann. Ich habs jetzt einfach so gemacht, dass ich mit den NVIC functionen die Interruptquellen abschalte, die einzige Interruptquelle die dann noch läuft ist der SysTick timer, da dessen Interruptnummer negative ist, und deshalb über die NVIC Funktion nicht abgeschaltet werden kann. Is nicht die schönste Lösung aber es sollte Funktionieren Außerdem wird dort eh nur eine Variable hochgezählt, die den eingeschlossen Teil nicht beeinflusst.
Random ... schrieb: > __attribute__( ( always_inline ) ) __STATIC_INLINE void > __disable_irq(void) > { > __ASM volatile ("cpsid i" : : : "memory"); > } Ich hab mich zwar eine Weile nicht mit ARM beschäftigt, aber soweit ich mich erinnere gibt das entsprechende Intrinsic des armcc noch den aktuellen Status zurück, so dass man den ursprünglichen Zustand bedingt wieder herstellen kann anstatt die Interupts einfach wieder einzuschalten.
Du solltest dich mit dem Interrupt System und den Interrupt Prioritäten beschäftigen. Anstatt Interrupts zu sperren, kann man die Priorität der laufenden Task erhöhen. Such einmal nach BASEPRI: http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/CHDBIBGJ.html#BABHCGDA
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.