HAL wrapper library crashes due to interrupt issue

Post here first, or if you can't find a relevant section!
Post Reply
JorgeMaker
Posts: 2
Joined: Wed Feb 10, 2021 11:15 pm

HAL wrapper library crashes due to interrupt issue

Post by JorgeMaker »

HiI am trying to re implement CAN library to run on STM32F405RTG6. I have been able to get my implementation to work properly for sending messages but when I turn on notifications, if there are messages to receive it hangs. It happens indistinctly when there are messages generated by another device or when I put it in loopbkac mode. Does any any one what cold be happeninig?

Thanks in advance for your time and support :)

PS: I have not come to implement the hadler part since just putting the callbakc crashes. The debugger says it receives an “unexpected exception” and goes into an infinite loop.

SimpleCan.h

Code: Select all

#ifndef __CAN__H
#define __CAN__H

#include "Arduino.h"
#include "stm32f4xx_hal_can.h"


// Value needed for prescaler. depends 
// on CLK configuration
enum CanSpeed
{
	Kbit500 = 5,
	Kbit250 = 10,
	Kbit125 = 20,
	Kbit100 = 25,
  Kbit50 =  50,
  Kbit20  = 125

};

enum CanMode
{
	NormalCAN = CAN_MODE_NORMAL,
	SilentCAN = CAN_MODE_SILENT,
	LoopBackCan = CAN_MODE_LOOPBACK,
	SilentLoopBackCAN = CAN_MODE_SILENT_LOOPBACK
};


typedef struct{
  uint8_t dlc;
  uint32_t msgID;
  bool isRTR;
  bool isStandard;
  uint8_t data[8];
}CanMessage;


CanMessage createMessage(void);
/**
 CAN wrapper for STM32F405RGT6 board.
*/
class SimpleCan
{
public:
/*
	class RxHandler
	{
	public:
		RxHandler(uint16_t dataLength, void(*callback)(CAN_RxHeaderTypeDef rxHeader, uint8_t *rxData));
		~RxHandler();
		void notify(CAN_HandleTypeDef *hcan1);
	
  private:
		CAN_RxHeaderTypeDef _rxHeader;
		uint8_t *_rxData;
		void(*_callback)(CAN_RxHeaderTypeDef, uint8_t *);
	};
*/
	SimpleCan();
	HAL_StatusTypeDef init(CanSpeed speed, CanMode mode);
	HAL_StatusTypeDef configFilter(CAN_FilterTypeDef *filterDef);
  HAL_StatusTypeDef configSnniferFilter();
	HAL_StatusTypeDef activateNotification(/*RxHandler *rxHandler*/);
	HAL_StatusTypeDef deactivateNotification();
	HAL_StatusTypeDef begin();
	HAL_StatusTypeDef stop();
	HAL_StatusTypeDef send(CanMessage message);
  //private: interrupt handler needs access to it
  CAN_HandleTypeDef hcan;
  //static RxHandler *_rxHandler;

};
#endif
SimpleCan.cpp

Code: Select all

#include <SimpleCan.h>
#include <Arduino.h>

extern "C" HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *);
extern "C" HAL_StatusTypeDef HAL_CAN_Stop (CAN_HandleTypeDef *);
extern "C" HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef *);
extern "C" HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *, uint32_t );
extern "C" void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *);

void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan1)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hcan1->Instance==CAN1)
  {
  /* USER CODE BEGIN CAN1_MspInit 0 */

  /* USER CODE END CAN1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_CAN1_CLK_ENABLE();

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**CAN1 GPIO Configuration
    PB8     ------> CAN1_RX
    PB9     ------> CAN1_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* CAN1 interrupt Init */
    HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
    /* USER CODE BEGIN CAN1_MspInit 1 */

    /* USER CODE END CAN1_MspInit 1 */
  }

}

CanMessage createMessage(){
  CanMessage message;
  message.dlc = 8;
  message.msgID = 200;
  message.isRTR = false;
  message.isStandard = true;
  uint8_t messageLoadBuffer[8] ={0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x23};
  memcpy(message.data, messageLoadBuffer, 8);
  
  return message;
}

SimpleCan::SimpleCan(){
    return;
}
HAL_StatusTypeDef SimpleCan::init(CanSpeed speed, CanMode mode){
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = speed;
  hcan.Init.Mode = mode;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_8TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_1TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = DISABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  
  return HAL_CAN_Init(&hcan);

}
HAL_StatusTypeDef SimpleCan::begin(){
    return HAL_CAN_Start(&hcan);

}
HAL_StatusTypeDef SimpleCan::stop(){
   	return HAL_CAN_Stop(&hcan);

}
HAL_StatusTypeDef SimpleCan::configFilter(CAN_FilterTypeDef *filterDef){

    // Default filter - accept all to CAN_FIFO*
    CAN_FilterTypeDef sFilterConfig;
    sFilterConfig.FilterBank = 0;
    sFilterConfig.FilterIdHigh = 0x00005;
    sFilterConfig.FilterBank = 0x0000;
    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
    sFilterConfig.FilterIdHigh = 0x00 ;  // HE TOCADO ESTO !!!!!!!
    sFilterConfig.FilterIdLow  = 0x0000;
    sFilterConfig.FilterMaskIdHigh = 0x0000;
    sFilterConfig.FilterMaskIdLow = 0x0000;
    sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
    sFilterConfig.FilterActivation = ENABLE;

    return HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
}
HAL_StatusTypeDef SimpleCan::configSnniferFilter(){

    // Default filter - accept all to CAN_FIFO*
	  CAN_FilterTypeDef sFilterConfig;
	  sFilterConfig.FilterBank = 0;
	  sFilterConfig.FilterIdHigh = 0x00005;
	  sFilterConfig.FilterBank = 0x0000;
	  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
	  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
	  sFilterConfig.FilterIdHigh = 0x200 << 5;  //11-bit ID, in top bits
	  sFilterConfig.FilterIdLow  = 0x0000;
	  sFilterConfig.FilterMaskIdHigh = 0x0000;
	  sFilterConfig.FilterMaskIdLow = 0x0000;
	  sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
	  sFilterConfig.FilterActivation = ENABLE;

    return HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
}

