Zephyr on the ESP32

This topic is to explore running Zephyr on ESP32 devices. To start, we have four boards:

Two boards with the ESP32-WROOM modules (Xtensa microprocessor) and two boards with the ESP32-C3 (RISC-V).

The process to build and flash Zephyr is similar for both architectures:

C3 RiscV:

west build -b esp32c3_devkitm --sysbuild samples/hello_world

Xtensa:

west build -b esp_wrover_kit --sysbuild samples/hello_world

And to flash:

west flash

You can run tio on the serial port to view the console.

ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:2
load:0x3fcc1e00,len:0x1fd0
load:0x403b6e00,len:0x7844
load:0x403bee00,len:0x1200
entry 0x403b92e6
I (48) boot: MCUboot 2nd stage bootloader
I (48) boot: compile time May 23 2024 18:07:00
I (48) boot: Multicore bootloader
I (49) spi_flash: detected chip: generic
I (52) spi_flash: flash io: dio
W (54) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (67) boot: chip revision: v0.3
I (69) boot.esp32c3: SPI Speed      : 40MHz
I (73) boot.esp32c3: SPI Mode       : SLOW READ
I (78) boot.esp32c3: SPI Flash Size : 4MB
I (81) boot: Enabling RNG early entropy source...
I (97) spi_flash: flash io: dio
[esp32c3] [INF] Image index: 0, Swap type: none
[esp32c3] [INF] Loading image 0 - slot 0 from flash, area id: 1
[esp32c3] [INF] Application start=40380730h
[esp32c3] [INF] DRAM segment: paddr=000136f0h, vaddr=3fc836c0h, size=0053ch (  1340) load
[esp32c3] [INF] IRAM segment: paddr=00010040h, vaddr=40380000h, size=036b0h ( 14000) load
[esp32c3] [INF] DROM segment: paddr=00020000h, vaddr=3c000000h, size=005B0h (  1456) map
[esp32c3] [INF] IROM segment: paddr=00030000h, vaddr=42010000h, size=02508h (  9480) map

*** Booting Zephyr OS build v3.6.0-4560-g11920e35a00e ***
Hello World! esp32c3_devkitm/esp32c3

The development process feels very similar between the Xtensa and RiscV devices.

Next steps will be to configure the WiFi networking and the Ethernet on the Olimex board.

1 Like

I think RISV on Zephyr is match made in heaven. We will see standard OSS on standard OpenSource ISA implementing h/w

Ethernet support

Zephyr includes support for the ESP32-ETHERNET-KIT:

Schematics

ESP32-ETHERNET-KIT Ethernet circuitry

Olimex ESP32-POE-ISO Ethernet Circuitry

Espressif has a nice page on the Zephyr efforts:

Looks like they are doing things right.

Ended up getting an ESP32-ETHERNET-KIT (far right in photo below):

I built the Ethernet sample:

west build -b esp32_ethernet_kit/esp32/procpu samples/boards/esp32/ethernet/

The Ethernet cable was detected by the Phy, but the Ethernet interface did not come up:

[00:00:01.104,000] <inf> phy_mii: PHY (1) ID 2430C54

*** Booting Zephyr OS build v3.6.0-5816-gaca152a94165 ***
[00:00:01.108,000] <inf> net_config: Initializing network
[00:00:01.108,000] <inf> net_config: Waiting interface 1 (0x3ffb5f08) to be up...
[00:00:06.916,000] <inf> phy_mii: PHY (1) Link speed 100 Mb, full duplex

[00:00:31.109,000] <inf> net_config: Running dhcpv4 client...
[00:00:31.109,000] <err> net_config: Timeout while waiting network interface
[00:00:31.109,000] <err> net_config: Network initialization failed (-115)

I then tried the ESP32 Ethernet sample on an STM32 H7 board – it worked fine. After reporting the issue on the Espressif channel on Discord, a developer from Espressif suggested a solution, and now it works! Apparently, something broke in some recent clock refactoring.

[00:00:07.017,000] <inf> phy_mii: PHY (1) Link speed 100 Mb, full duplex

