Forum: Mikrocontroller und Digitale Elektronik STM32F4 USART-Interrupt landet in def_irq_handler


von Bauteiltöter (Gast)


Lesenswert?

Guten Tag,

ich sammel gerade erste Erfahrung mit dem STM32F417.

Ich versuche das Interrupt-gesteuerte Senden über U(S)ART2 
hinzubekommen.

Ich verwende EM::Blocks 2.30 mit GCC / g++.
Da ich C++ programmieren möchte, habe ich unter "linker flags" "Use C++ 
libraries" angekreuzt.

In meinem Programm initialisiere ich zuerst den GPIO-Port (GPIOD.5) an 
dem das Terminal hängt, danach initialisiere ich den NVIC, danach den 
eigentlichen USART.
Danach schicke ich ein Byte per USART, das empfange ich auch korrekt am 
Computer.

Im Debugger sehe ich, das direkt danach das TC-Bit in USART2->SR auf 1 
geht, einen Takt später scheint der Debugger die Verbindung zu 
verlieren, wenn ich auf Pause drücke kann ich sehen, dass der 
Programmcounter in folgender Zeile steht:
startup_stm32f4xx.S
Zeile 286: def_irq_handler    USART2_IRQHandler

Disassembly an der Stelle ergibt einen Sprung auf die gleich Zeile, also 
eine klassische Entlosschleifen.

Meine Schlussfolgerung:
Der Interrupt wird korrekt ausgelöst und landet in diesem 
defaultHandler.
Meine Frage:
Warum? Warum landet der Controller nicht wenigstens im 
HardFault-Handler?

Seltsamer weise kann ich in meiner Funktion USART2_IRQHandler keinen 
Brakepoint setzen, Debuggerfehler: Error: No line 113 in file 
"src/main.cpp". (Versuch auf das 2. nop einen Brakepoint zu setzen.)

Hier ist der Code:
1
int main(void)
2
{
3
    //PD5 (TXD) konfigurieren
4
    GPIO_InitTypeDef GPIO_initStructur;
5
6
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
7
8
9
    GPIO_initStructur.GPIO_Pin = (1<<5);
10
    GPIO_initStructur.GPIO_Mode = GPIO_Mode_AF;
11
    GPIO_initStructur.GPIO_PuPd = GPIO_PuPd_NOPULL;
12
    GPIO_initStructur.GPIO_OType = GPIO_OType_PP;
13
    GPIO_initStructur.GPIO_Speed = GPIO_Speed_100MHz;
14
    GPIO_Init(GPIOD, &GPIO_initStructur);
15
    GPIO_PinAFConfig(GPIOD, 5, GPIO_AF_USART2); //USART2 auflegen
16
17
    //NVIC Konfigurieren
18
    NVIC_InitTypeDef NVIC_InitStructure;
19
    NVIC_InitStructure.NVIC_IRQChannel =  USART2_IRQn;
20
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
21
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
22
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
23
    NVIC_Init(&NVIC_InitStructure);
24
25
26
    //USART2 konfigurieren
27
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_USART2EN, ENABLE);
28
    USART_InitTypeDef Debug_init_s;
29
30
    Debug_init_s.USART_BaudRate = 256000;
31
    Debug_init_s.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
32
    Debug_init_s.USART_Mode = USART_Mode_Tx;
33
    Debug_init_s.USART_Parity = USART_Parity_No;
34
    Debug_init_s.USART_StopBits = USART_StopBits_1;
35
    Debug_init_s.USART_WordLength = USART_WordLength_8b;
36
37
    USART_DeInit(USART2);
38
    USART_Init(USART2, &Debug_init_s);
39
40
    //Flag auf 0 setzten damit der INterrupt nicht sofort kommt
41
    USART_ClearITPendingBit(USART2, USART_FLAG_TC); 
42
    USART_Cmd(USART2, ENABLE);
43
44
    //Interrupt aktivieren
45
    USART_ITConfig(USART2, USART_IT_TC, ENABLE);
46
47
    //Daten senden
48
    USART_SendData(USART2, 0x00);
49
50
51
    while(1)
52
    {
53
54
    }
55
}
56
57
void HardFault_Handler()
58
{
59
    while(1)
60
    {
61
    }
62
}
63
64
void USART2_IRQHandler()
65
{
66
    USART_ClearITPendingBit(USART2,USART_IT_TC);
67
    asm("nop");
68
    asm("nop");
69
    asm("nop");
70
    asm("nop");
71
    return;
72
}

Würde mich sehr freuen wenn mir jemand bei diesem Problem helfen kann.

lg

von Jim M. (turboj)


Lesenswert?

Bauteiltöter schrieb:
> Warum? Warum landet der Controller nicht wenigstens im
> HardFault-Handler? [...]
>  in file "src/main.cpp".

In C++ musst Du die Interrupt Handler als
1
extern "C" {
2
3
}

deklarieren. Ansonsten werden durch den C++ Comiler andere Signaturen 
benutzt, die nicht mehr zu den Deklarationen für die Vektortabelle 
passen.

von Bauteiltöter (Gast)


Lesenswert?

Nach 9 Minuten schon die richtige Antwort - ich bin von diesem Forum 
immer wieder begeistert!

Vielen Dank für die schnelle Hilfe, habe das extern "C" dazu geschrieben 
und - oh Wunder, es funktioniert.

lg

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.