HAL_StatusTypeDef SimpleCan::send(CanMessage message){
	uint32_t TxMailbox;
	CAN_TxHeaderTypeDef pHeader;
    pHeader.DLC= message.dlc;
    message.isStandard ? pHeader.IDE=CAN_ID_STD : pHeader.IDE=CAN_ID_EXT;
    message.isRTR ?  pHeader.RTR=CAN_RTR_REMOTE : pHeader.RTR=CAN_RTR_DATA;
    message.isStandard ? pHeader.StdId=0x200 : pHeader.ExtId=0x200;

    return HAL_CAN_AddTxMessage(&hcan, &pHeader, (uint8_t*)message.data, &TxMailbox);
}


HAL_StatusTypeDef SimpleCan::activateNotification( /*RxHandler *rxHandler*/)
{/*
    
	if (_rxHandler != NULL)
	{
		return HAL_ERROR;
	}
	_rxHandler = rxHandler;
    */
	return HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
}

HAL_StatusTypeDef SimpleCan::deactivateNotification(){
   // _rxHandler = NULL;
    return HAL_CAN_DeactivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
}
//       RxHandler   Implementation
/*
SimpleCan::RxHandler::RxHandler(uint16_t dataLength, void (*callback)(CAN_RxHeaderTypeDef, uint8_t *))
{
	_rxData = new byte[dataLength];
	_callback = callback;
}
SimpleCan::RxHandler::~RxHandler()
{
	delete[] _rxData;
}


void SimpleCan::RxHandler::notify(CAN_HandleTypeDef *hcan1)
{

    if (SimpleCan::_rxHandler == NULL)
    {
        return;
    }
    SimpleCan::_rxHandler->notify(hcan1);
}
*/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
   digitalToggle(PC13);
/*
    if (SimpleCan::_rxHandler == NULL)
    {
        return;
    }
    SimpleCan:_rxHandler->notify(hcan1);
*/
}
Test.cpp

Code: Select all

#include <Arduino.h>
#include "stm32f4xx_hal_can.h"
#include <SimpleCan.h>

// This SystemClock_Config  is copy&paste from CubeIDE
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  // Configure the main internal regulator output voltage
  //
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  // Initializes the RCC Oscillators according to the specified parameters
  // in the RCC_OscInitTypeDef structure.
  //
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 100;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  // Initializes the CPU, AHB and APB buses clocks

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  {
    Error_Handler();
  }
}
/*
static void handleCanMessage(CAN_RxHeaderTypeDef rxHeader, uint8_t *rxData)
{
	digitalToggle(PC13);
}

SimpleCan::RxHandler can1RxHandler(8, handleCanMessage);
*/
SimpleCan can;


void setup() {
    Serial1.begin(115200);
    pinMode(PC13,OUTPUT);
    can.init(Kbit250,LoopBackCAN);
    can.configSnniferFilter();
    can.activateNotification( /*&can1RxHandler*/);
    can.begin();
   

}
void loop() {
  Serial1.println("Hola Can !!!");
  //digitalToggle(PC13);
  CanMessage  msg = createMessage();
  can.send(msg);
  delay(10);
}

platformio.ini

Code: Select all

[env:genericSTM32F405RG]
platform = ststm32
board = genericSTM32F405RG
board_build.f_cpu = 100000000L
framework = arduino
debug_tool = stlink
upload_protocol = stlink
build_flags =
-D HSE_VALUE=8000000

-D HAVE_HWSERIAL1

-D PIN_WIRE_SDA=PB11
-D PIN_WIRE_SCL=PB10

-D PIN_SPI_MOSI=PA7
-D PIN_SPI_MISO=PA6
-D PIN_SPI_SCK=PA5
-D PIN_SPI_SS=PA4

-D HAL_CAN_MODULE_ENABLED
monitor_speed = 115200
lib_deps =
askuric/Simple FOC@^2.0.2
Wire
SPI
User avatar
fpiSTM
Posts: 1751
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: HAL wrapper library crashes due to interrupt issue

Post by fpiSTM »

You could have a look to STM32CubeF4 example.
https://github.com/STMicroelectronics/S ... mples/CAN/
Maybe you will find the issue looking at the code.

In a general way if you have an unexpected exception it is probably because the interrupt has no handler so by default it ends here.
JorgeMaker
Posts: 2
Joined: Wed Feb 10, 2021 11:15 pm

Re: HAL wrapper library crashes due to interrupt issue

Post by JorgeMaker »

I have implemented the corresponding HAL_CAN_RxFifo0MsgPendingCallback function but by any unknown reason when notification is activated it crashes going to an infinite loop.
Post Reply

Return to “General discussion”