[00:00:07.017,000] <inf> net_config: Interface 1 (0x3ffb5f08) coming up
[00:00:07.017,000] <inf> net_config: Running dhcpv4 client...
[00:00:09.607,000] <inf> net_dhcpv4: Received: 10.0.0.135
[00:00:09.607,000] <inf> net_config: IPv4 address: 10.0.0.135
[00:00:09.607,000] <inf> net_config: Lease time: 600 seconds
[00:00:09.607,000] <inf> net_config: Subnet: 255.255.255.0
[00:00:09.607,000] <inf> net_config: Router: 10.0.0.1

The above issue also links to another discussion that may be the key to getting the Ethernet working on the Olimex board, which uses a ESP32 GPIO to generate the 50MHz Phy clock.

This illustrates several things:

  1. Community is important. A developer from Espressif was aware of some recent changes that might have broke something – they had context.
  2. This also illustrates the advantage of developing on the main branch – you can get good support there as that is where the MCU developers are working. If you want support on an older LTS release, you better have a support contract in place.
  3. The support for using a GPIO pin for Phy clock was recently added – again, if you want to use features a little off the beaten path, developing on main is a good place to be.
  4. Proving something works on a competitor’s MCU is a good motivator and a good check to make sure the core OS components are working. It is amazing how I can build the same application on ESP32 and STM32 parts.
  5. Having the MCU vendor’s official development board allowed me to get quick support from the vendor as they could replicate the problem. If we had to debug this on the Olimex board, it would have been time-consuming as several things are different.
  6. When dealing with a complex system, break it down and verify it one step at a time.

Now to get the Phy clock running on the Olimex ES32-POE …

yeah more upstream you go, better the water is for drinking, its nature’s law :slight_smile:

1 Like

A post was split to a new topic: Zephyr SimpleIoT Application

Ethernet is now working on the Olimex ESP32-POE under Zephyr!

[00:00:00.210,000] <inf> phy_mii: PHY (0) ID 7C0F1
                                                                                                                     
[00:00:00.212,000] <inf> eth_esp32: APLL is occupied already, it is working at 50000000 Hz
*** Booting Zephyr OS build v3.7.0-rc1-375-g9f927f97847f ***
[00:00:00.225,000] <inf> net_config: Initializing network
[00:00:00.225,000] <inf> net_config: Waiting interface 1 (0x3ffb5d00) to be up...
uart:~$ SIOT Zephyr Application! esp32_poe/esp32/procpu
[00:00:03.418,000] <inf> phy_mii: PHY (0) Link speed 100 Mb, full duplex
                                                                                                                     
[00:00:03.418,000] <inf> net_config: Interface 1 (0x3ffb5d00) coming up
[00:00:03.418,000] <inf> net_config: Running dhcpv4 client...
[00:00:08.423,000] <inf> net_dhcpv4: Received: 10.0.0.148
[00:00:08.423,000] <inf> net_config: IPv4 address: 10.0.0.148
[00:00:08.423,000] <inf> net_config: Lease time: 600 seconds
[00:00:08.423,000] <inf> net_config: Subnet: 255.255.255.0
[00:00:08.423,000] <inf> net_config: Router: 10.0.0.1

Some fixes have been merged for ESP32 Ethernet and one PR is still pending. The complete build is here:

This is a Zephyr Workspace T2 topology that pulls in Zephyr as a dependency.

Notice right now, we are referencing a PR repo/branch that has the fixes we need.

manifest:
  remotes:
    - name: zephyrproject-rtos
      url-base: https://github.com/zephyrproject-rtos
    - name: zephyr-sylvio
      url-base: https://github.com/sylvioalves
    - name: zephyr-iwasz
      url-base: https://github.com/iwasz
  projects:
    - name: zephyr
      remote: zephyr-iwasz
      revision: initialize_ref_clk_in_mdio_esp32
      import: 
        name-allowlist:
          - hal_espressif
          - hal_stm32
          - cmsis
  self:
    path: siot

This has been a community effort: