Introduction
If you are considering adding Ethernet (10BASE-T) Raspberry Pi interface board to your Raspberry Pi Zero there are several available options based on the Microchip Enc28j60 chip (With the term Raspberry Pi interface board we refer to board with a compatible 2x20 connector and business card form factor, that matches the mechanical dimensions of a Raspberry Pi processor board while a hat is a smaller sized board that lacks the front panel section of the raised connectors e.g. Ethernet and USB). Lightside Instruments AS designed and produced one too. The ethernet4pi board is opensource-hardware (OSHWA UID: NO000004) designed with KiCAD.
The form factor used is of a Raspberry Pi 4B and has a USB-C connector for powering the board with a USB-C cable.
The board can be ordered on Amazon https://www.amazon.com/dp/B0C9DJX8KG
You can use this board also with Raspberry Pi 2-4 as a secondary interface (eth1).
This article contains 1: instructions to enable the board (identical to every other alternative based on the dtoverlay=enc28j60) and 2: benchmark reports
* iperf3 UDP benchmark Tx/Rx directions
* RFC2544 benchmark Rx direction
InstallationIn order to load the board driver you have to add the following line to your /boot/config.txt:
dtoverlay=enc28j60
Then reboot. Check that eth0 is listed as available interface:
pi@raspberrypi:~ $ ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether b8:27:eb:74:8b:d7 brd ff:ff:ff:ff:ff:ff
inet 192.168.14.19/24 brd 192.168.14.255 scope global dynamic noprefixroute wlan0
valid_lft 559sec preferred_lft 484sec
inet6 fe80::b55a:bf34:435d:8ece/64 scope link
valid_lft forever preferred_lft forever
3: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether b6:81:bc:19:fe:fe brd ff:ff:ff:ff:ff:ff
inet 10.0.0.2/8 brd 10.255.255.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
pi@raspberrypi:~ $
TestingWe wanted to better document the performance and behavior of the enc28j60 chip and the linux driver part of the Raspberry distribution. We did not find any benchmark reports so we established a repository. We added benchmark reports for iperf3 (UDP Rx and Tx) and a RFC2544 benchmark report for the Rx direction.
In summary there seems to be a 14% packet loss when the enc28j60 is receiving a 100% 10BASE-T throughput load and the maximum transmit speed is 45%.
For both tests we used the maximum Ethernet packet size of 1514 octets.
Below are the detailed reports.
Raspberry Pi running iperf3 server:Here is how we ran the iperf3 tests. First you need to start the server on the Pi Zero:
pi@raspberrypi:~ $ sudo ip addr add 10.0.0.2/24 dev eth0
pi@raspberrypi:~ $ iperf3 -s
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
UDP benchmark with iperf3 client:- PC sending:
user@pc:~/lsi/code/iperf$ ./src/.libs/iperf3 -u -c 10.0.0.2 -b 10000000 -t 10 -l 1472
warning: UDP block size 1472 exceeds TCP MSS 1448, may result in fragmentation / drops
Connecting to host 10.0.0.2, port 5201
[ 5] local 10.0.0.1 port 35534 connected to 10.0.0.2 port 5201
[ ID] Interval Transfer Bitrate Total Datagrams
[ 5] 0.00-1.00 sec 1.19 MBytes 10.0 Mbits/sec 849
[ 5] 1.00-2.00 sec 1.16 MBytes 9.75 Mbits/sec 828
[ 5] 2.00-3.00 sec 1.14 MBytes 9.57 Mbits/sec 813
[ 5] 3.00-4.00 sec 1.14 MBytes 9.57 Mbits/sec 813
[ 5] 4.00-5.00 sec 1.14 MBytes 9.56 Mbits/sec 812
[ 5] 5.00-6.00 sec 1.14 MBytes 9.57 Mbits/sec 813
[ 5] 6.00-7.00 sec 1.14 MBytes 9.57 Mbits/sec 813
[ 5] 7.00-8.00 sec 1.14 MBytes 9.58 Mbits/sec 813
[ 5] 8.00-9.00 sec 1.14 MBytes 9.56 Mbits/sec 812
[ 5] 9.00-10.00 sec 1.14 MBytes 9.57 Mbits/sec 813
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Jitter Lost/Total Datagrams
[ 5] 0.00-10.00 sec 11.5 MBytes 9.63 Mbits/sec 0.000 ms 0/8179 (0%) sender
[ 5] 0.00-10.11 sec 9.92 MBytes 8.23 Mbits/sec 0.357 ms 1111/8179 (14%) receiver
iperf Done.
- PC receiving:
user@pc:~/lsi/code/iperf$ ./src/.libs/iperf3 -u -c 10.0.0.2 -b 10000000 -t 10 -l 1472 --reverse
warning: UDP block size 1472 exceeds TCP MSS 1448, may result in fragmentation / drops
Connecting to host 10.0.0.2, port 5201
Reverse mode, remote host 10.0.0.2 is sending
[ 5] local 10.0.0.1 port 52621 connected to 10.0.0.2 port 5201
[ ID] Interval Transfer Bitrate Jitter Lost/Total Datagrams
[ 5] 0.00-1.00 sec 591 KBytes 4.84 Mbits/sec 0.132 ms 0/411 (0%)
[ 5] 1.00-2.00 sec 543 KBytes 4.45 Mbits/sec 0.123 ms 0/378 (0%)
[ 5] 2.00-3.00 sec 545 KBytes 4.46 Mbits/sec 0.153 ms 0/379 (0%)
[ 5] 3.00-4.00 sec 543 KBytes 4.45 Mbits/sec 0.107 ms 0/378 (0%)
[ 5] 4.00-5.00 sec 543 KBytes 4.45 Mbits/sec 0.127 ms 0/378 (0%)
[ 5] 5.00-6.00 sec 543 KBytes 4.45 Mbits/sec 0.150 ms 0/378 (0%)
[ 5] 6.00-7.00 sec 543 KBytes 4.45 Mbits/sec 0.159 ms 0/378 (0%)
[ 5] 7.00-8.00 sec 543 KBytes 4.45 Mbits/sec 0.166 ms 0/378 (0%)
[ 5] 8.00-9.00 sec 543 KBytes 4.45 Mbits/sec 0.137 ms 0/378 (0%)
[ 5] 9.00-10.00 sec 543 KBytes 4.45 Mbits/sec 0.141 ms 0/378 (0%)
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Jitter Lost/Total Datagrams
[ 5] 0.00-10.10 sec 5.41 MBytes 4.50 Mbits/sec 0.000 ms 0/3856 (0%) sender
[ 5] 0.00-10.00 sec 5.35 MBytes 4.49 Mbits/sec 0.141 ms 0/3814 (0%) receiver
iperf Done.
RFC2544 benchmarkThe RFC2544 is the ultimate packet switched network interconnect device benchmark. We used a hardware implementation for the transmitter interface and a software implementation for the receiver side running on the Pi Zero (details). The latency section is to be ignored since we did not enable any synchronization method:
root@raspberrypi:~/rfc2544-benchmark/example# ../rfc2544-benchmark --config=config2.xml --dst-node=ethernet4pizero --dst-node-interface=eth0 --src-node=tester0 --src-node-interface=eth0 --dst-mac-address="FE:6B:A8:BE:3B:C3" --src-mac-address="70:B3:D5:EC:20:00" --dst-ipv4-address="10.0.0.2" --src-ipv4-udp-port=49184 --src-ipv4-address="10.0.0.139" --frame-size=1500 --trial-time=2 --speed=1000000000 | tee log.txt | grep "^#"
#===Throughput===
#1 82236.842105 pps, 20 octets interframe gap, 100.00% ... 1569 / 164473
#2 41118.421053 pps, 1540 octets interframe gap, 50.00% ... 1559 / 82236
#3 20559.210526 pps, 4580 octets interframe gap, 25.00% ... 1383 / 41118
#4 10279.605263 pps, 10660 octets interframe gap, 12.50% ... 1384 / 20559
#5 5140.225347 pps, 22818 octets interframe gap, 6.25% ... 1385 / 10280
#6 2570.588356 pps, 47127 octets interframe gap, 3.13% ... 1398 / 5141
#7 1285.783351 pps, 95717 octets interframe gap, 1.56% ... 1383 / 2571
#8 643.391341 pps, 192783 octets interframe gap, 0.78% ... 1220 / 1286
#9 322.194843 pps, 386464 octets interframe gap, 0.39% ... 644 / 644
#10 482.791384 pps, 257411 octets interframe gap, 0.59% ... 946 / 965
#11 402.492232 pps, 309065 octets interframe gap, 0.49% ... 804 / 804
#12 442.640831 pps, 280896 octets interframe gap, 0.54% ... 881 / 885
#13 422.565684 pps, 294312 octets interframe gap, 0.51% ... 843 / 845
#14 412.527639 pps, 301510 octets interframe gap, 0.50% ... 824 / 825
#15 407.509919 pps, 305241 octets interframe gap, 0.50% ... 814 / 815
#16 404.999968 pps, 307142 octets interframe gap, 0.49% ... 808 / 809
#17 403.745466 pps, 308101 octets interframe gap, 0.49% ... 806 / 807
#18 403.117875 pps, 308583 octets interframe gap, 0.49% ... 803 / 806
#19 402.804810 pps, 308824 octets interframe gap, 0.49% ... 805 / 805
#20 402.960632 pps, 308704 octets interframe gap, 0.49% ... 805 / 805
#21 403.038589 pps, 308644 octets interframe gap, 0.49% ... 805 / 806
#22 402.999607 pps, 308674 octets interframe gap, 0.49% ... 803 / 805
#23 402.980119 pps, 308689 octets interframe gap, 0.49% ... 803 / 805
#24 402.969726 pps, 308697 octets interframe gap, 0.49% ... 804 / 805
#25 402.964529 pps, 308701 octets interframe gap, 0.49% ... 804 / 805
#26 402.961931 pps, 308703 octets interframe gap, 0.49% ... 802 / 805
#27 402.960632 pps, 308704 octets interframe gap, 0.49% ... 805 / 805
#Result: 402.960632 pps
#===Latency===
#Measurement style - bit forwarding
#1 0 ns (min=0 ns, max=0 ns) ... 803 / 805
#2 0 ns (min=0 ns, max=0 ns) ... 804 / 805
#3 0 ns (min=0 ns, max=0 ns) ... 804 / 805
#4 0 ns (min=0 ns, max=0 ns) ... 805 / 805
#5 0 ns (min=0 ns, max=0 ns) ... 804 / 805
#6 0 ns (min=0 ns, max=0 ns) ... 805 / 805
#7 0 ns (min=0 ns, max=0 ns) ... 802 / 805
#8 0 ns (min=0 ns, max=0 ns) ... 802 / 805
#9 0 ns (min=0 ns, max=0 ns) ... 805 / 805
#10 0 ns (min=0 ns, max=0 ns) ... 804 / 805
#11 0 ns (min=0 ns, max=0 ns) ... 804 / 805
#12 0 ns (min=0 ns, max=0 ns) ... 803 / 805
#13 0 ns (min=0 ns, max=0 ns) ... 804 / 805
#14 0 ns (min=0 ns, max=0 ns) ... 804 / 805
#15 0 ns (min=0 ns, max=0 ns) ... 805 / 805
#16 0 ns (min=0 ns, max=0 ns) ... 804 / 805
#17 0 ns (min=0 ns, max=0 ns) ... 804 / 805
#18 0 ns (min=0 ns, max=0 ns) ... 803 / 805
#19 0 ns (min=0 ns, max=0 ns) ... 805 / 805
#20 0 ns (min=0 ns, max=0 ns) ... 802 / 805
#Result: 0.000000 nanoseconds
#===Frame loss rate===
#1 100% rate, 99% loss, (100.000000% rate actual), 82236.842105 pps (82236.842105 pps actual), 20 octets interframe gap ... 1382 / 164473
#2 90% rate, 99% loss, (89.994079% rate actual), 74013.157895 pps (74008.288928 pps actual), 189 octets interframe gap ... 1386 / 148016
#3 80% rate, 98% loss, (80.000000% rate actual), 65789.473684 pps (65789.473684 pps actual), 400 octets interframe gap ... 1389 / 131578
#4 70% rate, 98% loss, (69.981584% rate actual), 57565.789474 pps (57550.644567 pps actual), 672 octets interframe gap ... 1383 / 115101
#5 60% rate, 98% loss, (59.984215% rate actual), 49342.105263 pps (49329.123915 pps actual), 1034 octets interframe gap ... 1383 / 98658
#6 50% rate, 98% loss, (50.000000% rate actual), 41118.421053 pps (41118.421053 pps actual), 1540 octets interframe gap ... 1391 / 82236
#7 39% rate, 97% loss, (39.989476% rate actual), 32894.736842 pps (32886.082610 pps actual), 2301 octets interframe gap ... 1390 / 65772
#8 29% rate, 97% loss, (29.998026% rate actual), 24671.052632 pps (24669.429643 pps actual), 3567 octets interframe gap ... 1383 / 49338
#9 19% rate, 95% loss, (20.000000% rate actual), 16447.368421 pps (16447.368421 pps actual), 6100 octets interframe gap ... 1391 / 32894
#10 9% rate, 91% loss, (9.999342% rate actual), 8223.684211 pps (8223.143214 pps actual), 13701 octets interframe gap ... 1386 / 16446
#===Back to back frames===
#1 2 back-to-back frames ... 2 / 2
#2 4 back-to-back frames ... 4 / 4
#3 8 back-to-back frames ... 8 / 8
#4 16 back-to-back frames ... 16 / 16
#5 32 back-to-back frames ... 32 / 32
#6 64 back-to-back frames ... 41 / 64
#7 48 back-to-back frames ... 41 / 48
#8 40 back-to-back frames ... 39 / 40
#9 36 back-to-back frames ... 34 / 36
#10 34 back-to-back frames ... 34 / 34
#11 35 back-to-back frames ... 33 / 35
#Result: 34
#===System recovery===
#TODO
#===Reset===
#TODO
- Raspberry Pi Zero sending Tester receiving: N.A.
One convenient solution is to use the ethernet4pizero board as a base board and not as a mezzanine. For this you need to solder the 20x2 header yourself so that your Pi Zero has a stacking connector e.g. https://www.adafruit.com/product/2223 instead of a male only connector while the ethernet4pi stacking connector is replaced with a regular 20x2 pin header. Then you can seamlessly reuse Raspberry Pi 4B intended enclosures without modification (obviously the micro SD card location is not the same and the height due to the stacked Raspberry Pi Zero is different).
Using spi0 with CE1 instead of CE0If you want to use the hat with another SPI device you can use the jumper and select CE1 instead of the default CE0. This requires you to change the enc28j60-overlay.dts rename, compile and copy to the overlay folder and load that overlay instead:
pi@raspberrypi:~ $ diff enc28j60-overlay.dts enc28j60-ce1-overlay.dts
19c19
< reg = <0>; /* CE0 */
---
> reg = <1>; /* CE1 */
pi@raspberrypi:~ $ dtc -@ -I dts -O dtb -o enc28j60-ce1.dtbo enc28j60-ce1-overlay.dts
pi@raspberrypi:~ $ sudo cp enc28j60-ce1.dtbo /boot/overlays/
Edit /boot/firmware/config.txt dtoverlay=enc28j60
-> dtoverlay=enc28j60-ce1
Reboot.
Comments