Skip to main content
Graduate II
October 24, 2025
Solved

Azure RTOS prevents CAN Interrupts

  • October 24, 2025
  • 1 reply
  • 229 views

I am running an application with Azure RTOS, and CAN bus.  All was well until I needed to increase the tick time to 2000/second (from 1000/second).  When I did this the CAN Interrupts stop working. To make things even worse, when I change the tick time back to 1000/sec within CubeIDE, it still doesn't work and I have to pull and older version off Github to get it going again.  I'm not overly familiar with Azure RTOS, usually I just do my own OS.  CAN interrupts are priority 0, RTOS 15.  TIM6 is used for tick for RTOS.

RobAshworth_0-1761287520118.png 

CAN Initilization:

 /* Configure Rx filter */
 sFilterConfig.IdType = FDCAN_STANDARD_ID;
 sFilterConfig.FilterIndex = 0;
 // sFilterConfig.FilterType = FDCAN_FILTER_DUAL;
 sFilterConfig.FilterType = FDCAN_FILTER_MASK;//Classic filter
 sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
 sFilterConfig.FilterID1 = 0x7F1;
 sFilterConfig.FilterID2 = 0x7F1;

 if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
 {
 Error_Handler();
 }

 sFilterConfig.IdType = FDCAN_STANDARD_ID;
 sFilterConfig.FilterIndex = 1;
 // sFilterConfig.FilterType = FDCAN_FILTER_DUAL;
 sFilterConfig.FilterType = FDCAN_FILTER_MASK;//classic
 sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
 sFilterConfig.FilterID1 = 0x7F2;
 sFilterConfig.FilterID2 = 0x7F2;

 if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
 {
 /* Filter configuration Error */
 Error_Handler();
 }
 //GLobal Filter setting
 /* Configure global filter to reject all non-matching frames */
 HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE);

 //Activate the Configuration CAN reception Interrupt
 if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
 {
 /* Notification Error */
 Error_Handler();
 }

 //Activate the Configuration CAN reception Interrupt
 if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO1_NEW_MESSAGE, 0) != HAL_OK)
 {
 /* Notification Error */
 Error_Handler();
 }
 HAL_FDCAN_Start(&hfdcan1);

CAN NVIC configuration:

 /**FDCAN1 GPIO Configuration
 PA11 ------> FDCAN1_RX
 PA12 ------> FDCAN1_TX
 */
 GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN1;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 /* FDCAN1 interrupt Init */
 HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);
 HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn);

 

And Azure RTOS:

UINT App_ThreadX_Init(VOID *memory_ptr)
{
 UINT ret = TX_SUCCESS;
 /* USER CODE BEGIN App_ThreadX_MEM_POOL */
 tx_thread_create(&thread_ptr,"my_thread",my_thread_entry,0x1234,thread_stack,THREAD_STACK_SIZE,15,15,1,TX_AUTO_START);
 tx_thread_create(&thread_ptr_HK,"SlowRowThread",SlowRowThread_Entry,0x1234,thread_stack_HK,THREAD_STACK_SIZE_HK,15,14,1,TX_AUTO_START);
 /* USER CODE END App_ThreadX_MEM_POOL */
 /* USER CODE BEGIN App_ThreadX_Init */
 /* USER CODE END App_ThreadX_Init */

 return ret;
}

 

    This topic has been closed for replies.
    Best answer by mbarg.1

    Interrupts have few to share with ThreadX even if sometime ThreadX suspends interrupts but it is for few clock cycles ...

    One question: what do you expect to happen when CAN triggers IT ? Can you share code of CAN IT Callback?

    Can you share .ioc before and after can changes (both first and second) ? It seems you are cumulating some bad side effect from IDE ..

    To double ckeck IDE, change something very useless like a GPIO pin and revert - is your design back to original? can use compare files - should be identical.

     

    1 reply

    mbarg.1Answer
    Graduate
    October 24, 2025

    Interrupts have few to share with ThreadX even if sometime ThreadX suspends interrupts but it is for few clock cycles ...

    One question: what do you expect to happen when CAN triggers IT ? Can you share code of CAN IT Callback?

    Can you share .ioc before and after can changes (both first and second) ? It seems you are cumulating some bad side effect from IDE ..

    To double ckeck IDE, change something very useless like a GPIO pin and revert - is your design back to original? can use compare files - should be identical.

     

    Graduate II
    October 24, 2025

    Here is the callback for both CAN RX functions.  I will try and compare the 2 .ioc files, but not sure the best way of doing this, as not sure their the easiest of things to look at in a text editor...also the .ioc obviously modifies a lot of files in the background!

    //FIFO0 is used by customer - Period, CAN ID, System Zero, CAN-FD or Classic CAN
    void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
    {
     u16 SensorNumberCheck;
     u8 MUX;
    
     //debug message
     TxData[0]=0x05;
    // TxMsg();//debug
    
     if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
     {
     /* Retreive Rx messages from RX FIFO0 */
     if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, CANRx) != HAL_OK)
     {
     /* Reception Error */
     Error_Handler();
     }
    
     //Format of the message is:
     //BYTE 0..1 = SENSOR NUMBER U16
     //BYTE 2 = CODE CHECK1
     //BYTY 3 = CODE CHECK2
     //BYTE 4 = MUX - TYPE OF MESSAGE U8
     //BYTE 5..6 = U16 Value
     //BYTE 7..10= Floating point value - N.B. CAN-FD Only
    
     //Check the sensor number agrees
     U16Value.b[1]=CANRx[0];
     U16Value.b[0]=CANRx[1];
     SensorNumberCheck=U16Value.d;
     MUX=CANRx[4];
     //Only allow this sensor number to be updated - otherwise any other sensor on the bus will!
     if(SensorNumberCheck==Config_Msg.SENSORNO)//check whole sensor number
     {

    and so on...FIFO1 callback:

    //CANRx Interrupt processing
    void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs)
    {
     u16 SensorNumberCheck;
     u8 MUX;
    
    // HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeaderDebug, TxDataSlowRow);
     //debug message
    // TxData[0]=0x10;
     TxMsg();
    
     if((RxFifo1ITs & FDCAN_IT_RX_FIFO1_NEW_MESSAGE) != RESET)
     {
     // Retreive Rx messages from RX FIFO0 //
     if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO1, &RxHeader, CANRx) != HAL_OK)
     {
     // Reception Error //
     Error_Handler();
     }
    
     //Format of the message is:
     //BYTE 0..1 = SENSOR NUMBER U16
     //BYTE 2 = CODE CHECK1
     //BYTY 3 = CODE CHECK2
     //BYTE 4 = MUX - TYPE OF MESSAGE U8
     //BYTE 5..6 = U16 Value
     //BYTE 7..10= Floating point value
    
     

      I wil 

    ST Employee
    October 24, 2025

    Hi @Rob Ashworth 

    Try to configure ThreadX to use the BASEPRI register, as shown below:

    HaithemRahmani_0-1761293638659.png

    set the 'TX_BASEPRI_VALUE' to a value different from 0, then the CAN interrupts won't be masked.

    regards
    Haithem.