Skip to main content
Graduate II
May 21, 2024
Question

Trouble with CAN Interrupt and Free RTOS

  • May 21, 2024
  • 1 reply
  • 2394 views

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.

    This topic has been closed for replies.

    1 reply

    Technical Moderator
    May 21, 2024

    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 ..

    Graduate II
    May 21, 2024
    /**
     ******************************************************************************
     * @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 */
     }
    }

     

    Technical Moderator
    May 21, 2024

    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.