ESP-IDF: Difference between revisions

From NixOS Wiki
imported>Mic92
No edit summary
imported>Mse63
pkgconfig has been replaced by pkg-config
 
(10 intermediate revisions by 6 users not shown)
Line 1: Line 1:
[https://github.com/espressif/esp-idf ESP-IDF] is the official framework to develop programs for the Espressif Systems [https://en.wikipedia.org/wiki/ESP32 ESP32] series microcontrollers.
[https://github.com/espressif/esp-idf ESP-IDF] is the official framework to develop programs for the Espressif Systems [https://en.wikipedia.org/wiki/ESP32 ESP32] series microcontrollers.
This guide explains how to install and use ESP-IDF on NixOS (I have not tested this on non-NixOS systems, but it might also work).
This guide explains how to install and use ESP-IDF on NixOS.


== Setting up the toolchain ==
== The easy way ==
ESP-IDF uses the Xtensa ESP32 GCC toolchain. Espressif hosts [https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz prebuilt binaries] on their website. Sadly, these are not statically compiled, and do not work on NixOS without the use of a FHS environment. I will use <code>buildFHSUserEnv</code> to make the binaries work. Let's make a derivation out of this:
The ESP32 toolchain and ESP-IDF have been packaged in https://github.com/mirrexagon/nixpkgs-esp-dev. If you have Nix 2.4 or later, you can get a shell with everything you need to build ESP-IDF projects for ESP32 with this command (no need to download anything yourself):
 
<syntaxhighlight lang="sh">
nix --experimental-features 'nix-command flakes' develop github:mirrexagon/nixpkgs-esp-dev#esp32-idf
</syntaxhighlight>
 
If you have an older version of Nix that doesn't support flakes, you can clone the repo and use one of the included shell files:
 
<syntaxhighlight lang="sh">
mkdir ~/esp
cd ~/esp
git clone https://github.com/mirrexagon/nixpkgs-esp-dev.git
cd nixpkgs-esp-dev
nix-shell shells/esp32-idf.nix
</syntaxhighlight>
 
See the [https://github.com/mirrexagon/nixpkgs-esp-dev#readme README] for more information.
 
== The manual way ==
If you want to set up the environment yourself, here is one way to do it.
 
=== Setting up the toolchain ===
ESP-IDF uses the Xtensa or risc-v32 ESP32 GCC toolchain. Espressif hosts the official [https://github.com/espressif/crosstool-NG/releases prebuilt binaries] on GitHub. Sadly, these are not statically compiled, and do not work on NixOS without the use of a FHS environment. I will use <code>buildFHSUserEnv</code> to make the binaries work. Let's make a derivation out of this:


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
{ stdenv, fetchurl, makeWrapper, buildFHSUserEnv }:
{ stdenv, lib, fetchurl, makeWrapper, buildFHSUserEnv }:


let
let
Line 17: Line 39:


stdenv.mkDerivation rec {
stdenv.mkDerivation rec {
   name = "esp32-toolchain";
   pname = "esp32-toolchain";
   version = "1.22.0";
   version = "2021r2-patch3";


   src = fetchurl {
   src = fetchurl {
    url = "https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz";
#    url = "https://github.com/espressif/crosstool-NG/releases/download/esp-${version}/riscv32-esp-elf-gcc8_4_0-esp-${version}-linux-amd64.tar.gz";
     sha256 = "0mji8jq1dg198z8bl50i0hs3drdqa446kvf6xpjx9ha63lanrs9z";
#    hash = "sha256-F5y61Xl5CtNeD0FKGNkAF8DxWMOXAiQRqOmGfbIXTxU=";
    url = "https://github.com/espressif/crosstool-NG/releases/download/esp-${version}/xtensa-esp32-elf-gcc8_4_0-esp-${version}-linux-amd64.tar.gz";
     hash = "sha256-nt0ed2J2iPQ1Vhki0UKZ9qACG6H2/2fkcuEQhpWmnlM=";
   };
   };


Line 40: Line 64:
   '';
   '';


   meta = with stdenv.lib; {
   meta = with lib; {
     description = "ESP32 toolchain";
     description = "ESP32 toolchain";
     homepage = https://docs.espressif.com/projects/esp-idf/en/stable/get-started/linux-setup.html;
     homepage = https://docs.espressif.com/projects/esp-idf/en/stable/get-started/linux-setup.html;
Line 51: Line 75:
{{note| You can choose any other location instead of <code>~/esp</code>. This guide assumes that the location is <code>~/esp</code>.}}
{{note| You can choose any other location instead of <code>~/esp</code>. This guide assumes that the location is <code>~/esp</code>.}}


== Setting up ESP-IDF and the development shell ==
=== Setting up ESP-IDF and the development shell ===
Clone the [https://github.com/espressif/esp-idf Espressif/esp-idf] repository:
Clone the [https://github.com/espressif/esp-idf espressif/esp-idf] repository:
<syntaxhighlight lang="sh">
<syntaxhighlight lang="sh">
cd ~/esp
cd ~/esp
Line 58: Line 82:
</syntaxhighlight>
</syntaxhighlight>


Now that we have ESP-IDF in place, it's time to set up the nix-shell environment with all the dependencies we need:
Now that we have ESP-IDF in place, it's time to set up the <code>nix-shell</code> environment with all the dependencies we need.


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
{ nixpkgs ? import <nixpkgs> {} }:
{ pkgs ? import <nixpkgs> {} }:
 
pkgs.mkShell {
  name = "esp-idf-env";
  buildInputs = with pkgs; [
    (pkgs.callPackage ./esp32-toolchain.nix {})
 
    git
    wget
    gnumake
 
    flex
    bison
    gperf
    pkg-config


let
    cmake
  inherit (nixpkgs) pkgs;
 
    ncurses5


  # esp-idf as of Nov 2019 requires pyparsing < 2.4
     ninja
  python2 = let
     packageOverrides = self: super: {
            pyparsing = super.pyparsing.overridePythonAttrs( old: rec {
                version = "2.3.1";
                src = super.fetchPypi {
                    pname="pyparsing";
                    inherit version;
                    sha256="66c9268862641abcac4a96ba74506e594c884e3f57690a696d21ad8210ed667a";
                };
        });
    };
    in pkgs.python2.override{inherit packageOverrides; self= python2;};
in


pkgs.stdenv.mkDerivation {
     (python3.withPackages (p: with p; [
  name = "esp-idf-env";
      pip
  src = ./esp-idf;
      virtualenv
  dontBuild = true;
    ]))
  dontConfigure = true;
  buildInputs = with pkgs; [
    gawk gperf gettext automake bison flex texinfo help2man libtool autoconf ncurses5 cmake glibcLocales
     (python2.withPackages (ppkgs: with ppkgs; [ pyserial future cryptography setuptools pyelftools pyparsing click ]))
    (pkgs.callPackage ~/esp/esp32-toolchain.nix {})
   ];
   ];
   shellHook = ''
   shellHook = ''
     export NIX_CFLAGS_LINK=-lncurses
     export IDF_PATH=$(pwd)/esp-idf
     export IDF_PATH=$HOME/esp/esp-idf
     export PATH=$IDF_PATH/tools:$PATH
     export IDF_TOOLS_PATH=$HOME/esp/esp-idf/tools
     export IDF_PYTHON_ENV_PATH=$(pwd)/.python_env
     export PATH="$IDF_TOOLS_PATH:$PATH"
 
    if [ ! -e $IDF_PYTHON_ENV_PATH ]; then
      python -m venv $IDF_PYTHON_ENV_PATH
      . $IDF_PYTHON_ENV_PATH/bin/activate
      pip install -r $IDF_PATH/requirements.txt
     else
      . $IDF_PYTHON_ENV_PATH/bin/activate
    fi
   '';
   '';
}
}
</syntaxhighlight>
</syntaxhighlight>


Save this as <code>~/esp/default.nix</code>.
Save this as <code>~/esp/shell.nix</code>.


You can now enter the development shell with the ESP32 toolchain and dependencies of ESP-IDF:
You can now enter the development shell with the ESP32 toolchain and dependencies of ESP-IDF:
<syntaxhighlight lang="sh">
<syntaxhighlight lang="sh">
cd ~/esp
cd ~/esp
nix-shell .
nix-shell
</syntaxhighlight>
</syntaxhighlight>
{{note|This environment uses a Python virtual environment and pip to get all the necessary Python dependencies, which is easier to keep up to date than using Python packages from Nix (at the cost of some reproducibility). The virtual environment is created if it doesn't already exist. When updating ESP-IDF, delete the <code>.python_env</code> directory and re-run <code>nix-shell</code>.}}


That's all you need to start developing with ESP-IDF on NixOS!
That's all you need to start developing with ESP-IDF on NixOS!
Line 113: Line 144:
== See also ==
== See also ==


* [https://github.com/bgamari/esp32.nix esp32.nix] provides nix expression for building the exp32 sdk as well as micropython.
* [https://github.com/bgamari/esp32.nix esp32.nix] provides nix expression for building the esp32 sdk as well as micropython.
* [https://github.com/taktoa/esp32-baremetal esp32-baremetal] has an example how to build esp32 firmware without relying on an sdk.
* [https://specific.solutions.limited/projects/hanging-plotter/electronics tutorial] for setting up the prebuilt toolchain with vscode


[[Category:Guide]]
[[Category:Guide]]

Latest revision as of 18:34, 14 January 2024

ESP-IDF is the official framework to develop programs for the Espressif Systems ESP32 series microcontrollers. This guide explains how to install and use ESP-IDF on NixOS.

The easy way

The ESP32 toolchain and ESP-IDF have been packaged in https://github.com/mirrexagon/nixpkgs-esp-dev. If you have Nix 2.4 or later, you can get a shell with everything you need to build ESP-IDF projects for ESP32 with this command (no need to download anything yourself):

nix --experimental-features 'nix-command flakes' develop github:mirrexagon/nixpkgs-esp-dev#esp32-idf

If you have an older version of Nix that doesn't support flakes, you can clone the repo and use one of the included shell files:

mkdir ~/esp
cd ~/esp
git clone https://github.com/mirrexagon/nixpkgs-esp-dev.git
cd nixpkgs-esp-dev
nix-shell shells/esp32-idf.nix

See the README for more information.

The manual way

If you want to set up the environment yourself, here is one way to do it.

Setting up the toolchain

ESP-IDF uses the Xtensa or risc-v32 ESP32 GCC toolchain. Espressif hosts the official prebuilt binaries on GitHub. Sadly, these are not statically compiled, and do not work on NixOS without the use of a FHS environment. I will use buildFHSUserEnv to make the binaries work. Let's make a derivation out of this:

{ stdenv, lib, fetchurl, makeWrapper, buildFHSUserEnv }:

let
  fhsEnv = buildFHSUserEnv {
    name = "esp32-toolchain-env";
    targetPkgs = pkgs: with pkgs; [ zlib ];
    runScript = "";
  };
in

stdenv.mkDerivation rec {
  pname = "esp32-toolchain";
  version = "2021r2-patch3";

  src = fetchurl {
#    url = "https://github.com/espressif/crosstool-NG/releases/download/esp-${version}/riscv32-esp-elf-gcc8_4_0-esp-${version}-linux-amd64.tar.gz";
#    hash = "sha256-F5y61Xl5CtNeD0FKGNkAF8DxWMOXAiQRqOmGfbIXTxU=";
    url = "https://github.com/espressif/crosstool-NG/releases/download/esp-${version}/xtensa-esp32-elf-gcc8_4_0-esp-${version}-linux-amd64.tar.gz";
    hash = "sha256-nt0ed2J2iPQ1Vhki0UKZ9qACG6H2/2fkcuEQhpWmnlM=";
  };

  buildInputs = [ makeWrapper ];

  phases = [ "unpackPhase" "installPhase" ];

  installPhase = ''
    cp -r . $out
    for FILE in $(ls $out/bin); do
      FILE_PATH="$out/bin/$FILE"
      if [[ -x $FILE_PATH ]]; then
        mv $FILE_PATH $FILE_PATH-unwrapped
        makeWrapper ${fhsEnv}/bin/esp32-toolchain-env $FILE_PATH --add-flags "$FILE_PATH-unwrapped"
      fi
    done
  '';

  meta = with lib; {
    description = "ESP32 toolchain";
    homepage = https://docs.espressif.com/projects/esp-idf/en/stable/get-started/linux-setup.html;
    license = licenses.gpl3;
  };
}

Create a new directory ~/esp and save this derivation as ~/esp/esp-toolchain.nix.

Note: You can choose any other location instead of ~/esp. This guide assumes that the location is ~/esp.

Setting up ESP-IDF and the development shell

Clone the espressif/esp-idf repository:

cd ~/esp
git clone --recursive https://github.com/espressif/esp-idf.git

Now that we have ESP-IDF in place, it's time to set up the nix-shell environment with all the dependencies we need.

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
  name = "esp-idf-env";
  buildInputs = with pkgs; [
    (pkgs.callPackage ./esp32-toolchain.nix {})

    git
    wget
    gnumake

    flex
    bison
    gperf
    pkg-config

    cmake

    ncurses5

    ninja

    (python3.withPackages (p: with p; [
      pip
      virtualenv
    ]))
  ];

  shellHook = ''
    export IDF_PATH=$(pwd)/esp-idf
    export PATH=$IDF_PATH/tools:$PATH
    export IDF_PYTHON_ENV_PATH=$(pwd)/.python_env

    if [ ! -e $IDF_PYTHON_ENV_PATH ]; then
      python -m venv $IDF_PYTHON_ENV_PATH
      . $IDF_PYTHON_ENV_PATH/bin/activate
      pip install -r $IDF_PATH/requirements.txt
    else
      . $IDF_PYTHON_ENV_PATH/bin/activate
    fi
  '';
}

Save this as ~/esp/shell.nix.

You can now enter the development shell with the ESP32 toolchain and dependencies of ESP-IDF:

cd ~/esp
nix-shell
Note: This environment uses a Python virtual environment and pip to get all the necessary Python dependencies, which is easier to keep up to date than using Python packages from Nix (at the cost of some reproducibility). The virtual environment is created if it doesn't already exist. When updating ESP-IDF, delete the .python_env directory and re-run nix-shell.

That's all you need to start developing with ESP-IDF on NixOS! The next step is to follow the ESP-IDF Get Started guide from section "Start a project" onward.

See also

  • esp32.nix provides nix expression for building the esp32 sdk as well as micropython.
  • esp32-baremetal has an example how to build esp32 firmware without relying on an sdk.
  • tutorial for setting up the prebuilt toolchain with vscode