Skip to content

Possible Imperfection: CAN.write()` blocks indefinitely on Portenta C33 when no ACK is available (no opposite node / node offline / CAN disabled) #514

@hamatyo0126

Description

@hamatyo0126

Summary

On Portenta C33 (RA6M5) using the Arduino_CAN library,
CAN.write() blocks indefinitely when the opposite CAN node cannot acknowledge the frame.

This causes the entire loop() to stop permanently.
The issue occurs on both CAN0 and CAN1.

In contrast, UNO R4 Minima and UNO R4 WiFi do not show this behavior.


Environment

  • Board: Portenta C33 with Portenta Breakout (ASX00031)
  • Library: Arduino_CAN.h
  • Bitrate: 500 kbps
  • Bus configuration: Only C33 connected (no active CAN node)
  • CAN transceivers: M5Stack U085 (SN65HVD230) × 2
  • Comparison boards: UNO R4 Minima, UNO R4 WiFi
  • BOARDS MANAGER: Arduino Renesas Portenta Boards 1.5.1

Expected behavior

CAN.write() should:

  • return even when no ACK is received, or
  • provide a timeout, or
  • return an error code, or
  • expose an API to detect ACK/bus state.

This is the behavior on UNO R4 Minima and UNO R4 WiFi, where:

  • CAN.write(msg) does not block,
  • it returns an error code (e.g., rc = -60003),
  • and the loop continues running normally.

Actual behavior (Portenta C33)

CAN.write() never returns when the opposite node cannot acknowledge the frame.

The following tested scenarios all result in a permanent block:

  • Opposite node (UNO R4) powered OFF
  • Opposite node reset via reset button
  • Physical disconnection of CAN lines
  • Opposite node with CAN.begin() not executed (CAN disabled)

In all cases:

  • "Sent msg = ..." is printed
  • but "rc = CAN.write(msg)" is never printed
  • because CAN.write() never returns

Observed logs

Portenta C33 (blocks when ACK is unavailable)

Return msg = [031] (8) : CAFE0000F2000000

Sent msg = [021] (8) : CAFE0000F3000000
rc = CAN.write(msg) = 1

Return msg = [031] (8) : CAFE0000F3000000

Sent msg = [021] (8) : CAFE0000F4000000
rc = CAN.write(msg) = 1

After this point, no further logs appear because CAN.write() never returns.


UNO R4 Minima / UNO R4 WiFi (do NOT block)

Sent msg = [021] (8) : CAFE00005F010000
rc = CAN.write(msg) = -60003

Sent msg = [021] (8) : CAFE000060010000
rc = CAN.write(msg) = -60003

Sent msg = [021] (8) : CAFE000060010000
rc = CAN.write(msg) = -60003

Both boards behave identically and continue running normally.


Steps to reproduce

  1. Connect Portenta C33 to a CAN transceiver
  2. Do not connect any active CAN node
  3. Upload the sketch below
  4. Observe that CAN.write() never returns

Minimal reproducible example (Portenta C33)

Note: The exact same sketch was also tested on UNO R4 Minima and UNO R4 WiFi.
On both boards, CAN.write(msg) returned -60003 instead of blocking.

#include <Arduino_CAN.h>

static uint32_t const CAN_ID = 0x21;

unsigned long previousMillis = 0;
const long interval = 1000;

void setup()
{
  Serial.begin(115200);

  if (!CAN.begin(CanBitRate::BR_500k))
  {
    Serial.println("CAN.begin(...) failed.");
    for (;;) {}
  }

  delay(1000);
}

static uint32_t msg_cnt = 0;

void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    uint8_t const msg_data[] = {0xCA,0xFE,0,0,0,0,0,0};
    memcpy((void *)(msg_data + 4), &msg_cnt, sizeof(msg_cnt));
    CanMsg const msg(CanStandardId(CAN_ID), sizeof(msg_data), msg_data);

    Serial.print("Sent msg = ");
    Serial.println(msg);

    int rc = CAN.write(msg);
    Serial.print("rc = CAN.write(msg) = ");
    Serial.println(rc);
    Serial.println("");

    msg_cnt++;
  }

  if (CAN.available())
  {
    CanMsg msg = CAN.read();
    Serial.print("Return msg = ");
    Serial.println(msg);
    Serial.println("");
  }
}

Receiver-side code used during testing (UNO R4 Minima / UNO R4 WiFi)

#include <Arduino_CAN.h>

void setup()
{
  Serial.begin(115200);

  if (!CAN.begin(CanBitRate::BR_500k))
  {
    Serial.println("CAN.begin(...) failed.");
    for (;;) {}
  }
}

void loop()
{
  if (CAN.available())
  {
    CanMsg const rx = CAN.read();
    CanMsg tx(CanStandardId(0x31), rx.data_length, rx.data);

    delayMicroseconds(500);
    int const rc = CAN.write(tx);
  }

  delay(1);
}

Additional notes

  • Issue occurs on both CAN0 and CAN1
  • Occurs regardless of termination resistors
  • No API exists to detect ACK absence or bus state
  • UNO R4 Minima / UNO R4 WiFi do NOT block
    • both return rc = -60003 when no ACK is available
    • both continue running normally

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions