HAL wrapper library crashes due to interrupt issue
Posted: Thu Feb 11, 2021 3:32 am
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
SimpleCan.cpp
Test.cpp
platformio.ini
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
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);
*/
}
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);
}
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