Skip to main content
WTetl.2
Associate II
January 17, 2023
Solved

How to differentiate which CANBUS a message is received on using STM32F4?

  • January 17, 2023
  • 3 replies
  • 1770 views

I have an STM32F403ZH Nucleo board and it's connected to three separate CAN channels. I would like to be able to receive identical messages on any channel (same identifier, baud rate, etc) and have the microcontroller be able to determine which one it came from so it can handle it differently. This would allow my three identical devices to not have to be reprogrammed to send messages with different identifiers.

I've been looking through the reference manual and I don't think it's possible. The 3 different CAN controllers all send the same interrupt to the main controller. No trace of which CAN controller sent the interrupt or received the message is stored when the message is sent to the FIFO, or in the mailbox when the main controller receives the message from the FIFO. I could differentiate between two channels by having them output into different FIFOs, but not three. If anybody knows a way then I'd be happy to hear it. Thank you.

This topic has been closed for replies.
Best answer by Karl Yamashita

You need to compare the CAN instance

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
	if(hcan->Instance == hcan1.Instance)
	{
		if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can1_header, can1_data) != HAL_OK)
		{
			// error handler
		}
	}
	else if(hcan->Instance == hcan2.Instance)
	{
		if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can2_header, can2_data) != HAL_OK)
		{
			// error handler
		}
	}
}

3 replies

Karl Yamashita
Karl YamashitaBest answer
Principal
January 18, 2023

You need to compare the CAN instance

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
	if(hcan->Instance == hcan1.Instance)
	{
		if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can1_header, can1_data) != HAL_OK)
		{
			// error handler
		}
	}
	else if(hcan->Instance == hcan2.Instance)
	{
		if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can2_header, can2_data) != HAL_OK)
		{
			// error handler
		}
	}
}

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
WTetl.2
WTetl.2Author
Associate II
January 18, 2023

Excellent, thank you!

JPeac.1
Visitor II
January 18, 2023

At the start of the CAN RXFIFO interrupt service routine read the interrupt vector from SCB->ICSR. This will uniquely identify which CAN bus is being processed.

I don't use the HAL or Cube. I have a reentrant RXFIFO handler which services all buses and FIFOs. I use the ICSR to determine which CAN peripheral and FIFO is in use and append the information to the incoming CAN message before queueing it to be passed to the CANopen protocol stack.

Determining the bus is necessary for some CANopen 4 implementations that support redundant buses and flying bus masters.

Jack Peacock