Forum: Mikrocontroller und Digitale Elektronik STM32F3 HAL CAN geht in den Error Handler beim receive int


von Bülent C. (mirki)


Lesenswert?

Moin moin,

mit CubeMX habe ich mir ein Projekt für Keil erzeugt indem ich CAN im 
Interrupt benutzen möchte. Nur habe ich das Problem, das beim auslösen 
des int's der STM32F3 sich aufhängt.
Im Debugger kann ich sehen, das die CAN Message richtig empfangen wurde.

Was habe ich gemacht:

Das ist in der main funktion:
1
  sFilterConfig.FilterNumber = 0;
2
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
3
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
4
  sFilterConfig.FilterIdHigh = 0x0000;
5
  sFilterConfig.FilterIdLow = 0x0000;
6
  sFilterConfig.FilterMaskIdHigh = 0x0000;
7
  sFilterConfig.FilterMaskIdLow = 0x0000;
8
  sFilterConfig.FilterFIFOAssignment = 0;
9
  sFilterConfig.FilterActivation = ENABLE;
10
  //sFilterConfig.BankNumber = 14; //Für STM32F303 nicht notwendig, da nur ein CAN
11
  HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
12
13
14
 if(HAL_CAN_Receive_IT(&hcan, CAN_FIFO0) != HAL_OK)
15
  {
16
    /* Reception Error */
17
    Error_Handler();
18
  }

Das ist die can.c
1
/* Includes ------------------------------------------------------------------*/
2
#include "can.h"
3
4
#include "gpio.h"
5
6
/* USER CODE BEGIN 0 */
7
8
/* USER CODE END 0 */
9
10
CAN_HandleTypeDef hcan;
11
12
/* CAN init function */
13
void MX_CAN_Init(void)
14
{
15
16
  hcan.Instance = CAN;
17
  hcan.Init.Prescaler = 4;
18
  hcan.Init.Mode = CAN_MODE_NORMAL;
19
  hcan.Init.SJW = CAN_SJW_1TQ;
20
  hcan.Init.BS1 = CAN_BS1_12TQ;
21
  hcan.Init.BS2 = CAN_BS2_5TQ;
22
  hcan.Init.TTCM = DISABLE;
23
  hcan.Init.ABOM = DISABLE;
24
  hcan.Init.AWUM = DISABLE;
25
  hcan.Init.NART = DISABLE;
26
  hcan.Init.RFLM = ENABLE;
27
  hcan.Init.TXFP = DISABLE;
28
  if (HAL_CAN_Init(&hcan) != HAL_OK)
29
  {
30
    Error_Handler();
31
  }
32
33
}
34
35
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
36
{
37
38
  GPIO_InitTypeDef GPIO_InitStruct;
39
  if(canHandle->Instance==CAN)
40
  {
41
  /* USER CODE BEGIN CAN_MspInit 0 */
42
43
  /* USER CODE END CAN_MspInit 0 */
44
    /* Peripheral clock enable */
45
    __HAL_RCC_CAN1_CLK_ENABLE();
46
  
47
    /**CAN GPIO Configuration    
48
    PA11     ------> CAN_RX
49
    PA12     ------> CAN_TX 
50
    */
51
    GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
52
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
53
    GPIO_InitStruct.Pull = GPIO_NOPULL;
54
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
55
    GPIO_InitStruct.Alternate = GPIO_AF9_CAN;
56
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
57
58
    /* Peripheral interrupt init */
59
    HAL_NVIC_SetPriority(USB_HP_CAN_TX_IRQn, 0, 0);
60
    HAL_NVIC_EnableIRQ(USB_HP_CAN_TX_IRQn);
61
    HAL_NVIC_SetPriority(USB_LP_CAN_RX0_IRQn, 0, 0);
62
    HAL_NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn);
63
  /* USER CODE BEGIN CAN_MspInit 1 */
64
65
  /* USER CODE END CAN_MspInit 1 */
66
  }
67
}
68
69
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
70
{
71
72
  if(canHandle->Instance==CAN)
73
  {
74
  /* USER CODE BEGIN CAN_MspDeInit 0 */
75
76
  /* USER CODE END CAN_MspDeInit 0 */
77
    /* Peripheral clock disable */
78
    __HAL_RCC_CAN1_CLK_DISABLE();
79
  
80
    /**CAN GPIO Configuration    
81
    PA11     ------> CAN_RX
82
    PA12     ------> CAN_TX 
83
    */
84
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
85
86
    /* Peripheral interrupt Deinit*/
87
    HAL_NVIC_DisableIRQ(USB_HP_CAN_TX_IRQn);
88
89
    HAL_NVIC_DisableIRQ(USB_LP_CAN_RX0_IRQn);
90
91
  }
92
  /* USER CODE BEGIN CAN_MspDeInit 1 */
93
94
  /* USER CODE END CAN_MspDeInit 1 */
95
} 
96
97
/* USER CODE BEGIN 1 */
98
99
/* USER CODE END 1 */
100
101
/**
102
  * @}
103
  */
104
105
/**
106
  * @}
107
  */
