SAMV7: MCAN: Prevent Interrupt-Flooding of ACKE when not connected to CAN-BUS. An Acknowledge-Error will occur every time no other CAN Node acknowledges the message sent. This will also occur if the device is not connected to the can-bus. The CAN-Standard declares, that the Chip has to retry a given message as long as it is not sent successfully (or it is not cancelled by the application). Every time the chip tries to resend the message an Acknowledge-Error-Interrupt is generated. At high baud rates this can lead in extremely high CPU load just for handling the interrupts (and possibly the error handling in the application). To prevent this Interrupt-Flooding we disable the ACKE once it is seen as long we didn't transfer at least one message successfully.

This commit is contained in:
Frank Benkert 2016-12-13 11:22:54 -06:00 committed by Gregory Nutt
parent dae7e77d91
commit a36ed28790

View File

@ -3388,6 +3388,19 @@ static void mcan_interrupt(FAR struct can_dev_s *dev)
{
canerr("ERROR: TX %08x\n", pending & MCAN_TXERR_INTS);
/* An Acknowledge-Error will occur if for example the device
* is not connected to the bus.
*
* The CAN-Standard states that the Chip has to retry the
* message forever, which will produce an ACKE every time.
* To prevent this Interrupt-Flooding and the high CPU-Load
* we disable the ACKE here as long we didn't transfer at
* least one message successfully (see MCAN_INT_TC below).
*/
ie &= ~MCAN_INT_ACKE;
mcan_putreg(priv, SAM_MCAN_IE_OFFSET, ie);
/* Clear the error indications */
mcan_putreg(priv, SAM_MCAN_IR_OFFSET, MCAN_TXERR_INTS);
@ -3441,6 +3454,17 @@ static void mcan_interrupt(FAR struct can_dev_s *dev)
if ((pending & MCAN_INT_TC) != 0)
{
/* Check if we have disabled the ACKE in the error-handling above
* (see MCAN_TXERR_INTS) to prevent Interrupt-Flooding and
* re-enable the error interrupt here again.
*/
if ((ie & MCAN_INT_ACKE) == 0)
{
ie |= MCAN_INT_ACKE;
mcan_putreg(priv, SAM_MCAN_IE_OFFSET, ie);
}
/* Clear the pending TX completion interrupt (and all
* other TX-related interrupts)
*/