Skip to main content

How to compile micropython for esp8266

· 7 min read
  1. create .venv
  2. compile the firmware (.bin) needed to flash into the board
  3. install esptool to talk with serial port
  4. others
    1. create sed fix for bash version
    2. create fix for libtool
    3. fix not case-sensitive file system

Oh well, you have the prebuilded .bin here:

legenda

esp-open-sdk : open-source toolchain bundle used to develop firmware for the ESP8266 microcontroller. It packages together everything needed to compile C code for the ESP8266 without installing each component manually.

Xtensa : The CPU architecture used in ESP8266 chips, designed by Tensilica.

lx106 : The specific Xtensa core variant in ESP8266.

elf : The target output format, Executable and Linkable Format, used for binaries on embedded systems.

xtensa-lx106-elf : as a whole refers to the cross-compiler toolchain that produces programs for this CPU. Aka if you want to run MicroPython on an ESP8266, you must use the xtensa-lx106-elf toolchain (or a compatible prebuilt one).

esptool.py : converts firmware.elf into firmware.bin

firmware.elf-0x00000.bin : typically the bootloader/boot partition and the initial firmware sections.

firmware.elf-0x09000.bin : typically the main application partition.

0x00000 and 0x09000 : (firmware.elf-0x00000.bin, firmware.elf-0x09000.bin) indicate the flash offset (addresses) where each binary should be written to the ESP8266's memory.

There are a lot of model:

  • NodeMCU
  • Wemos D1 Mini
  • bare module
  • etc...

check if is charge-only USB cable

charge-only USB

  1. LED briefly lights (initial 5V present)
  2. No new lsusb devices (no enumeration)
    • lsusb
  3. No dmesg output (no data communication)
    • sudo dmesg -wH
  4. 0mA current (no power negotiation)
    • lsusb -v | grep -E "(MaxPower|Bus)"

notes

# 1. connect ESP to PC with USB
# make sure your USB cable has D+ and D- data channel
# 1.1 check with dmesg
# -w, --follow
sudo dmesg -wH
# or
# journalctl -f | grep -i usb
# led should be always on

# check power status of every USB port
# lsusb -v | grep -E "(MaxPower|Bus)"
# if 0mA, nothing is connected
# Current negotiation: 500mA
# Initial connection: 5V provided (100mA default)

scripts

# 0. create .venv

# 1. compile the firmware needed to flash into the board
wsl # version 2

sudo apt install git make gcc g++ python3 python3-venv python3-pip build-essential gcc make libncurses-dev pkg-config unrar-free autoconf automake libtool libtool-bin gperf flex bison texinfo gawk ncurses-dev libexpat-dev python-dev python sed unzip bash help2man wget bzip2 libc6-dev

# we are going to compile those:
# sudo apt install gcc-xtensa-lx106
# sudo apt remove gcc-xtensa-lx106

mkdir "esp8266_micropython" && cd $_

#
# compile esp8266 toolchain
#
git clone --recursive https://github.com/pfalcon/esp-open-sdk.git
cd esp-open-sdk
make clean
# apply fixes
# fix bash version control (missing check on version 5)
sed -i "s/|\$EGREP '^GNU bash, version (3\\\.\[1-9]|4)')/|\$EGREP '^GNU bash, version (3\\\.\[1-9]|4|5)')/" ./crosstool-NG/configure.ac
# create sed fix to retrieving needed toolchain components tarballs - isl
sed -i "s/http:\/\/isl.gforge.inria.fr/ftp:\/\/gcc.gnu.org\/pub\/gcc\/infrastructure/" crosstool-NG/scripts/build/companion_libs/121-isl.sh
# create sed fix to retrieving needed toolchain components tarballs - expat
sed -i "s/http:\/\/downloads.sourceforge.net\/project\/expat\/expat\/\${CT_EXPAT_VERSION}/https:\/\/github.com\/libexpat\/libexpat\/releases\/download\/R_2_1_0\//" crosstool-NG/scripts/build/companion_libs/210-expat.sh
make

# add xtensa-lx106-elf/ subdirectory to PATH
# export PATH="full/path/to/esp-open-sdk/xtensa-lx106-elf/bin:$PATH"
# check
xtensa-lx106-elf-gcc --version
which xtensa-lx106-elf-gcc

#
# compile micropython with xtensa-lx106-elf toolchain
#
git clone --recursive https://github.com/micropython/micropython.git
cd micropython
git checkout v1.26.1 # checkout to stable branch / latest release
make -C ports/esp8266 submodules
make -C mpy-cross -j$(nproc)
make -C ports/esp8266 -j$(nproc)

## retry
make -C mpy-cross clean
make -C ports/esp8266 clean

# check firmware
ls ports/esp8266/build-ESP8266_GENERIC/firmware.elf

#
# 2. install esptool to convert to elf into bin and to talk with serial port
#
# Do not use old esptool (python2), use python3
#
pip3 install esptool
esptool --chip esp8266 elf2image ports/esp8266/build-ESP8266_GENERIC/firmware.elf --output .

