1
votes

I'm working on a project that uses the STM32 HAL drivers, and in particular the CAN driver in interrupt mode. I understand that the STM32F407xx microcontroller has three CAN transmit mailboxes, allowing users to "enqueue" three messages for transmission at a time. The HAL CAN driver however seems to return HAL_BUSY when HAL_CAN_Transmit_IT() is called rapidly, on the second call; taking a look at the source code, it looks like the function doesn't check whether any other mailboxes are empty before setting the handle status to BUSY_TX (even though another mailbox could be used for the following message), preventing a successive call from adding a message to another mailbox.

Am I missing something about the way this driver works? Has anybody run into this in the past? Any thoughts would be appreciated.

Thanks!

1

1 Answers

1
votes

Most of my STM32 work is bare-metal or with an open library, so I am not familiar with the official STM32 toolsets like cube that I assume you are using.

With that disclaimer out of the way, I think this has to do with how mailboxes are used.

In the docs for the STM32F413/423 (Section 32.3.3), it says: Three transmit mailboxes are provided to the software for setting up messages. The transmission Scheduler decides which mailbox has to be transmitted first.

In section 32.7.1, it says that mailbox priority is sent

By identifier: When more than one transmit mailbox is pending, the transmission order is given by the identifier of the message stored in the mailbox. The message with the lowest identifier value has the highest priority according to the arbitration of the CAN protocol. If the identifier values are equal, the lower mailbox number will be scheduled first.

By transmit request order: The transmit mailboxes can be configured as a transmit FIFO by setting the TXFP bit in the CAN_MCR register. In this mode the priority order is given by the transmit request order.

The effect is that if you load mailbox 0, then 1, then 2, they may complete in any order depending on the CAN id of the message. This is because CAN ids pull double roll as an 'address' and as a message priority marker. This mailbox behavior allows this prioritization to happen automatically for the programmer.

However, for most types of traffic, messages are expected to be sent in the order they were queued. Using a single mailbox prevents scrambling the order of messages.

So, maybe this is what you are seeing.