Pages in this article:
Of the 4 techniques in this article for connecting the Pi 5 to your PC, this is the simplest from a hardware perspective.
Power and data are provided by a USB-C cable from your laptop to the “power” connector on the Pi. The connector on the Pi is part of the onboard USB controller that provides several modes for communications. One is the typical On-The-Go USB type found on phones. Another is what is called “USB Gadget” mode where the port can act as a network device, in particular an Ethernet port. Then the PC can recognize the device as implementing Ethernet through a standardized protocol (for Windows, this is termed RNDIS). At that point the connection looks very similar to the setup described in the Ethernet document in this article.
While this approach has advantages of simple hardware and portability, there are several caveats:
The steps listed below are borrowed heavily from a great blog post (one of several for Pi connectivity over time) from Ben Hardill - “Pi5 USB-C Gadget”. Many thanks, Ben!
sudo apt update
sudo apt full-upgrade
sudo rpi-update
You will then need to reboot the Pi.
The next steps closely follow Ben’s article; you may want to refer to his excellent explanations. Changes that were needed for the VSCode operation will be noted.
sudo nano /boot/config.txt
-> Add the following line to end of file, save and exit editor:
dtoverlay=dwc2
-> next...
sudo nano /boot/cmdline.txt
-> Add ght following to end of line including the space before, no newline!, save and exit editor
modules-load=dwc2
-> next...
sudo nano /etc/modules
-> Add to end of file, save and exit editor:
libcomposite
sudo nano /usr/local/sbin/usb-gadget.sh
-> Add the following in the file:
#!/bin/bash
cd /sys/kernel/config/usb_gadget/
mkdir -p display-pi
cd display-pi
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0103 > bcdDevice # v1.0.3
echo 0x0320 > bcdUSB # USB2
echo 2 > bDeviceClass
mkdir -p strings/0x409
echo "fedcba9876543213" > strings/0x409/serialnumber
echo "Ben Hardill" > strings/0x409/manufacturer
echo "Display-Pi USB Device" > strings/0x409/product
mkdir -p configs/c.1/strings/0x409
echo "CDC" > configs/c.1/strings/0x409/configuration
echo 250 > configs/c.1/MaxPower
echo 0x80 > configs/c.1/bmAttributes
#ECM
mkdir -p functions/ecm.usb0
HOST="00:dc:c8:f7:75:15" # "HostPC"
SELF="00:dd:dc:eb:6d:a1" # "BadUSB"
echo $HOST > functions/ecm.usb0/host_addr
echo $SELF > functions/ecm.usb0/dev_addr
ln -s functions/ecm.usb0 configs/c.1/
#RNDIS
mkdir -p configs/c.2
echo 0x80 > configs/c.2/bmAttributes
echo 0x250 > configs/c.2/MaxPower
mkdir -p configs/c.2/strings/0x409
echo "RNDIS" > configs/c.2/strings/0x409/configuration
echo "1" > os_desc/use
echo "0xcd" > os_desc/b_vendor_code
echo "MSFT100" > os_desc/qw_sign
mkdir -p functions/rndis.usb0
HOST_R="00:dc:c8:f7:75:16"
SELF_R="00:dd:dc:eb:6d:a2"
echo $HOST_R > functions/rndis.usb0/dev_addr
echo $SELF_R > functions/rndis.usb0/host_addr
echo "RNDIS" > functions/rndis.usb0/os_desc/interface.rndis/compatible_id
echo "5162001" > functions/rndis.usb0/os_desc/interface.rndis/sub_compatible_id
ln -s functions/rndis.usb0 configs/c.2
ln -s configs/c.2 os_desc
udevadm settle -t 5 || :
ls /sys/class/udc > UDC
sleep 5
nmcli connection up bridge-br0
nmcli connection up bridge-slave-usb0
nmcli connection up bridge-slave-usb1
sleep 5
service dnsmasq restart
-> Save and exit the editor then do:
sudo chmod +x /usr/local/sbin/usb-gadget.sh
sudo nano /lib/systemd/system/usbgadget.service
-> Add the following in the editor:
[Unit]
Description=My USB gadget
After=network-online.target
Wants=network-online.target
#After=systemd-modules-load.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/usb-gadget.sh
[Install]
WantedBy=sysinit.target
-> Save the file and exit the editor, then do:
sudo systemctl enable usbgadget.service
sudo nmcli con add type bridge ifname br0
sudo nmcli con add type bridge-slave ifname usb0 master br0
sudo nmcli con add type bridge-slave ifname usb1 master br0
sudo apt-get install dnsmasq
sudo nano /etc/dnsmasq.d/br0
-> Add the following in the editor, save and exit the editor:
dhcp-authoritative
dhcp-rapid-commit
no-ping
interface=br0
dhcp-range=10.55.0.2,10.55.0.6,255.255.255.248,1h
dhcp-option=3
leasefile-ro
get-netadapter
-> copy the names of the interface having internet access (the Public IF) to the Gadget interface (the Private IF), then enter (as an example)
set-ics "Wi-Fi" "Ethernet 6"
ssh pi@raspberrypi.local
-> Now in the Pi terminal:
ping www.google.com
-> you should get good responses from Google
Congratulations! You can now run VSCode and connect to the remote SSH host to begin development. You should not have to change anything on the Pi when you reboot or power down. On the PC you should be able to reboot the Pi with no changes needed. If you remove the Pi USB cable from your PC and connect other similar USB devices (like a regular Ethernet adapter), it is advisable to remove the ICS sharing before connecting the Pi again. Then just start at step 14 above.