You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current CAN peripheral and shared classes have three major drawbacks:
Not interrupt based - messages are not handled upon arrival, rather upon manual request.
Single message capacity at the bus level - old messages are lost and the latest message can be "read" multiple times. This prevents us from using CAN for one-off messages like button signals. Decided to stay with single message capacity as it simplifies the Bus. We will architect our systems to handle messages as they arrive. See discussion CAN Architecture Update #274.
No filtering: the stm32 platform has a hardware CAN message filter which can ignore ranges of message IDs. Without filtering, our ECUs will be bogged down handling unrelated messages. Undecided how this will look, will implement filters later.
In particular, the current implementation freezes an ECU if it does not read all messages which arrive on the STM platform. This manifested in the TMS code freezing, and the root cause was the CAN_IT_RX_FIFO0_MSG_PENDING interrupt being triggered by BMS->FC CAN traffic (unrelated to the TMS). Since the TMS does not need to read these messages, it never called HAL_CAN_GetRxMessage(), so the interrupt continuously triggered preventing the program from continuing.
My initial idea is to enable filtering for ranges of messages (perhaps autogenerated from the DBC if possible) then trigger the HAL_CAN_GetRxMessage() in the CAN_IT_RX_FIFO0_MSG_PENDING interrupt. This will place the incoming message into a queue with all other messages of the same ID. The main program can pop elements from this queue when it wants to "read" that message. Using a queue ensures that no messages are missed, and we can intelligently raise an error if the queue becomes too full (i.e. a message is being sent to us but we aren't handling it). There isn't a great way to raise errors from an interrupt since the function has no caller (can't throw or return an error to anyone else). How would we decide whether to discard the oldest or incoming message? How big would the message queue be? Should it be FIFO or LIFO?
We will use a single message bucket for each RX message. It will always hold the latest message, so the old one will be discarded. This is ideal for measurement messages (like Accumulator Temp) since we only care about the value now. It is not ideal for event messages where the sender expects the receiver to respond to each and every message without dropping any. Instead of overcoming this issue with a queue at the CAN level, the application will decide how to handle it. They may choose to make an app-side queue for this message, or coordinate the nodes such that new events are not sent until the old one is acknowledged.
The text was updated successfully, but these errors were encountered:
Edit see #274
The current CAN peripheral and shared classes have three major drawbacks:
Not interrupt based - messages are not handled upon arrival, rather upon manual request.
Single message capacity at the bus level - old messages are lost and the latest message can be "read" multiple times. This prevents us from using CAN for one-off messages like button signals.Decided to stay with single message capacity as it simplifies the Bus. We will architect our systems to handle messages as they arrive. See discussion CAN Architecture Update #274.No filtering: theUndecided how this will look, will implement filters later.stm32
platform has a hardware CAN message filter which can ignore ranges of message IDs. Without filtering, our ECUs will be bogged down handling unrelated messages.In particular, the current implementation freezes an ECU if it does not read all messages which arrive on the STM platform. This manifested in the TMS code freezing, and the root cause was the
CAN_IT_RX_FIFO0_MSG_PENDING
interrupt being triggered by BMS->FC CAN traffic (unrelated to the TMS). Since the TMS does not need to read these messages, it never calledHAL_CAN_GetRxMessage()
, so the interrupt continuously triggered preventing the program from continuing.My initial idea is to enable filtering for ranges of messages (perhaps autogenerated from the DBC if possible) then trigger the
HAL_CAN_GetRxMessage()
in theCAN_IT_RX_FIFO0_MSG_PENDING
interrupt.This will place the incoming message into a queue with all other messages of the same ID. The main program can pop elements from this queue when it wants to "read" that message. Using a queue ensures that no messages are missed, and we can intelligently raise an error if the queue becomes too full (i.e. a message is being sent to us but we aren't handling it).There isn't a great way to raise errors from an interrupt since the function has no caller (can't throw or return an error to anyone else). How would we decide whether to discard the oldest or incoming message? How big would the message queue be? Should it be FIFO or LIFO?We will use a single message bucket for each RX message. It will always hold the latest message, so the old one will be discarded. This is ideal for measurement messages (like Accumulator Temp) since we only care about the value now. It is not ideal for event messages where the sender expects the receiver to respond to each and every message without dropping any. Instead of overcoming this issue with a queue at the CAN level, the application will decide how to handle it. They may choose to make an app-side queue for this message, or coordinate the nodes such that new events are not sent until the old one is acknowledged.
The text was updated successfully, but these errors were encountered: