infinite loop, externer Interrupt, STM32F746, HAL-Library

Gast #6992838
Lesenswert?

Hallo,

siehe Code unten. Ich versuche via HAL-Library ein externen 
Interrupt-Eingang zu integrieren.

Sobald der Eingang triggert, stürzt das Programm ab, bzw. geht gemäss 
Debugger in eine "infinite loop", siehe auch Bild Anhang.
Die LED im loop blinkt dann auch nicht mehr.

Was mache ich falsch? :-(
Wo findet man eigentlich all diese HAL-Funktionen/Dokumentation (geht 
das überhaupt ohne CubeMx?)? Aktuell behelfe ich mir da mit der 
Google-Suche. Aber das ist mühsam.

Mit Arduino (stm32duino) kann ich einfach attachInterrupt() machen, und 
es läuft.

1
#include "stm32f7xx.h"
2
#include "stm32f7xx_hal_def.h"
3
#include "../Utilities/STM32746G-Discovery/stm32746g_discovery.h"
4

5
static void SystemClock_Config(void);
6
static void MX_GPIO_Init(void);
7
void Error_Handler(void);
8

9
int main(void)
10
{
11

12
    HAL_Init();
13
    //NVIC_SetPriority(SysTick_IRQn, -1);
14

15
    /* Configure the system clock to 216 MHz */
16
    SystemClock_Config();
17
  
18
    MX_GPIO_Init();
19

20

21

22

23
    while (1)
24
    {
25
  HAL_Delay(5);
26
        HAL_Delay(500);
27
        //HAL_GPIO_TogglePin( GPIOI , GPIO_PIN_8);
28
        HAL_GPIO_TogglePin( GPIOA , GPIO_PIN_7);
29
    }
30
}
31

32
static void SystemClock_Config(void)
33
{
34
    RCC_ClkInitTypeDef RCC_ClkInitStruct;
35
    RCC_OscInitTypeDef RCC_OscInitStruct;
36

37
    /* Enable Power Control clock */
38
    __HAL_RCC_PWR_CLK_ENABLE();
39

40
    /* The voltage scaling allows optimizing the power consumption when the device is
41
     clocked below the maximum system frequency, to update the voltage scaling value
42
     regarding system frequency refer to product datasheet.  */
43
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
44

45
    /*##-1- System Clock Configuration #########################################*/
46
    /* Enable HSE Oscillator and activate PLL with HSE as source */
47
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
48
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
49
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
50
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
51
    RCC_OscInitStruct.PLL.PLLM = 25;
52
    RCC_OscInitStruct.PLL.PLLN = 400;
53
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
54
    RCC_OscInitStruct.PLL.PLLQ = 8;
55
    HAL_RCC_OscConfig(&RCC_OscInitStruct);
56

57
    /* Activate the Over-Drive mode */
58
    HAL_PWREx_EnableOverDrive();
59

60
    /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
61
     clocks dividers */
62
    RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
63
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
64
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
65
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
66
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
67
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_6);
68

69
}
70

71
static void MX_GPIO_Init(void)
72
{
73
  GPIO_InitTypeDef GPIO_InitStruct = {0};
74

75
  /* GPIO Ports Clock Enable */
76
  //__HAL_RCC_GPIOB_CLK_ENABLE();
77
  __HAL_RCC_GPIOI_CLK_ENABLE();
78
  __HAL_RCC_GPIOA_CLK_ENABLE();
79

80
  /*Configure GPIO pin : PI13 */
81
  GPIO_InitStruct.Pin = GPIO_PIN_13;
82
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
83
  GPIO_InitStruct.Pull = GPIO_NOPULL;
84
  HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
85

86
  GPIO_InitStruct.Pin = GPIO_PIN_7;
87
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
88
  GPIO_InitStruct.Pull = GPIO_NOPULL;
89
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
90

91
  GPIO_InitStruct.Pin = GPIO_PIN_8;
92
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
93
  GPIO_InitStruct.Pull = GPIO_NOPULL;
94
  HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
95

96
  /* EXTI interrupt init*/
97
  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
98
  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
99
  //NVIC_SetPriority(SysTick_IRQn, -1);
100

101
}
102

103
/* USER CODE BEGIN 4 */
104
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
105
{
106
  //HAL_GPIO_TogglePin( GPIOI , GPIO_PIN_8);
107
  //HAL_GPIO_TogglePin( GPIOA , GPIO_PIN_7);
108
  /*
109
  if(GPIO_Pin == GPIO_PIN_13)
110
  {
111
  }
112
  */
113
  //__NOP();
114
}
115
/* USER CODE END 4 */
116
void Error_Handler(void)
117
{
118
  /* USER CODE BEGIN Error_Handler_Debug */
119
  /* User can add his own implementation to report the HAL error return state */
120
  /* USER CODE END Error_Handler_Debug */
121
}
Angehängte Dateien:
Gast #6992854
Lesenswert?

Für z.B. Uart muss ich immer noch eine IQRHandler aktivieren.

void USART3_IRQHandler(void)
{
    HAL_UART_IRQHandler(g_cp_HandleUart[2]);
}

g_cp_HandleUart[] ist mein globales Handle-Array


Vielleicht braucht GPIO das auch so ähnlich?

Die IRQs, die verfügbar sind, stehen bei mir in
startup_stm32h743zitx.s
..
  .word     USART1_IRQHandler
  .word     USART2_IRQHandler
