Zephyr does Ethernet Too!

When it comes to the Internet of Things, wireless tech like celluar and WiFi get all the flashy press coverage. But wired devices aren’t second class citizens, they’re the connectivity-of-choice for tons of industrial applications. Zephyr makes it really easy to add an Ethernet connection to any project.

Here at Golioth we’re getting ready for a couple of conferences: the Zephyr Developer’s Summit and the Embedded World Conference, both in June. We’ll have hardware demos on site, and the thought of competing for RF spectrum with tens of thousands of other radios gives me the demo blues. So we will include a wired-network demo at the Golioth kiosk to be on the safe side.

What did it take to get our hardware up and running with Ethernet? Not much. It’s a quick and easy process, so let’s dive in!

Wire up an Ethernet module

We’ve chosen the WIZnet W5500 Ethernet chip to handle the Ethernet PHY. It connects to a microcontroller using SPI and there is a handy ETH WIZ Click module available that includes the jack and magnetics for easy prototyping. This chip has great driver support in Zephyr, which we’ll get to in the next section.

Wiring it up will be familiar to anyone who has worked with Serial Peripheral Interface (SPI) devices. I’m using an nRF52840 microcontroller in this demo. The bindings page for nrf-spi lists sck-pin, mosi-pin, miso-pin, and cs-gpios which connect to the ETH WIZ Click’s SCK, SDI, SDO, and CS pins. The w5500 bindings page also details int-gpios and reset-gpios which connect to the INT and RST pins on the Ethernet module.

We need to tell Zephyr that this module is present by adding it to an overlay file.

[sourcecode title=”adafruit_feather_nrf52840.overlay”]
&spi1 {
compatible = "nordic,nrf-spi";
status = "okay";
cs-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
test_spi_w5500: w5500@0 {
compatible = "wiznet,w5500";
label = "w5500";
reg = <0x0>;
spi-max-frequency = <10000000>;
int-gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
};
};
[/sourcecode]

This overlay file uses the SPI pin definitions already present in the board DTS file. The node for the W5500 chip correctly assigns CS (chip select), INT, and RST pins.

Configure the Ethernet library and IP handling

The node shown above needs to be added to a board overlay file in your project. For your convenience, we have hello-ethernet sample code that includes board files for several different microcontrollers.

In addition to telling Zephyr how the Ethernet chip is connected, we need to tell Zephyr to build in the proper libraries.

[sourcecode title=”adafruit_feather_nrf52840.conf”]
CONFIG_SPI=y
CONFIG_NET_L2_ETHERNET=y
CONFIG_ETH_W5500=y
CONFIG_ETH_W5500_TIMEOUT=1000
CONFIG_NET_DHCPV4=y
CONFIG_NET_MGMT=y
[/sourcecode]

These KConfig symbols tell the build tools that we need the SPI peripherals, we’ll be using Ethernet–specifically the W5500 chip, and that we’re going to need some tools to manage the DHCP process for acquiring and using an IP address. I’ve added these settings to a board-specific conf file, but they could be added to the prj.conf if you prefer.

That last part requires just a bit of work in the main.c file. We need to tell Zephyr that if Ethernet is enabled, we want to make an API call to acquire and use an IP address assigned by the wired network’s DHCP server.

[sourcecode title=”excerpts from main.c”]
#if IS_ENABLED(CONFIG_NET_L2_ETHERNET)
#include <net/net_if.h>
#endif

/* This next part goes in main() before the loop */
if (IS_ENABLED(CONFIG_NET_L2_ETHERNET))
{
LOG_INF("Connecting to Ethernet");
struct net_if *iface;
iface = net_if_get_default();
net_dhcpv4_start(iface);
}
[/sourcecode]

Don’t forget to plug it in

This sounds silly, but I have spent fives-of-minutes wondering why I wasn’t able to get an IP address. I’m so used to working with WiFi and cellular, sometimes I forget to plug in the Ethernet cable. Don’t be me.

*** Booting Zephyr OS build zephyr-v3.0.0-3806-g05cc2e1ac388  ***

[00:00:00.259,429]  golioth_system: Initializing
[00:00:00.259,796]  golioth_hello: main: Start Hello sample
[00:00:00.259,826]  golioth_hello: Connecting to Ethernet
[00:00:00.259,887]  golioth_hello: Sending hello! 0
[00:00:00.259,948]  golioth_system: Starting connect
[00:00:00.260,131]  golioth_hello: Failed to send hello!
[00:00:00.260,467]  golioth: Fail to get address (coap.golioth.io 5684) -11
[00:00:00.260,467]  golioth_system: Failed to connect: -11
[00:00:00.260,498]  golioth_system: Failed to connect: -11
[00:00:05.260,223]  golioth_hello: Sending hello! 1
[00:00:05.260,437]  golioth_hello: Failed to send hello!
[00:00:05.260,589]  golioth_system: Starting connect
[00:00:05.260,925]  golioth: Fail to get address (coap.golioth.io 5684) -11
[00:00:05.260,955]  golioth_system: Failed to connect: -11
[00:00:05.260,955]  golioth_system: Failed to connect: -11
[00:00:05.300,750]  net_dhcpv4: Received: 192.168.1.106
[00:00:10.260,498]  golioth_hello: Sending hello! 2
[00:00:10.260,711]  golioth_hello: Failed to send hello!
[00:00:10.261,047]  golioth_system: Starting connect
[00:00:10.315,734]  golioth_system: Client connected!
[00:00:15.260,803]  golioth_hello: Sending hello! 3
[00:00:20.263,305]  golioth_hello: Sending hello! 4

That warning aside, the display above is a typical run of the hello-ethernet sample. You can see that the Ethernet connection is initialized shortly after power-on. The Golioth client immediately starts trying to send log messages to the cloud but fails until an IP address is secured about 5.3 seconds into runtime.

All Internet connections act the same in Zephyr

Zephyr abstracts the details of your Internet connection. Once it’s set up, your app has access to sockets for whatever operation it needs. For the most part your code doesn’t need to know how it’s actually getting to the network.

Of course there are exceptions. Here we needed to explicitly sort out an IP address. But considering the complexity that actually goes into operating a network stack, Zephyr sure has taken the degree of difficulty down to a minimum.

Mike Szczys
Mike Szczys
Mike is a Firmware Engineer at Golioth. His deep love of microcontrollers began in the early 2000s, growing from the desire to make more of the BEAM robotics he was building. During his 12 years at Hackaday (eight of them as Editor in Chief), he had a front-row seat for the growth of the industry, and was active in developing a number of custom electronic conference badges. When he's not reading data sheets he's busy as an orchestra musician in Madison, Wisconsin.

Post Comments

More from this author

Related posts

spot_img

Latest posts

Golioth Design Partners: IoT Solutions for Constrained Devices | 2025 Partner Network

We regularly refer Golioth users to our trusted Design Partners to help design, test, and deploy hardware out into the world. The Golioth Design Partner program has been going for more than 2 years and continues growing. In 2025, we reached 20 listed partners, with others in the wings.

Adding Golioth Example Code to Your ESP-IDF Project

In our previous blog post, we demonstrated how to add the Golioth Firmware SDK to an ESP-IDF project. As you start integrating Golioth into...

Tracking Our CEO at CES

We used Golioth Location to build an application that keeps up with Golioth CEO Jonathan Beri at CES 2025.

Want to stay up to date with the latest news?

We would love to hear from you! Please fill in your details and we will stay in touch. It's that simple!