Skip to main content
Rob Ashworth
Senior
October 24, 2025
Solved

Azure RTOS prevents CAN Interrupts

  • October 24, 2025
  • 1 reply
  • 230 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;
}

 

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.1
mbarg.1Best answer
Senior III
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.

 

Rob Ashworth
Senior
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 

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