Forum: Mikrocontroller und Digitale Elektronik STM32 Timer Interrupt Problem mit CooCox IDE


von Klaus (Gast)


Lesenswert?

Hallo,

ich habe in folgenden Schnipsel eine merkwürdige Erscheinung:
1
int main(int argc, const char* argv[])
2
{
3
  SystemInit();
4
5
  TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
6
  NVIC_InitTypeDef NVIC_InitStructure;
7
8
  SystemInit();
9
10
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
11
12
  TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
13
  TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
14
  TIM_TimeBase_InitStructure.TIM_Prescaler = 1900;
15
  TIM_TimeBase_InitStructure.TIM_Period = 17999;
16
  TIM_TimeBaseInit(TIM2, &TIM_TimeBase_InitStructure);
17
18
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
19
20
  TIM_Cmd(TIM2, ENABLE);
21
22
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
23
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
24
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
25
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
26
  NVIC_Init(&NVIC_InitStructure);
27
28
  while (1)
29
  {
30
    int i = 0; //HIER IST EIN BREAK-POINT
31
    i++;
32
  }
33
34
    return 0;
35
}
36
37
void TIM2_IRQHandler()
38
{
39
  ; //HIER IST EIN BREAK-POINT
40
}

Der Break-Punkt im Timer Interrupt wird angesprungen, aber der 
Break-Punkt in der Hauptschleife nicht.

Wenn ich jetzt den Break-Punkt im Interrupt entferne, dann hält der 
Debugger trotzdem nicht in der Hauptschleife an.

Vielmehr scheint es so, dass sich die Kiste hier aufhängt:
1
NVIC_Init(&NVIC_InitStructure);

Warum?

Ich bin dankbar für jeden Hinweis. Gruß Klaus

von chris (Gast)


Lesenswert?

Klaus schrieb:
> Vielmehr scheint es so, dass sich die Kiste hier aufhängt:

Nein, du setzt in deinem Interrupt nicht das zugehörige Flag zurück.
Somit wird ununterbrochen die ISR aufgerufen und die main()-Funktion 
wird garnicht mehr ausgeführt. (Anders als beim AVR, wo zwischen zwei 
Interrupts immer kurz  die main dran kommt).

von Klaus (Gast)


Lesenswert?

chris schrieb:
> Klaus schrieb:
>> Vielmehr scheint es so, dass sich die Kiste hier aufhängt:
>
> Nein, du setzt in deinem Interrupt nicht das zugehörige Flag zurück.
> Somit wird ununterbrochen die ISR aufgerufen und die main()-Funktion
> wird garnicht mehr ausgeführt. (Anders als beim AVR, wo zwischen zwei
> Interrupts immer kurz  die main dran kommt).

Hallo chris,

vielen Dank für die schnelle und kompetente Hilfe!
Genau das wars.

Gruß Klaus

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

chris schrieb:
> Klaus schrieb:
>> Vielmehr scheint es so, dass sich die Kiste hier aufhängt:
>
> Nein, du setzt in deinem Interrupt nicht das zugehörige Flag zurück.
> Somit wird ununterbrochen die ISR aufgerufen und die main()-Funktion
> wird garnicht mehr ausgeführt. (Anders als beim AVR, wo zwischen zwei
> Interrupts immer kurz  die main dran kommt).

Das Feature heißt "Interrupt chaining".
Im Gegensatz zum AVR ist ein Interrupt für den ARM deutlich aufwändiger.
Die CPU sichert automatisch eine Menge Kontext weg, das kostet soviel 
Zeit, dass ein 168MHz-M4 nicht überragend viel schneller ist, als ein 
AVR.

Wenn nun aber am Ende des Interrupts weitere Interrupts anhängig sind 
(interrupt pending), dann spart sich die CPU den Overhead für Rückladen 
und neu Einspringen.

Passende Literatur zu dem Thema NVIC findet sich hier
http://infocenter.arm.com/help/topic/com.arm.doc.100166_0001_00_en/arm_cortexm4_processor_trm_100166_0001_00_en.pdf

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.