Forum: Mikrocontroller und Digitale Elektronik ARM cortex M4 IRQ Interrupts


von Thomas (Gast)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

: Bearbeitet durch User
von Thomas (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

Thomas schrieb:
> man den RealView Compiler verwendet.

Es gibt schon seit vielen Jahren ein CMSIS mit Unterstützung von GCC.

von Thomas (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

: Bearbeitet durch User
von Thomas (Gast)


Lesenswert?

Ich verwende die DAVE3 IDE von Infineon in der Version 3.1.8

von Random .. (thorstendb) Benutzerseite


Lesenswert?

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
}

von W.S. (Gast)


Lesenswert?

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.

von Thomas (Gast)


Lesenswert?

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.

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

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.

von Priority (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.