.
In summary, this article describes how to build the xtensa-esp32 toolchains and openocd-esp32 for arm64 / aarch64 from scratch, using Raspberry Pi 4 (64-bit) and Debian-based Raspberry Pi OS. In addition, it provides instructions on how to use the xtensa-esp32 toolchains with the Arduino ESP32 v2.0.0.
.
The Arduino-ESP32 package of the version 2.0.0 is not yet available for 64-bit ARM architecture. However, for other platforms such as armhf (32-bit ARM), win32, win64, linux-x86_64, and mac-os, there are prebuilt files available for downloading. You can check the contents of the package_esp32_index.json
file.
The Arduino-esp32 version 2.0.0 is based on the ESP-IDF version 4.4 (Dev) and has added support for ESP32-S2 and ESP-C3.
The article is organized into sections as follow:
- Getting System Information
- Building Xtensa-ESP32 Toolchain for ARM64
- Building binutils-esp32ulp for ARM64
- Building openocd-esp32 for ARM64
- Installing Arduino-esp32 v2.0.0 for ARM64
- Basic Arduino Sketch Demo for ESP32
Getting System Information
.
We will use a 64-bit Raspberry Pi 4 SBC to build the software from sourcecode. The following commands are used to show information about the system.
$ uname -a
Linux raspberrypi 5.10.60-v8+ #1449 SMP PREEMPT Wed Aug 25 15:01:33 BST 2021 aarch64 GNU/Linux$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"$ hostnamectl
Static hostname: raspberrypi
Icon name: computer
Machine ID: 683ec8367b5e45b0be13dad7xxxxxxxx
Boot ID: 4ae010bd0bf149cd8637208cxxxxxxxx
Operating System: Debian GNU/Linux 10 (buster)
Kernel: Linux 5.10.60-v8+
Architecture: arm64# check version of python/gcc/g++$ python -V
Python 3.7.3$ gcc --version
gcc (Debian 8.3.0-6) 8.3.0$ g++ --version
g++ (Debian 8.3.0-6) 8.3.0
Building Xtensa-ESP32 Toolchain for ARM64
.
- Install necessary software packages:
$ sudo apt-get install gawk gperf grep gettext python python-dev automake bison flex texinfo help2man libtool libtool-bin make
2. Download the crosstool-NG for ESP32 repository (esp-2021r1
) from github:
$ mkdir -p $HOME/src
$ mkdir -p ~/esp && cd ~/esp
$ git clone https://github.com/espressif/crosstool-NG.git
$ cd crosstool-NG
$ git checkout esp-2021r1
$ git submodule update --init
$ ./bootstrap && ./configure --enable-local && make
3. Choose xtensa-esp32-elf as target:
# select xtensa-esp32-elf as target
$ ./ct-ng xtensa-esp32-elf # edit the configuration and save change to the .config file
$ ./ct-ng menuconfig# show all the steps of the build process
$ ./ct-ng list-stepsAvailable build steps, in order:
- companion_tools_for_build
- companion_libs_for_build
- companion_tools_for_host
- companion_libs_for_host
- binutils_for_build
- binutils_for_host
- cc_core_pass_1
- kernel_headers
- libc_start_files
- cc_core_pass_2
- libc
- cc_for_build
- cc_for_host
- libc_post_cc
- companion_libs_for_target
- binutils_for_target
- debug
- test_suite
- finish
4. Start the build process:
# increase the max. of open files to 2048
$ ulimit -n 2048# remove all toolchain components under ./build/tarballs
$ rm -fr .build/tarballs/*$ TARGET=xtensa-esp32-elf
$ ./ct-ng ${TARGET}
$ ./ct-ng menuconfig# start the build process
$ ./ct-ng build# change permissions of built files for user (writable)
$ chmod -R u+w builds/${TARGET}# make an archive file (.tar.gz) for the built files
$ cd ./builds
$ FILENAME=${TARGET}-gcc8_4_0-esp-2021r1-linux-arm64
$ tar -cvf ${FILENAME}.tar ./xtensa-esp32-elf
$ gzip -9 ${FILENAME}.tar# calculate and show the SHA256 checksum
$ sha256sum ${FILENAME}.tar.gz
076455e9b96b8944d1f200fa42d47054faac70b88e0bce2b2f663d4ec48991c3 xtensa-esp32-elf-gcc8_4_0-esp-2021r1-linux-arm64.tar.gz# get the file size in bytes
$ ls -l ${FILENAME}.tar.gz | awk '{print $5}'
85469631
Bug: You have to edit the .config
file and change the version of expat-lib from 2.2.9 to 2.4.1.
You can use the sed command to replace string:
$ sed -i 's/2.2.9/2.4.1/g' .config
For the xtensa-esp32s2-elf or xtensa-esp32s3-elf or riscv32-esp-elf target:
$ TARGET=xtensa-esp32s2-elf
$ ./ct-ng ${TARGET}
$ ./ct-ng menuconfig$ ./ct-ng build
$ chmod -R u+w builds/${TARGET}# make an archive file (.tar.gz) for the built files
$ cd ./builds
$ FILENAME=${TARGET}-gcc8_4_0-esp-2021r1-linux-arm64
$ tar -cvf ${FILENAME}.tar ./${TARGET}
$ gzip -9 ${FILENAME}.tar# calculate and show the SHA256 checksum
$ sha256sum ${FILENAME}.tar.gz# get the file size in bytes
$ ls -l ${FILENAME}.tar.gz | awk '{print $5}'
Warning: the complete build process can take up to 180 minutes (~3hrs) on Raspberry Pi 4.
Building binutils-esp32ulp for ARM64
.
- Download the binutils-esp32ulp repository from github:
$ git clone --recursive https://github.com/espressif/binutils-esp32ulp
$ cd binutils-esp32ulp
2. Choose gcc and g++ version 7 and python 2.7:
# install gcc and g++ version 7
$ sudo apt -y install gcc-7 g++-7
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 7
$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 7
# select the version of gcc and g++ to be used by default
$ sudo update-alternatives --config gcc
$ sudo update-alternatives --config g++# select the version of python to be used by default
$ sudo update-alternatives --config python# check version
$ python -V
Python 2.7.16$ gcc --version
gcc (Debian 7.4.0-6) 7.4.0$ g++ --version
g++ (Debian 7.4.0-6) 7.4.0
3. Configure for esp32ulp-elf or esp32s2ulp-elf target and start the build process:
$ TARGET=esp32ulp-elf
$ mkdir -p ./${TARGET}-binutils
$ find -name "config.status" -exec rm -f {} \;
$ find -name "config.cache" -exec rm -f {} \;
$ CC=gcc ./configure --target=${TARGET} --prefix=`pwd`/${TARGET}-binutils
$ make -j4
$ make install
$ make distclean
4. Make an archive file (.tar.gz)
$ FILE=binutils-${TARGET}-linux-arm64-2.28.51-esp-20191205
$ tar -cvf ${FILE}.tar ./${TARGET}-binutils
$ gzip -9 ${FILE}.tar
$ sha256sum ${FILE}.tar.gz
When finished, you can change back the configuration for gcc and g++ to version 8.
Building openocd-esp32 for ARM64
.
- Download the openocd-esp32 repository (
v0.10.0-esp32–20210902
) from github:
$ git clone --recursive https://github.com/espressif/openocd-esp32
2. Install necessary software packages:
$ sudo apt install -y git gcc binutils make libtool pkg-config autoconf automake texinfo libgpiod-dev libusb-1.0 libudev-dev libusb-1.0-0-dev
3. Run the following commands to configure the build files:
$ cd openocd-esp32
$ ./bootstrap
$ ./configure --prefix=`pwd`/openocd-esp32/
4. Start the build process:
$ make && make install
5. Make an archive file (.tar.gz):
$ FILE=openocd-esp32-arm64-0.10.0-esp32-20210902
$ tar -cvf ${FILE}.tar ./openocd-esp32
$ gzip -9 ${FILE}.tar
$ sha256sum ${FILE}.tar.gz
$ ls -l ${FILE}.tar.gz | awk '{print $5}'
Installing Arduino-esp32 v2.0.0 for ARM64
1. Download the package_esp32_index.json
(v2.0.0) file from github:
$ wget https://github.com/espressif/arduino-esp32/releases/download/2.0.0/package_esp32_index.json
.
2. Put all necessary archive files (tar.gz) under /home/pi/esp-2021r1
. as listed below.
$ tree -L 1 ~/esp-2021r1/
/home/pi/esp-2021r1/
├── package_esp32_index.json
├── riscv32-esp-elf-gcc8_4_0-esp-2021r1-linux-arm64.tar.gz
├── xtensa-esp32-elf-gcc8_4_0-esp-2021r1-linux-arm64.tar.gz
└── xtensa-esp32s2-elf-gcc8_4_0-esp-2021r1-linux-arm64.tar.gz0 directories, 4 files
3. Modify the package_esp32_index.json by adding options for arm64 files:
Search for:
"name": "riscv32-esp-elf-gcc",
"version": "gcc8_4_0-esp-2021r1",
Add the following lines (JSON format):
{
"host": "aarch64-linux-gnu",
"url": "file:///home/pi/esp-2021r1/riscv32-esp-elf-gcc8_4_0-esp-2021r1-linux-arm64.tar.gz",
"archiveFileName": "riscv32-esp-elf-gcc8_4_0-esp-2021r1-linux-arm64.tar.gz",
"checksum": "SHA-256:e8fa4c52233ba1236be81287083593913d85ea288f4b5ce5be2edfe9581d3b3d",
"size": "150926486"
},
Search for:
"name": "xtensa-esp32-elf-gcc",
"version": "gcc8_4_0-esp-2021r1",
Add the following lines (JSON format):
{
"host": "aarch64-linux-gnu",
"url": "file:///home/pi/esp-2021r1/xtensa-esp32-elf-gcc8_4_0-esp-2021r1-linux-arm64.tar.gz",
"archiveFileName": "xtensa-esp32-elf-gcc8_4_0-esp-2021r1-linux-arm64.tar.gz",
"checksum": "SHA-256:076455e9b96b8944d1f200fa42d47054faac70b88e0bce2b2f663d4ec48991c3",
"size": "85469631"
},
Search for:
"name": "xtensa-esp32s2-elf-gcc",
"version": "gcc8_4_0-esp-2021r1",
Add the following lines (JSON format):
{
"host": "aarch64-linux-gnu",
"url": "file:///home/pi/esp-2021r1/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r1-linux-arm64.tar.gz",
"archiveFileName": "xtensa-esp32s2-elf-gcc8_4_0-esp-2021r1-linux-arm64.tar.gz",
"checksum": "SHA-256:200d569899e6172dea299669cbe1dea0766370026fac6dcc2e8e5a29666da771",
"size": "85746821"
},
4. Open the Arduino IDE, Go to Arduino> Preferences; Enter the following URL into the “Additional Board Manager URLs”. Then, click the “OK” button:
file:///home/pi/esp-2021r1/package_esp32_index.json
Open the Boards Manager. Go to Tools > Board > Boards Manager…
Choose “esp32” and version 2.0.0. Then, click Install.
After installation, a new directory named esp32
under ~/.arduino15/packages/
was created with the following subdirectories:
$ tree -L 4 ~/.arduino15/packages/esp32/
/home/pi/.arduino15/packages/esp32/
├── hardware
│ └── esp32
│ └── 2.0.0
│ ├── boards.txt
│ ├── cores
│ ├── libraries
│ ├── platform.txt
│ ├── programmers.txt
│ ├── tools
│ └── variants
└── tools
├── esptool_py
│ └── 3.1.0
│ └── esptool.py
├── mklittlefs
│ └── 3.0.0-gnu12-dc7f933
│ ├── mklittlefs
│ └── package.json
├── mkspiffs
│ └── 0.2.3
│ └── mkspiffs
├── riscv32-esp-elf-gcc
│ └── gcc8_4_0-esp-2021r1
│ └── riscv32-esp-elf
├── xtensa-esp32-elf-gcc
│ └── gcc8_4_0-esp-2021r1
│ └── xtensa-esp32-elf
└── xtensa-esp32s2-elf-gcc
└── gcc8_4_0-esp-2021r1
└── xtensa-esp32s2-elf23 directories, 7 files
Open ~/.arduino15/packages/esp32/hardware/esp32/2.0.0/platform.txt
and change the compiler.path
setting from
compiler.path={runtime.tools.{build.tarch}-{build.target}-elf-gcc.path}/bin/
to
compiler.path={runtime.tools.{build.tarch}-{build.target}-elf-gcc.path}/{build.tarch}-{build.target}-elf/bin/
Then, restart the Arduino IDE.
Basic Arduino Sketch Demo
.
Create a new Arduino sketch and choose the ESP32-S2 or ESP32-C3 as the target board.
Build and upload the sketch to the target board.
After a successful upload, open the Arduino Serial Monitor to see the serial output from the ESP32 board.