arduino / arduino/ArduinoCore-renesas
Arduino_CAN library: Calling `if (CAN1.available())` causes message loss on the other interface
- Dominant language
- C
- Stars
- 193
- Forks
- 112
- PR merge metrics
- No merged PRs in 30d
Description
### **Summary**
On the Portenta C33 using the Arduino_CAN library, calling `read()` on the *other* CAN interface causes intermittent message loss.
This happens **regardless of which interface is CAN0 or CAN1**.
- If I read from **CAN1**, then **CAN** (CAN0) drops messages.
- If I swap the wiring and read from **CAN**, then **CAN1** drops messages.
This indicates that reading from one CAN interface interferes with the receive handling of the other interface.
---
### **Environment**
- Board: **Portenta C33**
- Library: **Arduino_CAN**
- Bitrate: **500 kbps**
- Both CAN interfaces enabled: `CAN` and `CAN1`
- Arduino Renesas Portenta Boards version: 1.5.3
- Arduino IDE version: 2.3.8
---
### **Sender Code**
```cpp
#include
static uint32_t const CAN_ID = 0x20;
void setup() {
Serial.begin(115200);
CAN.begin(CanBitRate::BR_500k);
}
static uint32_t msg_cnt = 0;
void loop() {
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("R4 sent:");
Serial.println(msg);
if (int const rc = CAN.write(msg); rc < 0) {
Serial.print("CAN.write(...) failed with error code ");
Serial.println(rc);
for (;;) {}
}
msg_cnt++;
delay(3000);
}
```
### **Sender Log (Correct)**
Messages increment normally:
```
16:06:19.417 -> R4 sent:[020] (8) : CAFE000001000000
16:06:22.387 -> R4 sent:[020] (8) : CAFE000002000000
16:06:25.405 -> R4 sent:[020] (8) : CAFE000003000000
16:06:28.417 -> R4 sent:[020] (8) : CAFE000004000000
16:06:31.427 -> R4 sent:[020] (8) : CAFE000005000000
16:06:34.425 -> R4 sent:[020] (8) : CAFE000006000000
16:06:37.420 -> R4 sent:[020] (8) : CAFE000007000000
16:06:40.420 -> R4 sent:[020] (8) : CAFE000008000000
16:06:43.431 -> R4 sent:[020] (8) : CAFE000009000000
16:06:46.417 -> R4 sent:[020] (8) : CAFE00000A000000
16:06:49.434 -> R4 sent:[020] (8) : CAFE00000B000000
16:06:52.448 -> R4 sent:[020] (8) : CAFE00000C000000
16:06:55.431 -> R4 sent:[020] (8) : CAFE00000D000000
16:06:58.455 -> R4 sent:[020] (8) : CAFE00000E000000
16:07:01.407 -> R4 sent:[020] (8) : CAFE00000F000000
```
---
### **Receiver Code**
```cpp
#include
void setup() {
Serial.begin(115200);
CAN.begin(CanBitRate::BR_500k);
CAN1.begin(CanBitRate::BR_500k);
}
void loop() {
// CAN0
if (CAN.available()) {
CanMsg const msgR0 = CAN.read();
Serial.print("C33 got");
Serial.println(msgR0);
}
// CAN1
if (CAN1.available()) {
CanMsg const msgR1 = CAN1.read();
}
}
```
---
### **Receiver Log (Problem)**
Only some messages are received:
```
16:06:16.446 -> C33 got[020] (8) : CAFE000000000000
16:06:19.417 -> C33 got[020] (8) : CAFE000001000000
16:06:28.417 -> C33 got[020] (8) : CAFE000004000000
16:06:31.427 -> C33 got[020] (8) : CAFE000005000000
16:06:34.425 -> C33 got[020] (8) : CAFE000006000000
16:06:46.418 -> C33 got[020] (8) : CAFE00000A000000
16:06:52.448 -> C33 got[020] (8) : CAFE00000C000000
16:06:55.431 -> C33 got[020] (8) : CAFE00000D000000
16:07:01.442 -> C33 got[020] (8) : CAFE00000F000000
```
Several messages (0x02, 0x03, 0x07, 0x08, 0x09, 0x0B, etc.) are missing.
---
### **Critical Observation**
If I comment out the CAN1 read block:
```cpp
// if (CAN1.available()) {
// CanMsg const msgR1 = CAN1.read();
// }
```
Then **CAN receives 100% of messages with no loss**.
---
### **Additional Important Finding**
Even if I **swap the roles of CAN and CAN1**, the same issue occurs:
- If I receive on **CAN1** and call `read()` on **CAN**,
→ **CAN1** starts dropping messages.
So the issue is **not tied to a specific hardware interface**.
It appears that **reading from one interface disrupts the other interface’s receive handling**.
---
### **Expected Behavior**
- Each CAN interface should operate independently.
- Reading from one interface should not affect the other.
- No message loss should occur on an idle bus.
### **Actual Behavior**
- Calling `read()` on the unused CAN interface causes message loss on the active interface.
- Removing the `read()` call restores perfect reception.
---
### **Notes**
- Both CAN buses run at 500 kbps.
- The issue occurs even when **no messages are sent to the second interface**.
- This strongly suggests a driver-level issue (interrupt handling, shared buffer, or concurrency bug).
---
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reproducing the issue with the provided Portenta C33 receiver using both CAN.available()/read() paths, then inspect the Arduino_CAN receive handling for CAN and CAN1. The work is done when reading either interface leaves the other interface receiving all messages without loss, including when the interface roles are swapped.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- arduino, cpp
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100