There are many discussions around klipper, serial/can/USB, and bandwidth.
My 2 cents: Real bandwidth with really loaded mcu will be around 50 Kbps.
I did write a benchmark module: GitHub - nefelim4ag/klipper at bus-benchmark
The module is python only and does not require you to update your mcu.
I just reused existing mcu functions.
So, here are the results with my thoughts.
# printer.cfg
# Linux MCU HOST working over the psuedo terminal
[bus_benchmark host]
mcu: host
# stm32h723 USB-Can emulation 1_000_000 bits
[bus_benchmark mcu]
mcu: mcu
# rp2040 USB Serial Emulation.
[bus_benchmark rp2040]
mcu: rp2040
lsusb -t
/: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci-hcd/1p, 5000M
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci-hcd/2p, 480M
|__ Port 1: Dev 12, If 0, Class=Communications, Driver=cdc_acm, 12M
|__ Port 1: Dev 12, If 1, Class=CDC Data, Driver=cdc_acm, 12M
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci-hcd/1p, 5000M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci-hcd/2p, 480M
|__ Port 1: Dev 29, If 0, Class=Vendor Specific Class, Driver=gs_usb, 12M
Linux thinks STM32 & rp2040 has 12 Mbps.
$ BUS_LATENCY MCU=host COUNT=200
// Latency: mean=0.000121020s stddev=0.000061630s
$ BUS_LATENCY MCU=mcu COUNT=200
// Latency: mean=0.000249133s stddev=0.000028107s
$ BUS_LATENCY MCU=rp2040 COUNT=200
// Latency: mean=0.000996884s stddev=0.000029622s
So, the serial is the slowest. Latency is 120 us, 250 us, 996 us.
Bandwidth
$ BUS_BANDWIDTH MCU=host COUNT=1000
// Latency: mean=0.000073312s stddev=0.000051271s
// Approximate bandwidth: 10475829.50 bps
$ BUS_BANDWIDTH MCU=mcu COUNT=1000
// Latency: mean=0.000730682s stddev=0.000053912s
// Approximate bandwidth: 1051072.65 bps
$ BUS_BANDWIDTH MCU=rp2040 COUNT=500
// Latency: mean=0.000998789s stddev=0.000063828s
// Approximate bandwidth: 768931.21 bps
nload can0
screenshot.
Linux is the fastest, as expected, around 10 Mbps.
MCU USB to CAN bus bridge got slightly higher results than expected (we have CRC overhead for Klipper serial + CAN CRC).
However, NLoad clearly shows that the USB CAN Bridge works faster than the defined 1 Mbps.
USB Serial saturates around 760 Kbps.
I did not hit CPU limit with this test, simply because of how it works.
CPU is using a āperformanceā governor during this test at 2.9 GHz.
Addressing concerns below, about count
and precision.
BUS_BANDWIDTH MCU=mcu COUNT=8
BUS_BANDWIDTH MCU=mcu COUNT=16
BUS_BANDWIDTH MCU=mcu COUNT=32
BUS_BANDWIDTH MCU=mcu COUNT=64
BUS_BANDWIDTH MCU=mcu COUNT=128
BUS_BANDWIDTH MCU=mcu COUNT=256
BUS_BANDWIDTH MCU=mcu COUNT=512
BUS_BANDWIDTH MCU=mcu COUNT=1024
BUS_BANDWIDTH MCU=mcu COUNT=2048
BUS_BANDWIDTH MCU=mcu COUNT=4096
BUS_BANDWIDTH MCU=mcu COUNT=8192
Latency: mean=0.000676792s stddev=0.000038650s
Approximate bandwidth: 1134765.61 bps
Transfered: 48 * 8 * 2 = 768.00 bytes
Latency: mean=0.000668934s stddev=0.000027414s
Approximate bandwidth: 1148095.65 bps
Transfered: 48 * 16 * 2 = 1536.00 bytes
Latency: mean=0.000669885s stddev=0.000087903s
Approximate bandwidth: 1146464.74 bps
Transfered: 48 * 32 * 2 = 3072.00 bytes
Latency: mean=0.000666482s stddev=0.000034197s
Approximate bandwidth: 1152319.49 bps
Transfered: 48 * 64 * 2 = 6144.00 bytes
Latency: mean=0.000666031s stddev=0.000030229s
Approximate bandwidth: 1153100.32 bps
Transfered: 48 * 128 * 2 = 12288.00 bytes
Latency: mean=0.000673456s stddev=0.000080476s
Approximate bandwidth: 1140386.33 bps
Transfered: 48 * 256 * 2 = 24576.00 bytes
Latency: mean=0.000675128s stddev=0.000075948s
Approximate bandwidth: 1137562.27 bps
Transfered: 48 * 512 * 2 = 49152.00 bytes
Latency: mean=0.000666847s stddev=0.000066104s
Approximate bandwidth: 1151688.84 bps
Transfered: 48 * 1024 * 2 = 98304.00 bytes
Latency: mean=0.000650181s stddev=0.000042222s
Approximate bandwidth: 1181208.94 bps
Transfered: 48 * 2048 * 2 = 196608.00 bytes
Latency: mean=0.000658150s stddev=0.000069231s
Approximate bandwidth: 1166906.72 bps
Transfered: 48 * 4096 * 2 = 393216.00 bytes
Latency: mean=0.000655775s stddev=0.000048133s
Approximate bandwidth: 1171133.33 bps
Transfered: 48 * 8192 * 2 = 786432.00 bytes
On my setup, with octopus connected to USB and working in USB CAN Bridge mode, there is no significant dependency between sample count and output.
I think anyone concerned about available bandwidth can now test that.
Hope someone finds it useful.
Thanks.