Enhance Real-Time Performance for High-Frequency CANFD over UDP Use Case (with TSN + PREEMPT_RT)
Hi, thanks for the great work on cannelloni. I'm currently exploring its use in a real-time teleoperation system for remote robots, and I’d like to discuss a proposal to improve its real-time performance under high-frequency communication loads.
🎯 Objective Enhance the real-time determinism of cannelloni in high-frequency CANFD-over-Ethernet use cases, approaching EtherCAT-like performance levels.
✅ Target Use Case Application: Real-time remote robot control
Transport: UDP over Time Sensitive Networking (TSN)
CAN: CAN FD
Requirements: Deterministic latency with low jitter, high reliability (low packet loss), and fast response cycle (sub-millisecond)
🧩 Rationale & Observations TSN ensures low network congestion and near-zero UDP packet loss (barring extreme electromagnetic interference or hardware faults).
By eliminating network-level uncertainty, focus shifts to optimizing the software stack for real-time determinism.
🛠 Software Real-Time Strategy We are experimenting with the following Linux system configuration:
Kernel: PREEMPT_RT patched Linux
Scheduling:
Real-time priority: 99
Scheduling policy: SCHED_FIFO
CPU affinity: Isolate dedicated CPU cores for the process
Memory locking: mlockall(MCL_CURRENT | MCL_FUTURE) to prevent paging
Result: Achieved latency jitter below 100µs in controlled environments
🧪 Initial Findings Using the above setup on both cannelloni server and client, we are observing:
Improved determinism in CAN-to-Ethernet cycle timing
Substantially reduced risk of buffer overflows and packet delays
Good alignment with cyclic control loop execution in our robot controller
💬 Discussion Points Add some optionals for realtime config to enable RT scheduling, CPU affinity, memory locking, etc.
Looking forward to your feedback and happy to contribute code if this direction makes sense!
I have forked the repository and submitted a commit that adds initial support for real-time performance tuning. The changes introduce two new command-line options:
✅ New Features: -a <cpu_id>: Set CPU affinity using pthread_setaffinity_np() to bind the process to a specific core.
-y
🔧 Additional Enhancements: Enabled memory locking using mlockall(MCL_CURRENT | MCL_FUTURE) to prevent paging delays.
Updated usage() help text with the new options.
Validated and gracefully handled error cases (e.g., invalid CPU core or priority range).
These additions are meant to enable deterministic timing and reduce latency jitter in time-sensitive CANFD-over-UDP applications, especially when used in combination with TSN and a PREEMPT_RT Linux kernel.
Looking forward to any feedback or suggestions you might have. I’m happy to revise the patch or extend it further if needed!
https://github.com/maxwelllls/cannelloni/commit/57778c36c894a27840ed0e83bc92f5e0e9bbcc6f