108
109
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Und das hier ist die Callback Funktion für die int Funktion
1
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle)
2
{
3
 
4
    
5
    ToggleLED(2);
6
  
7
     
8
  if(HAL_CAN_Receive_IT(&hcan, CAN_FIFO0) != HAL_OK)
9
  {
10
  
11
    Error_Handler();
12
  }
13
  
14
  
15
16
}

Habe schon überall geschaut, aber konnte nichts auffälliges finden was 
auf einen Fehler hindeuten könnte.
Für jeden Tip wäre ich sehr dankbar.

VG,
Bülent

von Knut (Gast)


Lesenswert?

Dieses HAL Zeug, sollte doch dafür gut sein, um sich aufs wesentliche zu 
konzentrieren, da das CubeMX die Hardware Config etc vornimmt.
Aber wehe da passt etwas nicht... Daher liebe ich die StdLibs.

von Bülent C. (mirki)


Lesenswert?

Knut schrieb:
> Dieses HAL Zeug, sollte doch dafür gut sein, um sich aufs
> wesentliche zu
> konzentrieren, da das CubeMX die Hardware Config etc vornimmt.
> Aber wehe da passt etwas nicht... Daher liebe ich die StdLibs.

Danke, aber das bringt mich jetzt nicht weiter.

von il Conte (Gast)


Lesenswert?

Bülent C. schrieb:
> Danke, aber das bringt mich jetzt nicht weiter.

Wieso nicht. Der Hinweis von Knut ist doch gut.

Also ich würde zumindest versuchen zu verstehen
was hinter der 'StdLibs' steckt.
Vieleicht bringt es dich ja weiter.
Auf jeden Fall stellt es eine Horizonterweiterung dar ;-)

von Bülent C. (mirki)


Lesenswert?

Mit den StdLibs bekomme ich es ja hin, da ist es kein Problem, aber 
warum geht dies nicht mit HAL. Im grunde genommen müsste eigentlich 
alles richtig sein, oder ich übersehe was HAL spezifisches, wovon ich 
schwer ausgehe.

von Franz (Gast)


Lesenswert?

Schau mal von wo HAL_CAN_RxCpltCallback aufgerufen wird

von Bülent C. (mirki)


Lesenswert?

Also, es scheint sich hier evtl. um einen Bug in den HAL Treibern zu 
handeln.
Beim debuggen habe ich folgendes festgestellt:

Wenn eine CAN Message ankommt, dann wird die Funktion
HAL_CAN_IRQHandler aufgerufen.

Nachdem diese Bedingung
1
if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0)) &&
2
     (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0) != 0))
 erfüllt wurde, wird die CAN_Receive_IT Funktion aufgerufe.
Beim lesen der CAN Message geht es direkt in den Fault Handler.
Im Fault Handler habe ich ein HAL_CAN_STATE_BUSY_RX auf CAN receive.

Wie kann sowas sein, ich habe den den CAN TX int nicht mal an. ?!

: Bearbeitet durch User
von Bülent C. (mirki)


Lesenswert?

Problem gelöst...

Die init Funktion war nicht vollständig von CubeMX erstellt worden.
Bug oder kein Bug?

hcan.pTxMsg = &TxMessage;
hcan.pRxMsg = &RxMessage;
fehlten gänzlich....
1
void MX_CAN_Init(void)
2
{
3
  static CanTxMsgTypeDef        TxMessage;
4
  static CanRxMsgTypeDef        RxMessage;
5
  
6
  hcan.pTxMsg = &TxMessage;
7
  hcan.pRxMsg = &RxMessage;
8
  
9
  hcan.Instance = CAN;
10
  hcan.Init.Prescaler = 4;
11
  hcan.Init.Mode = CAN_MODE_NORMAL;
12
  hcan.Init.SJW = CAN_SJW_1TQ;
13
  hcan.Init.BS1 = CAN_BS1_12TQ;
14
  hcan.Init.BS2 = CAN_BS2_5TQ;
15
  hcan.Init.TTCM = DISABLE;
16
  hcan.Init.ABOM = DISABLE;
17
  hcan.Init.AWUM = DISABLE;
18
  hcan.Init.NART = DISABLE;
19
  hcan.Init.RFLM = ENABLE;
20
  hcan.Init.TXFP = DISABLE;
21
  if (HAL_CAN_Init(&hcan) != HAL_OK)
22
  {
23
    Error_Handler();
24
  }
25
26
}

von Holger (Gast)


Lesenswert?

Bülent C. schrieb:
> Die init Funktion war nicht vollständig von CubeMX erstellt worden.
> Bug oder kein Bug?
> hcan.pTxMsg = &TxMessage;
> hcan.pRxMsg = &RxMessage;
> fehlten gänzlich....

Im zweiten Teil des CAN-Bus Tutorials gibt es endlich die Programmierung 
und GANZ WICHTIGE TIPPS!! neuen CubeMX und dem JTAG /SWD disable
..... bis zum CAN Loopback mode test vorspulen ...
Link:
https://www.youtube.com/watch?v=gu1Uz2K3zh4
---------------------------------------------


Alle Codes zum Download in der Youtube Beschreibung.
---------------------------------------------

Gruss Holger.

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.