Ethernet

Introduction

The Pi-Tron has two ethernet ports which allows the user to have two independent network interfaces on the Pi-Tron to work with. The Raspberry Pi usually generates its MAC address from the CPU serial number automatically and adds this to the Raspberry Pi Foundation specific MAC address part, so that every Raspberry Pi on a network can be identified as such.

Every Raspberry Pi MAC address starts with B8:27:EB which allows for an easy identification of the device, however for custom designs like the Pi-Tron, it makes sense to have a different MAC address for the ethernet ports. This is achieved by "burning" a MAC address into the OTP registers 64 and 65 of the Raspberry Pi.

There is however a restriction set by the Raspberry Pi Foundation, the OTP register can only hold one MAC address for one ethernet port, but the Pi-Tron has two network interfaces. When the devices starts, the Raspberry Pi OS automatically loads the MAC address from the OTP and sets it to both ethernet ports, as there is no second MAC address. To correct this, the user has to manually intervene and change the MAC address of the second ethernet port by hand or using a script.

Note: The OTP registers of the Raspberry Pi of all models can only hold one MAC address, see the documentation at Raspberry Pi OTP Register Documentation

The ethernet ports of the Pi-Tron have the following names:

  • First ethernet port: eth0
  • Second ethernet port: eth1

Every Pi-Tron has a label which shows the two MAC addresses assigned to this device by Kontron Electronics. The label also has to barcodes or data matrix codes, which can be scanned with a smartphone for example.

Look for a label like this:

Pi-Tron MAC label example

There are two things to note: First, there is one MAC address and data matrix code on the left (bottom) and the second one is on the right (top). Second, the MAC addresses on the label have no separation, they are shown as one whole hexadecimal number. To be able to use them, they have to be brought in to the MAC address format by adding colons like this: xx:xx:xx:xx:xx:xx

Manually set MAC address

Take the second MAC address from the label and assign it to eth1 manually like this:

pi@raspberry:~ $ sudo ifconfig eth1 down
pi@raspberry:~ $ sudo ifconfig eth1 hw ether xx:xx:xx:xx:xx:xx
pi@raspberry:~ $ sudo ifconfig eth1 up

Replace the xx:xx:xx:xx:xx:xx with a real MAC address!

The MAC address of eth0 should already be set to the other MAC address on the label. Use the command ifconfig to check that now both ethernet ports have a different MAC address. This has to be done after every start of the device, which means putting this in a script can make things easier. Calling the script from the file rc.local will do the above steps automatically each time the Pi-Tron is booted or restarted.

Create a new shell script:

pi@raspberry:~ $ cd ~
pi@raspberry:~ $ nano set_mac_address.sh

Then add to the file:

#!/bin/bash

sudo ifconfig eth1 down
sudo ifconfig eth1 hw ether xx:xx:xx:xx:xx:xx
sudo ifconfig eth1 up

Replace the xx:xx:xx:xx:xx:xx with a real MAC address! Save the changes to the file and close the editor.

Make the script executable:

pi@raspberry:~ $ chmod +x set_mac_address.sh

Add it to the rc.local file:

pi@raspberry:~ $ sudo nano /etc/rc.local

Just before the line "exit 0" add the following:

sudo /home/pi/set_mac_address.sh

Save the changes, close the editor and reboot. After the reboot check the MAC addresses of eth0 and eth1 that they are different.

Generate eth1 MAC Address

Setting the MAC address of eth1 manually gives the user great control over the ethernet ports, but this procedure might be cumbersome or unusable in serial or mass production situations. In these scenarios it makes sense to generate the MAC address for eth1 from the OTP registers, by simply adding plus one (+1) to the MAC address found in the OPT registers. This also conforms to the MAC address label found on any Pi-Tron device. The second address on the label is always the first MAC address plus one (+1).

Based on this knowledge the MAC address for eth1 can be automatically generated each time the Pi-Tron boots or restarts.

Create a new script file:

pi@raspberry:~ $ cd ~
pi@raspberry:~ $ nano gen_eth1_mac.sh

Enter the following code to the file:

#!/bin/bash

# This script extracts the MAC from OTP and adds plus one (+1) to it
# and assigns this new MAC to eth1. This new MAC should also be printed
# on the MAC label of the Pi-Tron.

#------------------------------------------------------------------------
# Check the OTP registers
#------------------------------------------------------------------------
otpreg=$( vcgencmd otp_dump | grep "64:")
otpreg2=$( vcgencmd otp_dump | grep "65:")
if [ -z $(echo $otpreg | grep "00000000") ]
then
    echo ""
    echo " OTP registers have a MAC address programed!" 
    # Combine both register to create one string
    otpreg3=$otpreg2$otpreg
    # Cut off unwanted parts
    mactomake=${otpreg3/65:}
    mactomake=${mactomake/64:}
    # Extract the MAC address
    mactomake=${mactomake:0:12}
    # Turn the MAC address string from a hex value into an integer
    macint=$((0x${mactomake}))
    # Add plus one (1) to the MAC address
    macintnew=$(($macint+1))
    # Convert the MAC address back in to a hex value 
    macnew=$( printf "%x" $macintnew )
    # Turn all letters into capital letters
    macbig=${macnew^^}
    # Add the colons after every 2 numbers
    macfinal=$( echo $macbig | sed "s/\(..\)/\1:/g;s/:$//" )   
else
    echo ""
    echo " ERROR: OTP registers are empty! This script is not needed!"
    exit 0
fi

#------------------------------------------------------------------------
# Set eth1 new MAC address
#------------------------------------------------------------------------
echo " Setting new MAC on eth1: "$macfinal
echo ""
# Deactivate eth1
sudo ifconfig eth1 down
# Set the new eth1 MAC address
sudo ifconfig eth1 hw ether $macfinal
# Activate eth1 again
sudo ifconfig eth1 up
#------------------------------------------------------------------------

exit 0

Save the changes to the file and close the editor. Try running the file and see if the resulting MAC address corresponds to the label on the Pi-Tron.

Make the script executable:

pi@raspberry:~ $ chmod +x gen_eth1_mac.sh

Run it and then check the MAC addresses:

pi@raspberry:~ $ sudo ./gen_eth1_mac.sh

 OTP registers have a MAC address programed!
 Setting new MAC on eth1: xx:xx:xx:xx:xx:73

pi@pitron:~ $ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet xxx.xxx.xxx.xxx  netmask xxx.xxx.xxx.xxx  broadcast xxx.xxx.xxx.xxx
        inet6 fff::fff:fff:fff:fff  prefixlen 64  scopeid 0x20<link>
        ether xx:xx:xx:xx:xx:72  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether xx:xx:xx:xx:xx:73  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

The MAC address generated in this example has "73" as the last value, whereas in the OTP and on eth0 it is "72". This means the script successfully read the MAC address from the OTP and added plus one (+1). For demonstration purposes all other values have been replaced with "xxx" or "fff".

If all of this was successful, the script file can be added to the rc.local file, this way it is run every time the Pi-Tron starts and the MAC address of eth1 is set automatically.

Add it to the rc.local file:

pi@raspberry:~ $ sudo nano /etc/rc.local

Just before the line "exit 0" add the following:

sudo /home/pi/gen_eth1_mac.sh

Save the changes, close the editor and reboot. After the reboot check the MAC addresses of eth0 and eth1 that they are different by one count.