cancel
Showing results for 
Search instead for 
Did you mean: 

Trouble with CAN Interrupt and Free RTOS

DiogoPedrosa
Associate III

I am having issues with the use of HAL_CAN_RxFifo0MsgPendingCallback. I've set every configuration (filter, start, interrupt, notification, and priority), but the function doesn't seem to be called at any time.Most of the code is generated from the cube Ide besides the implementation of the callback funtion and the filter.The filter is supposed to let every message get through.

I've tested without the interrupt with FreeRTOS, and with the interrupt without FreeRTOS, and it worked. What could I be missing? I've also tested in loopback and normal mode, but it didn't make a difference. Additionally, every other function that I created worked fine.

8 REPLIES 8
SofLit
ST Employee

Hello,

1- Could you please confirm the following:

Without FreeRTOS + Rx polling is working.
In baremetal + Rx interrupt is working.
With FreeRTOS + Rx interrup is not working.

2- If the above is confirmed, could you please share the three projects in loopback mode? Please remove all the stuff not related to the CAN+FreeRTOS: no USART no USB etc ..

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
/**
  ******************************************************************************
  * @file    can.c
  * @brief   This file provides code for the configuration
  *          of the CAN instances.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under Ultimate Liberty license
  * SLA0044, the "License"; You may not use this file except in compliance with
  * the License. You may obtain a copy of the License at:
  *                             www.st.com/SLA0044
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "can.h"

/* USER CODE BEGIN 0 */
#include "cmsis_os.h"
#include "main.h"
typedef struct {
    CAN_RxHeaderTypeDef header;
    uint8_t data[8];
} CanRx_Buffer;
osMessageQueueId_t CanRxMessagesHandle;

CAN_RxHeaderTypeDef RxHeader;
CAN_TxHeaderTypeDef TxHeader;
uint8_t rxData[8];
uint8_t txData[8];
uint32_t TxMailbox;
/* USER CODE END 0 */

CAN_HandleTypeDef hcan;

/* CAN init function */
void MX_CAN_Init(void)
{

  /* USER CODE BEGIN CAN_Init 0 */

  /* USER CODE END CAN_Init 0 */

  /* USER CODE BEGIN CAN_Init 1 */

  /* USER CODE END CAN_Init 1 */
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = 16;
  hcan.Init.Mode = CAN_MODE_LOOPBACK;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_6TQ;
  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;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN_Init 2 */

   	CAN_FilterTypeDef  sFilterConfig;

    	sFilterConfig.FilterBank = 0;
      sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
      sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
      sFilterConfig.FilterIdHigh = 0x0000;
      sFilterConfig.FilterIdLow = 0x0000;
      sFilterConfig.FilterMaskIdHigh = 0x0000;
      sFilterConfig.FilterMaskIdLow = 0x0000;
      sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
      sFilterConfig.FilterActivation = ENABLE;
      sFilterConfig.SlaveStartFilterBank = 14;

      if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
      {
        /* Filter configuration Error */
        Error_Handler();
      }
      if(HAL_CAN_Start(&hcan)){
    	  Error_Handler();
      };
      HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);

  /* USER CODE END CAN_Init 2 */

}

void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{

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

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

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**CAN GPIO Configuration
    PA11     ------> CAN_RX
    PA12     ------> CAN_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

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

  /* USER CODE END CAN1_MspInit 1 */
  }
}

void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{

  if(canHandle->Instance==CAN1)
  {
  /* USER CODE BEGIN CAN1_MspDeInit 0 */

  /* USER CODE END CAN1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_CAN1_CLK_DISABLE();

    /**CAN GPIO Configuration
    PA11     ------> CAN_RX
    PA12     ------> CAN_TX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);

    /* CAN1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
  /* USER CODE BEGIN CAN1_MspDeInit 1 */

  /* USER CODE END CAN1_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */
extern void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    CAN_RxHeaderTypeDef RxHeader;
    uint8_t RxData[8];

    if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK)
    {

        if (RxHeader.StdId == 1523)
        {
            // Process the MS3 message
            CanRx_Buffer canMessage;
            canMessage.header = RxHeader;
            memcpy(canMessage.data, RxData, sizeof(RxData));

        }
    }
}
/* USER CODE END 1 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

can.c with interrupt and freeRtos

void canRx_wwork(void *argument)
{
  /* USER CODE BEGIN canRx_wwork */
  /* Infinite loop */
  for(;;)
  {
	  TxHeader.StdId =1;
	  	 TxHeader.DLC =2;
	  	 TxHeader.IDE =CAN_ID_STD;
	  	 TxHeader.RTR = CAN_RTR_DATA;
	  	 TxHeader.TransmitGlobalTime =DISABLE;
	  	 txData[0]=20;
	  	 txData[1]=40;
	  	 HAL_CAN_AddTxMessage(&hcan, &TxHeader, txData, &TxMailbox);
    osDelay(1);
  }

freertos.c. Just adding a message to transmit and expecting it to be received in the callback 

 

Now without the interrupt ,just added the getrx(This works)