--
Gast #6992868
Lesenswert?

utzutr schrieb:
> du nutzt zwar die callback .. aber ich vermisse die eigentliche ISR  mit
> der HAL  ISR funktion ( die am ende deine callback aufruft )

wird wohl schon im stm32fxx_hal_gpio.c definiert:
1
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
2
{
3
  /* Prevent unused argument(s) compilation warning */
4
  UNUSED(GPIO_Pin);
5
  
6
  /* NOTE: This function Should not be modified, when the callback is needed,
7
           the HAL_GPIO_EXTI_Callback could be implemented in the user file
8
   */
9
}


Gibt es eigentlich (offizielle) Beispiele/Dokumentation zu dieser 
HAL-Library?
Gast #6992871
Lesenswert?

äh falscher Code, hier wird die Callback aufgerufen, im 
stm32fxx_hal_gpio.c - File:
1
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
2
{
3
  /* EXTI line interrupt detected */
4
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
5
  {
6
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
7
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
8
  }
9
}
#6992874
Lesenswert?

Kommt mir bekannt vor... Deine INT-Routine wird nicht im 
Interrupt-Vektor eingetragen, sodass dort über den Default Vector bei 
Eintreten eines Interrupts in diese Endlos-Schleife gesprungen wird.
Ich weiß jetzt nicht mehr auswending, was genau ich damals im Code 
ändern musste, aber schau Dir mal Deine Interrupt Vector Table an und 
checke, ob an der relevanten Stelle Deine gewollte INT-Routine 
eingetragen ist.
Gast #6992917
Lesenswert?

epika schrieb:
> Wo findet man eigentlich all diese HAL-Funktionen/Dokumentation (geht
> das überhaupt ohne CubeMx?)

z.B. auf github im STM32CubeF7 Repo sind Beispiele und Doku.
Wie schon genannt, fehlt vermutlich die eigentliche ISR und der 
Interrupt landet im Defaulthandler.

https://github.com/STMicroelectronics/STM32CubeF7/blob/e96f98542c6782d97bdd0c50833ee4b70130f3a7/Projects/STM32F746ZG-Nucleo/Examples/GPIO/GPIO_EXTI/Src/stm32f7xx_it.c#L155-L158
Gast #6992950
Lesenswert?

Ich nutze statt irgend eines Delay immer:
1
//main.c:
2
/* USER CODE BEGIN 4 */
3
void HAL_SYSTICK_Callback(void){
4
...}
5
/* USER CODE END 4 */

Um diese zu nutzen, muss ich in der stm32fxxx_it.c im SysTick_Handler 
den Aufruf von HAL_SYSTICK_IRQHandler eintragen, von dem die Funktion 
HAL_SYSTICK_Callback aufgerufen wird.
Dieses Prinzip ist für alle Interrupt/Callback identisch:
1
void SysTick_Handler(void)
2
{
3
  /* USER CODE BEGIN SysTick_IRQn 0 */
4

5
  /* USER CODE END SysTick_IRQn 0 */
6
  HAL_IncTick();
7
  /* USER CODE BEGIN SysTick_IRQn 1 */
8
  HAL_SYSTICK_IRQHandler();
9
  /* USER CODE END SysTick_IRQn 1 */
10
}
Gast #6993016
Lesenswert?

Thilo L. schrieb:
> aber schau Dir mal Deine Interrupt Vector Table an und
> checke, ob an der relevanten Stelle Deine gewollte INT-Routine
> eingetragen ist.

also CubeMx fügt folgendes im stm32f7xx_it.c hinzu:
1
void EXTI15_10_IRQHandler(void)
2
{
3
  /* USER CODE BEGIN EXTI15_10_IRQn 0 */
4

5
  /* USER CODE END EXTI15_10_IRQn 0 */
6
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
7
  /* USER CODE BEGIN EXTI15_10_IRQn 1 */
8

9
  /* USER CODE END EXTI15_10_IRQn 1 */
10
}

und das hier ist schon vorhanden:
1
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
2
{
3
  /* EXTI line interrupt detected */
4
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
5
  {
6
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
7
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
8
  }
9
}

Hans schrieb:
> Interrupt Flag wird nicht gelöscht. Deswegen andauernd Interrupts was
> der Compiler wohl als "infinite loop" übersetzt.

In den Beispielen im Internet, wenn man die Callback 
"HAL_GPIO_EXTI_Callback" verwendet, finde ich keine Zeile die das Flag 
löscht.
Wenn man direkt "void EXTI15_10_IRQHandler(void)" verwendet, dann 
schon... muss ich da noch eine Zeile hinzufügen um das Flag zu löschen? 
Wieso macht CubeMx dies nicht automatisch :-D ??

ijo, nicht einfach....
Gast #6993028
Lesenswert?

epika schrieb:
> Wieso macht CubeMx dies nicht automatisch :-D ??
1
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);

wird hier schon gelöscht.
Also lag es wohl am fehlenden Code:
1
void EXTI15_10_IRQHandler(void)
2
{
3
  /* USER CODE BEGIN EXTI15_10_IRQn 0 */
4
  /* USER CODE END EXTI15_10_IRQn 0 */
5
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
6
  /* USER CODE BEGIN EXTI15_10_IRQn 1 */
7
  /* USER CODE END EXTI15_10_IRQn 1 */
8
}

muss ich morgen testen....

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