#
# 3. Install MicroPython
#
# erase flash
esptool --port /dev/ttyXXX erase_flash
esptool --chip esp8266 write_flash 0x00000 0x00000.bin 0x09000 0x09000.bin

create sed fix for bash version

grep -n "\$EGREP" ./crosstool-NG/configure.ac
sed -n "/\$EGREP '^GNU bash, version (3\\\.\[1-9]|4)')/p" ./crosstool-NG/configure.ac
sed -n "/|\$EGREP '^GNU bash, version (3\\\.\[1-9]|4)')/p" ./crosstool-NG/configure.ac

# see what will modify:
sed -n "s/|\$EGREP '^GNU bash, version (3\\\.\[1-9]|4)')/|\$EGREP '^GNU bash, version (3\\\.\[1-9]|4|5)')/p" ./crosstool-NG/configure.ac

# create fix command
sed -i "s/|\$EGREP '^GNU bash, version (3\\\.\[1-9]|4)')/|\$EGREP '^GNU bash, version (3\\\.\[1-9]|4|5)')/" ./crosstool-NG/configure.ac

# verify
grep -n "\$EGREP" ./crosstool-NG/configure.ac

create fix for libtool

# libtool and libtoolize are the same thing
grep -n -C 10 "libtool >= 1.5.26" ./crosstool-NG/configure.ac
libtoolize --version
which libtoolize

# the fix:
sudo ln -s /usr/bin/libtoolize /usr/local/bin/libtool

fix *not* case-sensitive

# You are in windows file system, move to real WSL linux environment

# move everything from:
# /mnt/c/...

# to:
# ~/
# or every other path than /mnt/c/...

create sed fix to retrieving needed toolchain components tarballs

Error happened in: do_isl_get[scripts/build/companion_libs/121-isl.sh@16]

cd esp8266_micropython/esp-open-sdk

# look at the actual URL
cat -n crosstool-NG/scripts/build/companion_libs/121-isl.sh

# search for the version of isl
grep -R --line-number --color=auto 'CT_ISL_VERSION' crosstool-NG/

# search a good mirror in the web
# example: substitute the mirror in the script with "ftp://gcc.gnu.org/pub/gcc/infrastructure"

# create sed fix
# print the line affected
sed -n "/http:\/\/isl.gforge.inria.fr/p" crosstool-NG/scripts/build/companion_libs/121-isl.sh
# see what will modify:
sed -n "s/http:\/\/isl.gforge.inria.fr/ftp:\/\/gcc.gnu.org\/pub\/gcc\/infrastructure/p" crosstool-NG/scripts/build/companion_libs/121-isl.sh
# create sed fix
sed -i "s/http:\/\/isl.gforge.inria.fr/ftp:\/\/gcc.gnu.org\/pub\/gcc\/infrastructure/" crosstool-NG/scripts/build/companion_libs/121-isl.sh

# check
cat -n crosstool-NG/scripts/build/companion_libs/121-isl.sh

# always make clean before redo make

# you can add:
# CT_DoLog INFO "isl-${CT_ISL_VERSION}"
# to see what is going on

# then you can check if download works
# example: ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.14.tar.bz2
# https://gcc.gnu.org/pub/gcc/infrastructure/

Error happened in: do_expat_get[scripts/build/companion_libs/210-expat.sh@12]

Another mirror error.

cat -n crosstool-NG/scripts/build/companion_libs/210-expat.sh
grep -R --line-number --color=auto 'CT_EXPAT_VERSION' crosstool-NG/
# 2.1.0
# http://downloads.sourceforge.net/project/expat/expat/2.1.0
# https://sourceforge.net/projects/expat/files/expat/2.1.0/expat-2.1.0-RENAMED-VULNERABLE-PLEASE-USE-2.3.0-INSTEAD.tar.gz

# this is working:
# https://github.com/libexpat/libexpat/releases/download/R_2_1_0/expat-2.1.0.tar.gz
# https://github.com/libexpat/libexpat/releases/download/R_2_1_0/

# create sed fix
# print the line affected
sed -n "/http:\/\/downloads.sourceforge.net\/project\/expat\/expat\/\${CT_EXPAT_VERSION}/p" crosstool-NG/scripts/build/companion_libs/210-expat.sh
# see what will modify:
sed -n "s/http:\/\/downloads.sourceforge.net\/project\/expat\/expat\/\${CT_EXPAT_VERSION}/https:\/\/github.com\/libexpat\/libexpat\/releases\/download\/R_2_1_0\/\${CT_EXPAT_VERSION}/p" crosstool-NG/scripts/build/companion_libs/210-expat.sh
# create sed fix
sed -i "s/http:\/\/downloads.sourceforge.net\/project\/expat\/expat\/\${CT_EXPAT_VERSION}/https:\/\/github.com\/libexpat\/libexpat\/releases\/download\/R_2_1_0\//" crosstool-NG/scripts/build/companion_libs/210-expat.sh

# check that worked
cat -n crosstool-NG/scripts/build/companion_libs/210-expat.sh

sources