void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */


  /* Infinite loop */
  for(;;)
  {
	  HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, rxData);
    osDelay(1);
  }
  /* USER CODE END StartDefaultTask */
}

/* USER CODE BEGIN Header_canRx_wwork */
/**
* @brief Function implementing the canRx thread.
* @PAram argument: Not used
* @retval None
*/
/* USER CODE END Header_canRx_wwork */
void canRx_wwork(void *argument)
{
  /* USER CODE BEGIN canRx_wwork */
  /* Infinite loop */
  for(;;)
  {
	  TxHeader.StdId =1;
	  	 TxHeader.DLC =2;
	  	 TxHeader.IDE =CAN_ID_STD;
	  	 TxHeader.RTR = CAN_RTR_DATA;
	  	 TxHeader.TransmitGlobalTime =DISABLE;
	  	 txData[0]=20;
	  	 txData[1]=40;
	  	 HAL_CAN_AddTxMessage(&hcan, &TxHeader, txData, &TxMailbox);
    osDelay(1);
  }
  /* USER CODE END canRx_wwork */
}

And without the freertos and with interrupt(this also works)

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    CAN_RxHeaderTypeDef RxHeader;
    uint8_t RxData[8];

    if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK)
    {

        if (RxHeader.StdId == 1523)
        {
            // Process the MS3 message


        }
    }
}
while (1)
  {
    /* USER CODE END WHILE */
	  TxHeader.StdId =1;
	 	  	 TxHeader.DLC =2;
	 	  	 TxHeader.IDE =CAN_ID_STD;
	 	  	 TxHeader.RTR = CAN_RTR_DATA;
	 	  	 TxHeader.TransmitGlobalTime =DISABLE;
	 	  	 TxData[0]=20;
	 	  	 TxData[1]=40;
	 	  	 HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox);
	 		  //HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, RxData);

    /* USER CODE BEGIN 3 */
  }

 now the can.c

void MX_CAN_Init(void)
{

  /* USER CODE BEGIN CAN_Init 0 */

  /* USER CODE END CAN_Init 0 */

  /* USER CODE BEGIN CAN_Init 1 */

  /* USER CODE END CAN_Init 1 */
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = 16;
  hcan.Init.Mode = CAN_MODE_LOOPBACK;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_6TQ;
  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;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN_Init 2 */

   	CAN_FilterTypeDef  sFilterConfig;

    	sFilterConfig.FilterBank = 0;
      sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
      sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
      sFilterConfig.FilterIdHigh = 0x0000;
      sFilterConfig.FilterIdLow = 0x0000;
      sFilterConfig.FilterMaskIdHigh = 0x0000;
      sFilterConfig.FilterMaskIdLow = 0x0000;
      sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
      sFilterConfig.FilterActivation = ENABLE;
      sFilterConfig.SlaveStartFilterBank = 14;

      if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
      {
        /* Filter configuration Error */
        Error_Handler();
      }
      if(HAL_CAN_Start(&hcan)){
    	  Error_Handler();
      };
      HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
  /* USER CODE END CAN_Init 2 */

}

void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{

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

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

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**CAN GPIO Configuration
    PA11     ------> CAN_RX
    PA12     ------> CAN_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

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

  /* USER CODE END CAN1_MspInit 1 */
  }
}

 

Hello,

1- You didn't confirm the points in 1.

2- I'm wondering how it worked in one of the projects in loopback mode while Rx pin is not set to pill-up mode!

3- Better to share the projects than sharing the code in order to run them on a board.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Also Just noticed the Tx and RX pins config:

 

    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 

Mode = INPUT and not AF? it should be set to GPIO_MODE_AF_PP.

And where is GPIO_InitStruct.Alternate? is not set here neither for Tx nor Rx!

Is it fully generated by CubeMx or you inserted some changes by yourself?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

I have changed nothing in what the cubemx auto generated,only added the config filter based on an example provided by st.

I´ve managed to make it work at least in loopback,I dont know what I have changed,but in loopback is working.When I tested the communication with a automotive ECU(megasquirt 3x) and it didnt work,ive talked with others and they say it might me a problem with the ECU not the code. In my opnion if it works in loopback it should work in normal mode and any problem that I could have is hardware related,like the transceiver or the other CAN device.

Here is the code that works with the loopback.The rest of the code I havent started,so its kinda only the communication can working.

Hello,

Again you didn't confirm the fowlling:

- Without FreeRTOS + Rx polling is working.
- In baremetal + Rx interrupt is working.
- With FreeRTOS + Rx interrup is not working.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Hello,

Looking at your Clock config you seem using HSI as source for the system clock which is not recommended in the CAN communication in Normal mode and you need to use HSE with an external crystal. In loopback mode it works fine. It could be this is the reason of the issue.

So, please check this point before further analysis.

SofLit_0-1716378368976.png

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

I've changed to HSI and nothing changed,as I said it might be a hardware problem from the external ECU.

As for - Without FreeRTOS + Rx polling is working. - Yes
- In baremetal + Rx interrupt is working. -No I used HAL Library
- With FreeRTOS + Rx interrup is not working. - Yes