STM32 Timer Interrupt Problem mit CooCox IDE

Gast #4493821
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
Gast #4493844
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).
Gast #4493853
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
(Firma: www.harerod.de) Persönliche Seite #4493995
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren