From 191557db023bb0b2bb340bcd6e9510a06e361915 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 8 Aug 2018 17:58:00 +1000 Subject: [PATCH] docs: Copy CMake docs to a separate set of directories Required first step before merging back to mainline. --- docs/_static/what-you-need-cmake.png | Bin 0 -> 113695 bytes docs/en/api-guides/build-system-cmake.rst | 942 +++++++++++++++++ docs/en/api-guides/build-system.rst | 992 ++++++------------ docs/en/api-guides/gnu-make-build-system.rst | 55 - docs/en/api-guides/index.rst | 1 + docs/en/cmake-pending-features.rst | 10 + docs/en/cmake-warning.rst | 4 + .../add-idf_path-to-profile.rst | 73 ++ docs/en/get-started-cmake/eclipse-setup.rst | 10 + .../establish-serial-connection.rst | 131 +++ .../get-started-devkitc-v2.rst | 80 ++ .../get-started-cmake/get-started-devkitc.rst | 114 ++ .../get-started-pico-kit-v3.rst | 67 ++ .../get-started-pico-kit.rst | 213 ++++ .../get-started-wrover-kit-v2.rst | 192 ++++ .../get-started-wrover-kit.rst | 413 ++++++++ docs/en/get-started-cmake/idf-monitor.rst | 135 +++ docs/en/get-started-cmake/index.rst | 464 ++++++++ .../get-started-cmake/linux-setup-scratch.rst | 73 ++ docs/en/get-started-cmake/linux-setup.rst | 112 ++ .../get-started-cmake/macos-setup-scratch.rst | 83 ++ docs/en/get-started-cmake/macos-setup.rst | 90 ++ .../toolchain-setup-scratch.rst | 25 + .../windows-setup-scratch.rst | 89 ++ docs/en/get-started-cmake/windows-setup.rst | 71 ++ .../get-started/add-idf_path-to-profile.rst | 72 +- docs/en/get-started/eclipse-setup-windows.rst | 79 ++ docs/en/get-started/eclipse-setup.rst | 104 +- .../establish-serial-connection.rst | 3 +- docs/en/get-started/idf-monitor.rst | 9 +- docs/en/get-started/index.rst | 259 ++--- docs/en/get-started/linux-setup-scratch.rst | 21 +- docs/en/get-started/linux-setup.rst | 13 +- docs/en/get-started/macos-setup-scratch.rst | 28 +- docs/en/get-started/macos-setup.rst | 32 +- docs/en/get-started/windows-setup-scratch.rst | 143 ++- docs/en/get-started/windows-setup.rst | 67 +- docs/en/index.rst | 4 +- docs/zh_CN/api-guides/build-system-cmake.rst | 1 + .../api-guides/gnu-make-build-system.rst | 1 - docs/zh_CN/cmake-pending-features.rst | 1 + docs/zh_CN/cmake-warning.rst | 1 + .../add-idf_path-to-profile.rst | 1 + .../zh_CN/get-started-cmake/eclipse-setup.rst | 1 + .../establish-serial-connection.rst | 1 + .../get-started-devkitc-v2.rst | 1 + .../get-started-cmake/get-started-devkitc.rst | 1 + .../get-started-pico-kit-v3.rst | 1 + .../get-started-pico-kit.rst | 1 + .../get-started-wrover-kit-v2.rst | 1 + .../get-started-wrover-kit.rst | 1 + docs/zh_CN/get-started-cmake/idf-monitor.rst | 1 + docs/zh_CN/get-started-cmake/index.rst | 1 + .../get-started-cmake/linux-setup-scratch.rst | 1 + docs/zh_CN/get-started-cmake/linux-setup.rst | 1 + .../get-started-cmake/macos-setup-scratch.rst | 1 + docs/zh_CN/get-started-cmake/macos-setup.rst | 1 + .../toolchain-setup-scratch.rst | 1 + .../windows-setup-scratch.rst | 1 + .../zh_CN/get-started-cmake/windows-setup.rst | 1 + .../get-started/eclipse-setup-windows.rst | 82 ++ docs/zh_CN/get-started/eclipse-setup.rst | 103 +- docs/zh_CN/index.rst | 1 + tools/idf.py | 2 +- tools/kconfig_new/confgen.py | 3 + 65 files changed, 4364 insertions(+), 1122 deletions(-) create mode 100644 docs/_static/what-you-need-cmake.png create mode 100644 docs/en/api-guides/build-system-cmake.rst delete mode 100644 docs/en/api-guides/gnu-make-build-system.rst create mode 100644 docs/en/cmake-pending-features.rst create mode 100644 docs/en/cmake-warning.rst create mode 100644 docs/en/get-started-cmake/add-idf_path-to-profile.rst create mode 100644 docs/en/get-started-cmake/eclipse-setup.rst create mode 100644 docs/en/get-started-cmake/establish-serial-connection.rst create mode 100644 docs/en/get-started-cmake/get-started-devkitc-v2.rst create mode 100644 docs/en/get-started-cmake/get-started-devkitc.rst create mode 100644 docs/en/get-started-cmake/get-started-pico-kit-v3.rst create mode 100644 docs/en/get-started-cmake/get-started-pico-kit.rst create mode 100644 docs/en/get-started-cmake/get-started-wrover-kit-v2.rst create mode 100644 docs/en/get-started-cmake/get-started-wrover-kit.rst create mode 100644 docs/en/get-started-cmake/idf-monitor.rst create mode 100644 docs/en/get-started-cmake/index.rst create mode 100644 docs/en/get-started-cmake/linux-setup-scratch.rst create mode 100644 docs/en/get-started-cmake/linux-setup.rst create mode 100644 docs/en/get-started-cmake/macos-setup-scratch.rst create mode 100644 docs/en/get-started-cmake/macos-setup.rst create mode 100644 docs/en/get-started-cmake/toolchain-setup-scratch.rst create mode 100644 docs/en/get-started-cmake/windows-setup-scratch.rst create mode 100644 docs/en/get-started-cmake/windows-setup.rst create mode 100644 docs/en/get-started/eclipse-setup-windows.rst create mode 100644 docs/zh_CN/api-guides/build-system-cmake.rst delete mode 100644 docs/zh_CN/api-guides/gnu-make-build-system.rst create mode 100644 docs/zh_CN/cmake-pending-features.rst create mode 100644 docs/zh_CN/cmake-warning.rst create mode 100644 docs/zh_CN/get-started-cmake/add-idf_path-to-profile.rst create mode 100644 docs/zh_CN/get-started-cmake/eclipse-setup.rst create mode 100644 docs/zh_CN/get-started-cmake/establish-serial-connection.rst create mode 100644 docs/zh_CN/get-started-cmake/get-started-devkitc-v2.rst create mode 100644 docs/zh_CN/get-started-cmake/get-started-devkitc.rst create mode 100644 docs/zh_CN/get-started-cmake/get-started-pico-kit-v3.rst create mode 100644 docs/zh_CN/get-started-cmake/get-started-pico-kit.rst create mode 100644 docs/zh_CN/get-started-cmake/get-started-wrover-kit-v2.rst create mode 100644 docs/zh_CN/get-started-cmake/get-started-wrover-kit.rst create mode 100644 docs/zh_CN/get-started-cmake/idf-monitor.rst create mode 100644 docs/zh_CN/get-started-cmake/index.rst create mode 100644 docs/zh_CN/get-started-cmake/linux-setup-scratch.rst create mode 100644 docs/zh_CN/get-started-cmake/linux-setup.rst create mode 100644 docs/zh_CN/get-started-cmake/macos-setup-scratch.rst create mode 100644 docs/zh_CN/get-started-cmake/macos-setup.rst create mode 100644 docs/zh_CN/get-started-cmake/toolchain-setup-scratch.rst create mode 100644 docs/zh_CN/get-started-cmake/windows-setup-scratch.rst create mode 100644 docs/zh_CN/get-started-cmake/windows-setup.rst create mode 100644 docs/zh_CN/get-started/eclipse-setup-windows.rst diff --git a/docs/_static/what-you-need-cmake.png b/docs/_static/what-you-need-cmake.png new file mode 100644 index 0000000000000000000000000000000000000000..b98d2bbfd2004829a5ff60b156fddefa98b22877 GIT binary patch literal 113695 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"MgbTo9cs>Mu@6l3ugtW7Q~O35miB3qGLsX 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 literal 0 HcmV?d00001 diff --git a/docs/en/api-guides/build-system-cmake.rst b/docs/en/api-guides/build-system-cmake.rst new file mode 100644 index 000000000..b7aae2dda --- /dev/null +++ b/docs/en/api-guides/build-system-cmake.rst @@ -0,0 +1,942 @@ +Build System (CMake) +******************** + +.. include:: ../cmake-warning.rst + +.. include:: ../cmake-pending-features.rst + +This document explains the implementation of the CMake-based ESP-IDF build system and the concept of "components". :doc:`Documentation for the GNU Make based build system ` is also available + +Read this document if you want to know how to organise and build a new ESP-IDF project or component using the CMake-based build system. + + +Overview +======== + +An ESP-IDF project can be seen as an amalgamation of a number of components. +For example, for a webserver that shows the current humidity, there could be: + +- The ESP32 base libraries (libc, ROM bindings, etc) +- The WiFi drivers +- A TCP/IP stack +- The FreeRTOS operating system +- A webserver +- A driver for the humidity sensor +- Main code tying it all together + +ESP-IDF makes these components explicit and configurable. To do that, +when a project is compiled, the build system will look up all the +components in the ESP-IDF directories, the project directories and +(optionally) in additional custom component directories. It then +allows the user to configure the ESP-IDF project using a a text-based +menu system to customize each component. After the components in the +project are configured, the build system will compile the project. + +Concepts +-------- + +- A "project" is a directory that contains all the files and configuration to build a single "app" (executable), as well as additional supporting elements such as a partition table, data/filesystem partitions, and a bootloader. + +- "Project configuration" is held in a single file called ``sdkconfig`` in the root directory of the project. This configuration file is modified via ``idf.py menuconfig`` to customise the configuration of the project. A single project contains exactly one project configuration. + +- An "app" is an executable which is built by ESP-IDF. A single project will usually build two apps - a "project app" (the main executable, ie your custom firmware) and a "bootloader app" (the initial bootloader program which launches the project app). + +- "components" are modular pieces of standalone code which are compiled into static libraries (.a files) and linked into an app. Some are provided by ESP-IDF itself, others may be sourced from other places. + +Some things are not part of the project: + +- "ESP-IDF" is not part of the project. Instead it is standalone, and linked to the project via the ``IDF_PATH`` environment variable which holds the path of the ``esp-idf`` directory. This allows the IDF framework to be decoupled from your project. + +- The toolchain for compilation is not part of the project. The toolchain should be installed in the system command line PATH. + +Using the Build System +====================== + +.. _idf.py: + +idf.py +------ + +The ``idf.py`` command line tool provides a front-end for easily managing your project builds. It manages the following tools: + +- CMake_, which configures the project to be built +- A command line build tool (either Ninja_ build or `GNU Make`) +- `esptool.py`_ for flashing ESP32. + +The :ref:`getting started guide ` contains a brief introduction to how to set up ``idf.py`` to configure, build, and flash projects. + +``idf.py`` should be run in an ESP-IDF "project" directory, ie one containing a ``CMakeLists.txt`` file. Older style projects with a Makefile will not work with ``idf.py``. + +Type ``idf.py --help`` for a full list of commands. Here are a summary of the most useful ones: + +- ``idf.py menuconfig`` runs the "menuconfig" tool to configure the project. +- ``idf.py build`` will build the project found in the current directory. This can involve multiple steps: + + - Create the build directory if needed. The sub-directory ``build`` is used to hold build output, although this can be changed with the ``-B`` option. + - Run CMake_ as necessary to configure the project and generate build files for the main build tool. + - Run the main build tool (Ninja_ or `GNU Make`). By default, the build tool is automatically detected but it can be explicitly set by passing the ``-G`` option to ``idf.py``. + + Building is incremental so if no source files or configuration has changed since the last build, nothing will be done. +- ``idf.py clean`` will "clean" the project by deleting build output files from the build directory, forcing a "full rebuild" the next time the project is built. Cleaning doesn't delete CMake configuration output and some other files. +- ``idf.py fullclean`` will delete the entire "build" directory contents. This includes all CMake configuration output. The next time the project is built, CMake will configure it from scratch. Note that this option recursively deletes *all* files in the build directory, so use with care. Project configuration is not deleted. +- ``idf.py reconfigure`` re-runs CMake_ even if it doesn't seem to need re-running. This isn't necessary during normal usage, but can be useful after adding/removing files from the source tree. +- ``idf.py flash`` will automatically build the project if necessary, and then flash it to an ESP32. The ``-p`` and ``-b`` options can be used to set serial port name and flasher baud rate, respectively. +- ``idf.py monitor`` will display serial output from the ESP32. The ``-p`` option can be used to set the serial port name. Type ``Ctrl-]`` to exit the monitor. See :doc:`/get-started/idf-monitor` for more details about using the monitor. + +Multiple ``idf.py`` commands can be combined into one. For example, ``idf.py -p COM4 clean flash monitor`` will clean the source tree, then build the project and flash it to the ESP32 before running the serial monitor. + +.. note:: The environment variables ``ESPPORT`` and ``ESPBAUD`` can be used to set default values for the ``-p`` and ``-b`` options, respectively. Providing these options on the command line overrides the default. + +Advanced Commands +^^^^^^^^^^^^^^^^^ + +- ``idf.py app``, ``idf.py bootloader``, ``idf.py partition_table`` can be used to build only the app, bootloader, or partition table from the project as applicable. +- There are matching commands ``idf.py app-flash``, etc. to flash only that single part of the project to the ESP32. +- ``idf.py -p PORT erase_flash`` will use esptool.py to erase the ESP32's entire flash chip. +- ``idf.py size`` prints some size information about the app. ``size-components`` and ``size-files`` are similar commands which print more detailed per-component or per-source-file information, respectively. + +The order of multiple ``idf.py`` commands on the same invocation is not important, they will automatically be executed in the correct order for everything to take effect (ie building before flashing, erasing before flashing, etc.). + +Using CMake Directly +-------------------- + +:ref:`idf.py` is a wrapper around CMake_ for convenience. However, you can also invoke CMake directly if you prefer. + +.. highlight:: bash + +When ``idf.py`` does something, it prints each command that it runs for easy reference. For example, the ``idf.py build`` command is the same as running these commands in a bash shell (or similar commands for Windows Command Prompt):: + + mkdir -p build + cd build + cmake .. -G Ninja # or 'Unix Makefiles' + ninja + +In the above list, the ``cmake`` command configures the project and generates build files for use with the final build tool. In this case the final build tool is Ninja_: running ``ninja`` actually builds the project. + +It's not necessary to run ``cmake`` more than once. After the first build, you only need to run ``ninja`` each time. ``ninja`` will automatically re-invoke ``cmake`` if the project needs reconfiguration. + +If using CMake with ``ninja`` or ``make``, there are also targets for more of the ``idf.py`` sub-commands - for example running ``make menuconfig`` or ``ninja menuconfig`` in the build directory will work the same as ``idf.py menuconfig``. + +.. note:: + If you're already familiar with CMake_, you may find the ESP-IDF CMake-based build system unusual because it wraps a lot of CMake's functionality to reduce boilerplate. See `writing pure CMake components`_ for some information about writing more "CMake style" components. + +Using CMake in an IDE +--------------------- + +You can also use an IDE with CMake integration. The IDE will want to know the path to the project's ``CMakeLists.txt`` file. IDEs with CMake integration often provide their own build tools (CMake calls these "generators") to build the source files as part of the IDE. + +When adding custom non-build steps like "flash" to the IDE, it is recommended to execute ``idf.py`` for these "special" commands. + +For more detailed information about integrating ESP-IDF with CMake into an IDE, see `Build System Metadata`_. + +.. setting-python-interpreter: + +Setting the Python Interpreter +------------------------------ + +Currently, ESP-IDF only works with Python 2.7. If you have a system where the default ``python`` interpreter is Python 3.x, this can lead to problems. + +If using ``idf.py``, running ``idf.py`` as ``python2 $IDF_PATH/tools/idf.py ...`` will work around this issue (``idf.py`` will tell other Python processes to use the same Python interpreter). You can set up a shell alias or another script to simplify the command. + +If using CMake directly, running ``cmake -D PYTHON=python2 ...`` will cause CMake to override the default Python interpreter. + +If using an IDE with CMake, setting the ``PYTHON`` value as a CMake cache override in the IDE UI will override the default Python interpreter. + +To manage the Python version more generally via the command line, check out the tools pyenv_ or virtualenv_. These let you change the default python version. + +.. _example-project-structure: + +Example Project +=============== + +.. highlight:: none + +An example project directory tree might look like this:: + + - myProject/ + - CMakeLists.txt + - sdkconfig + - components/ - component1/ - CMakeLists.txt + - Kconfig + - src1.c + - component2/ - CMakeLists.txt + - Kconfig + - src1.c + - include/ - component2.h + - main/ - src1.c + - src2.c + + - build/ + +This example "myProject" contains the following elements: + +- A top-level project CMakeLists.txt file. This is the primary file which CMake uses to learn how to build the project. The project CMakeLists.txt file sets the ``MAIN_SRCS`` variable which lists all of the source files in the "main" directory (part of this project's executable). It may set other project-wide CMake variables, as well. Then it includes the file :idf_file:`/tools/cmake/project.cmake` which + implements the rest of the build system. Finally, it sets the project name and defines the project. + +- "sdkconfig" project configuration file. This file is created/updated when ``idf.py menuconfig`` runs, and holds configuration for all of the components in the project (including ESP-IDF itself). The "sdkconfig" file may or may not be added to the source control system of the project. + +- Optional "components" directory contains components that are part of the project. A project does not have to contain custom components of this kind, but it can be useful for structuring reusable code or including third party components that aren't part of ESP-IDF. + +- "main" directory is a special "by convention" directory that contains source code for the project executable itself. These source files are listed in the project's CMakeLists file. You don't need to name this directory "main", but we recommend you follow this convention. If you have a lot of source files in your project, we recommend grouping most into components instead of putting them all in "main". + +- "build" directory is where build output is created. This directory is created by ``idf.py`` if it doesn't already exist. CMake configures the project and generates interim build files in this directory. Then, after the main build process is run, this directory will also contain interim object files and libraries as well as final binary output files. This directory is usually not added to source control or distributed with the project source code. + +Component directories each contain a component ``CMakeLists.txt`` file. This file contains variable definitions +to control the build process of the component, and its integration into the overall project. See `Component CMakeLists Files`_ for more details. + +Each component may also include a ``Kconfig`` file defining the `component configuration`_ options that can be set via ``menuconfig``. Some components may also include ``Kconfig.projbuild`` and ``project_include.cmake`` files, which are special files for `overriding parts of the project`_. + +Project CMakeLists File +======================= + +Each project has a single top-level ``CMakeLists.txt`` file that contains build settings for the entire project. By default, the project CMakeLists can be quite minimal. + +Minimal Example CMakeLists +-------------------------- + +.. highlight:: cmake + +Minimal project:: + + cmake_minimum_required(VERSION 3.5) + + set(MAIN_SRCS main/src1.c main/src2.c) + + include($ENV{IDF_PATH}/tools/cmake/project.cmake) + project(myProject) + + +.. _project-mandatory-parts: + +Mandatory Parts +--------------- + +The inclusion of these four lines, in the order shown above, is necessary for every project: + +- ``cmake_minimum_required(VERSION 3.5)`` tells CMake what version is required to build the project. ESP-IDF is designed to work with CMake 3.5 or newer. This line must be the first line in the CMakeLists.txt file. +- ``set(MAIN_SRCS xxx)`` sets a variable - ``MAIN_SRCS`` to be a list of the "main" source files in the project. Paths are relative to the CMakeLists. They don't specifically need to be under the "main" sub-directory, but this structure is encouraged. + + It is *strongly recommended not to add a lot of files to the MAIN_SRCS list*. If you have a lot of source files then it recommended to organise them functionally into individual components under the project "components" directory. This will make your project more maintainable, reusable, and easier to configure. Components are further explained below. + + ``MAIN_SRCS`` must name at least one source file (although that file doesn't need to necessarily include an ``app_main()`` function or anything else). +- ``include($ENV{IDF_PATH}/tools/cmake/project.cmake)`` pulls in the rest of the CMake functionality to configure the project, discover all the components, etc. +- ``project(myProject)`` creates the project itself, and specifies the project name. The project name is used for the final binary output files of the app - ie ``myProject.elf``, ``myProject.bin``. Only one project can be defined per CMakeLists file. + + +Optional Project Variables +-------------------------- + +These variables all have default values that can be overridden for custom behaviour. Look in :idf_file:`/tools/cmake/project.cmake` for all of the implementation details. + +- ``COMPONENT_DIRS``: Directories to search for components. Defaults to `${IDF_PATH}/components`, `${PROJECT_PATH}/components`, and ``EXTRA_COMPONENT_DIRS``. Override this variable if you don't want to search for components in these places. +- ``EXTRA_COMPONENT_DIRS``: Optional list of additional directories to search for components. Paths can be relative to the project directory, or absolute. +- ``COMPONENTS``: A list of component names to build into the project. Defaults to all components found in the ``COMPONENT_DIRS`` directories. Use this variable to "trim down" the project for faster build times. Note that any component which "requires" another component via ``COMPONENT_REQUIRES`` will automatically have it added to this list, so the ``COMPONENTS`` list can be very short. +- ``COMPONENT_REQUIRES_COMMON``: A list of components that every component requires. These components are automatically added to every component's ``COMPONENT_PRIV_REQUIRES`` list and also the project's ``COMPONENTS`` list. By default, this variable is set to the minimal set of core "system" components needed for any ESP-IDF project. Usually, you would not change this variable in your project. + +Any paths in these variables can be absolute paths, or set relative to the project directory. + +To set these variables, use the `cmake set command `_ ie ``set(VARIABLE "VALUE")``. The ``set()`` commands should be placed after the ``cmake_minimum(...)`` line but before the ``include(...)`` line. + +.. _component-directories-cmake: + +Component CMakeLists Files +========================== + +Each project contains one or more components. Components can be part of ESP-IDF, part of the project's own components directory, or added from custom component directories (:ref:`see above `). + +A component is any directory in the ``COMPONENT_DIRS`` list which contains a ``CMakeLists.txt`` file. + +Searching for Components +------------------------ + +The list of directories in ``COMPONENT_DIRS`` is searched for the project's components. Directories in this list can either be components themselves (ie they contain a `CMakeLists.txt` file), or they can be top-level directories whose sub-directories are components. + +When CMake runs to configure the project, it logs the components included in the build. This list can be useful for debugging the inclusion/exclusion of certain components. + +Multiple components with the same name +-------------------------------------- + +When ESP-IDF is collecting all the components to compile, it will do this in the order specified by ``COMPONENT_DIRS``; by default, this means ESP-IDF's internal components first, then the project's components, and finally any components set in ``EXTRA_COMPONENT_DIRS``. If two or more of these directories +contain component sub-directories with the same name, the component in the last place searched is used. This allows, for example, overriding ESP-IDF components +with a modified version by copying that component from the ESP-IDF components directory to the project components directory and then modifying it there. +If used in this way, the ESP-IDF directory itself can remain untouched. + +Minimal Component CMakeLists +---------------------------- + +.. highlight:: cmake + +The minimal component ``CMakeLists.txt`` file is as follows:: + + set(COMPONENT_SRCDIRS ".") + set(COMPONENT_ADD_INCLUDEDIRS "include") + register_component() + +- ``COMPONENT_SRCDIRS`` is a (space-separated) list of directories to search for source files. Source files (``*.c``, ``*.cpp``, ``*.cc``, ``*.S``) in these directories will be compiled into the component library. +- ``COMPONENT_ADD_INCLUDEDIRS`` is a (space-separated) list of directories to add to the global include search path for any component which requires this component, and also the main source files. +- ``register_component()`` is required to add the component (using the variables set above) to the build. A library with the name of the component will be built and linked into the final app. If this step is skipped (perhaps due to use of a CMake `if function `_ or similar), this component will not be part of the build. + +Directories are usually specified relative to the ``CMakeLists.txt`` file itself, although they can be absolute. + +See `example component CMakeLists`_ for more complete component ``CMakeLists.txt`` examples. + +.. _component variables: + +Preset Component Variables +-------------------------- + +The following component-specific variables are available for use inside component CMakeLists, but should not be modified: + +- ``COMPONENT_PATH``: The component directory. Evaluates to the absolute path of the directory containing ``component.mk``. The component path cannot contain spaces. This is the same as the ``CMAKE_CURRENT_SOURCE_DIR`` variable. +- ``COMPONENT_NAME``: Name of the component. Same as the name of the component directory. + +The following variables are set at the project level, but available for use in component CMakeLists: + +- ``PROJECT_NAME``: Name of the project, as set in project Makefile +- ``PROJECT_PATH``: Absolute path of the project directory containing the project Makefile. Same as the ``CMAKE_SOURCE_DIR`` variable. +- ``COMPONENTS``: Names of all components that are included in this build, formatted as a semicolon-delimited CMake list. +- ``CONFIG_*``: Each value in the project configuration has a corresponding variable available in make. All names begin with ``CONFIG_``. :doc:`More information here `. +- ``IDF_VER``: Git version of ESP-IDF (produced by ``git describe``) + +If you modify any of these variables inside ``CMakeLists.txt`` then this will not prevent other components from building but it may make your component hard to build and/or debug. + +- ``COMPONENT_ADD_INCLUDEDIRS``: Paths, relative to the component directory, which will be added to the include search path for + all other components which require this one. If an include directory is only needed to compile this specific component, + add it to ``COMPONENT_PRIV_INCLUDEDIRS`` instead. +- ``COMPONENT_REQUIRES`` is a (space-separated) list of components that are required to include this project's header files into other components. If this component has a header file in a ``COMPONENT_ADD_INCLUDEDIRS`` directory that includes a header from another component, that component should be listed in ``COMPONENT_REQUIRES``. Requirements are recursive. + + The ``COMPONENT_REQUIRES`` list can be empty because some very common components (like newlib for libc, freertos for RTOS functions, etc) are always required by all components. This list is found in the project-level variable ``COMPONENT_REQUIRES_COMMON``. + + If a component only requires another component's headers to compile its source files (not for including this component's headers), then these components should be listed in ``COMPONENT_PRIV_REQUIRES`` instead. + + See `Component Requirements`_ for more details. + +Optional Component-Specific Variables +------------------------------------- + +The following variables can be set inside ``component.mk`` to control the build of that component: + +- ``COMPONENT_PRIV_INCLUDEDIRS``: Directory paths, must be relative to + the component directory, which will be added to the include search + path for this component's source files only. +- ``COMPONENT_PRIV_REQUIRES`` is a (space-separated) list of components that are required to either compile or link this component's source files. These components' header paths do not propagate to other components which require it, they are only used to compile this component's sources. See `Component Requirements`_ for more details. +- ``COMPONENT_SRCDIRS``: Directory paths, must be relative to the component directory, which will be searched for source files (``*.cpp``, + ``*.c``, ``*.S``). Set this to specify a list of directories which contain source files. +- ``COMPONENT_SRCS``: Paths to individual source files to compile. Setting this causes ``COMPONENT_SRCDIRS`` to be ignored. Setting this variable instead gives you finer grained control over which files are compiled. + If you don't set ``COMPONENT_SRCDIRS`` or ``COMPONENT_SRCS``, your component won't compile a library but it may still add include paths for use when compiling other components or the source files listed in ``MAIN_SRCS``. +- ``COMPONENT_SRCEXCLUDE``: Paths to source files to exclude from component. Can be set in conjunction with ``COMPONENT_SRCDIRS`` if there is a directory with a large number of source files to include in the component but one or more source files which should not be. Paths can be specified relative to the component directory or absolute. + +Controlling Component Compilation +--------------------------------- + +.. highlight:: cmake + +To pass compiler options when compiling source files belonging to a particular component, use the ``component_compile_options`` function:: + + component_compile_options(-Wno-unused-variable) + +This is a wrapper around the CMake `target_compile_options`_ command. + +To apply the compilation flags to a single source file, use the CMake `set_source_files_properties`_ command:: + + set_source_files_properties(mysrc.c + PROPERTIES COMPILE_FLAGS + -Wno-unused-variable + ) + +This can be useful if there is upstream code that emits warnings. + +When using these commands, place them after the ``register_component()`` line in the component CMakeLists file. + +.. _component-configuration-cmake: + +Component Configuration +======================= + +Each component can also have a ``Kconfig`` file, alongside ``CMakeLists.txt``. This contains +configuration settings to add to the configuration menu for this component. + +These settings are found under the "Component Settings" menu when menuconfig is run. + +To create a component Kconfig file, it is easiest to start with one of the Kconfig files distributed with ESP-IDF. + +For an example, see `Adding conditional configuration`_. + +Preprocessor Definitions +======================== + +The ESP-IDF build system adds the following C preprocessor definitions on the command line: + +- ``ESP_PLATFORM`` — Can be used to detect that build happens within ESP-IDF. +- ``IDF_VER`` — Defined to a git version string. E.g. ``v2.0`` for a tagged release or ``v1.0-275-g0efaa4f`` for an arbitrary commit. + +Component Requirements +====================== + +When compiling each component, the ESP-IDF build system recursively evaluates its components. + +Each component's source file is compiled with these include path directories: + +- The current component's ``COMPONENT_ADD_INCLUDEDIRS`` and ``COMPONENT_PRIV_INCLUDEDIRS``. +- The ``COMPONENT_ADD_INCLUDEDIRS`` set by all components in the current component's ``COMPONENT_REQUIRES`` and ``COMPONENT_PRIV_REQUIRES`` variables (ie all the current component's public and private dependencies). +- All of the ``COMPONENT_REQUIRES`` of those components, evaluated recursively (ie all public dependencies of this component's dependencies, recursively expanded). + +When writing a component +------------------------ + +- ``COMPONENT_REQUIRES`` should be set to all components whose header files are #included from the *public* header files of this component. +- ``COMPONENT_PRIV_REQUIRES`` should be set to all components whose header files are #included from *any source files* of this component, unless already listed in ``COMPONENT_REQUIRES``. Or any component which is required to be linked in order for this component to function correctly. +- ``COMPONENT_REQUIRES`` and/or ``COMPONENT_PRIV_REQUIRES`` should be set before calling ``register_component()``. +- The values of ``COMPONENT_REQUIRES`` and ``COMPONENT_PRIV_REQUIRES`` should not depend on any configuration choices (``CONFIG_xxx`` macros). This is because requirements are expanded before configuration is loaded. Other component variables (like include paths or source files) can depend on configuration choices. +- Not setting either or both ``REQUIRES`` variables is fine. If the component has no requirements except for the "common" components needed for RTOS, libc, etc (``COMPONENT_REQUIRES_COMMON``) then both variables can be empty or unset. + +When creating a project +----------------------- + +- By default, every component is included in the build. +- If you set the ``COMPONENTS`` variable to a minimal list of components used directly by your project, then the build will include: + - Components mentioned explicitly in ``COMPONENTS``. + - Those components' requirements (evaluated recursively). + - The "common" components that every component depends on. +- Setting ``COMPONENTS`` to the minimal list of required components can significantly reduce compile times. +- When compiling the project's source files (``MAIN_SRCS``), the public header directories (``COMPONENT_ADD_INCLUDEDIRS`` list) of all components included in the build are available. + +.. _component-requirements-implementation: + +Requirements in the build system implementation +----------------------------------------------- + +- Very early in the CMake configuration process, the script ``expand_requirements.cmake`` is run. This script does a partial evaluation of all component CMakeLists.txt files and builds a graph of component requirements (this graph may have cycles). The graph is used to generate a file ``component_depends.cmake`` in the build directory. +- The main CMake process then includes this file and uses it to determine the list of components to include in the build (internal ``BUILD_COMPONENTS`` variable). +- Configuration is then evaluated for the components included in the build. +- Each component is included in the build normally and the CMakeLists.txt file is evaluated again to add the component libraries to the build. + +Build Process Internals +======================= + +For full details about CMake_ and CMake commands, see the `CMake v3.5 documentation`_. + +project.cmake contents +---------------------- + +When included from a project CMakeLists file, the ``project.cmake`` file defines some utility modules and global variables and then sets ``IDF_PATH`` if it was not set in the system environment. + +It also defines an overridden custom version of the built-in CMake_ ``project`` function. This function is overridden to add all of the ESP-IDF specific project functionality. + +project function +---------------- + +The custom ``project()`` function performs the following steps: + +- Evaluates component dependencies and builds the ``BUILD_COMPONENTS`` list of components to include in the build (see :ref:`above`). +- Finds all components in the project (searching ``COMPONENT_DIRS`` and filtering by ``COMPONENTS`` if this is set). +- Loads the project configuration from the ``sdkconfig`` file and generates a ``sdkconfig.cmake`` file and a ``sdkconfig.h`` header. These define configuration values in CMake and C/C++, respectively. If the project configuration changes, cmake will automatically be re-run to re-generate these files and re-configure the project. +- Sets the `CMAKE_TOOLCHAIN_FILE`_ variable to the ESP-IDF toolchain file with the Xtensa ESP32 toolchain. +- Declare the actual cmake-level project by calling the `CMake project function `_. +- Load the git version. This includes some magic which will automatically re-run CMake if a new revision is checked out in git. See `File Globbing & Incremental Builds`_. +- Include ``project_include.cmake`` files from any components which have them. +- Add each component to the build. Each component CMakeLists file calls ``register_component``, calls the CMake `add_library `_ function to add a library and then adds source files, compile options, etc. +- Add the final app executable to the build. +- Go back and add inter-component dependencies between components (ie adding the public header directories of each component to each other component). + +Browse the :idf_file:`/tools/cmake/project.cmake` file and supporting functions in :idf_file:`/tools/cmake/idf_functions.cmake` for more details. + +Debugging CMake +--------------- + +Some tips for debugging the ESP-IDF CMake-based build system: + +- When CMake runs, it prints quite a lot of diagnostic information including lists of components and component paths. +- Running ``cmake -DDEBUG=1`` will produce more verbose diagnostic output from the IDF build system. +- Running ``cmake`` with the ``--trace`` or ``--trace-expand`` options will give a lot of information about control flow. See the `cmake command line documentation`_. + +.. _warn-undefined-variables-cmake: + +Warning On Undefined Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, ``idf.py`` passes the ``--warn-uninitialized`` flag to CMake_ so it will print a warning if an undefined variable is referenced in the build. This can be very useful to find buggy CMake files. + +If you don't want this behaviour, it can be disabled by passing ``--no-warnings`` to ``idf.py``. + +Overriding Parts of the Project +------------------------------- + +project_include.cmake +^^^^^^^^^^^^^^^^^^^^^ + +For components that have build requirements which must be evaluated before any component CMakeLists +files are evaluated, you can create a file called ``project_include.cmake`` in the +component directory. This CMake file is included when ``project.cmake`` is evaluating the entire project. + +``project_include.cmake`` files are used inside ESP-IDF, for defining project-wide build features such as ``esptool.py`` command line arguments and the ``bootloader`` "special app". + +Note that ``project_include.cmake`` isn't necessary for the most common component uses - such as adding include directories to the project, or ``LDFLAGS`` to the final linking step. These values can be customised via the ``CMakeLists.txt`` file itself. See `Optional Project Variables`_ for details. + +Take great care when setting variables or targets in a ``project_include.cmake`` file. As the values are included into the top-level project CMake pass, they can influence or break functionality across all components! + +KConfig.projbuild +^^^^^^^^^^^^^^^^^ + +This is an equivalent to ``project_include.cmake`` for :ref:`component-configuration-cmake` KConfig files. If you want to include +configuration options at the top-level of menuconfig, rather than inside the "Component Configuration" sub-menu, then these can be defined in the KConfig.projbuild file alongside the ``CMakeLists.txt`` file. + +Take care when adding configuration values in this file, as they will be included across the entire project configuration. Where possible, it's generally better to create a KConfig file for :ref:`component-configuration-cmake`. + + +Configuration-Only Components +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Special components which contain no source files, only ``Kconfig.projbuild`` and ``KConfig``, can have a one-line ``CMakeLists.txt`` file which calls the function ``register_config_only_component()``. This function will include the component in the project build, but no library will be built *and* no header files will be added to any include paths. + +If a CMakeLists.txt file doesn't call ``register_component()`` or ``register_config_only_component()``, it will be excluded from the project entirely. This may sometimes be desirable, depending on the project configuration. + +Example Component CMakeLists +============================ + +Because the build environment tries to set reasonable defaults that will work most +of the time, component ``CMakeLists.txt`` can be very small or even empty (see `Minimal Component CMakeLists`_). However, overriding `component variables`_ is usually required for some functionality. + +Here are some more advanced examples of component CMakeLists files. + +Adding conditional configuration +-------------------------------- + +The configuration system can be used to conditionally compile some files +depending on the options selected in the project configuration. + +.. highlight:: none + +``Kconfig``:: + + config FOO_ENABLE_BAR + bool "Enable the BAR feature." + help + This enables the BAR feature of the FOO component. + +``CMakeLists.txt``:: + + set(COMPONENT_SRCS "foo.c" "more_foo.c") + + if(CONFIG_FOO_ENABLE_BAR) + list(APPEND COMPONENT_SRCS "bar.c") + endif(CONFIG_FOO_ENABLE_BAR) + +This example makes use of the CMake `if function `_ and `list APPEND `_ function. + +This can also be used to select or stub out an implementation, as such: + +``Kconfig``:: + + config ENABLE_LCD_OUTPUT + bool "Enable LCD output." + help + Select this if your board has a LCD. + + config ENABLE_LCD_CONSOLE + bool "Output console text to LCD" + depends on ENABLE_LCD_OUTPUT + help + Select this to output debugging output to the lcd + + config ENABLE_LCD_PLOT + bool "Output temperature plots to LCD" + depends on ENABLE_LCD_OUTPUT + help + Select this to output temperature plots + +.. highlight:: cmake + +``CMakeLists.txt``:: + + if(CONFIG_ENABLE_LCD_OUTPUT) + set(COMPONENT_SRCS lcd-real.c lcd-spi.c) + else() + set(COMPONENT_SRCS lcd-dummy.c) + endif() + + # We need font if either console or plot is enabled + if(CONFIG_ENABLE_LCD_CONSOLE OR CONFIG_ENABLE_LCD_PLOT) + list(APPEND COMPONENT_SRCS "font.c") + endif() + + +Source Code Generation +---------------------- + +Some components will have a situation where a source file isn't +supplied with the component itself but has to be generated from +another file. Say our component has a header file that consists of the +converted binary data of a BMP file, converted using a hypothetical +tool called bmp2h. The header file is then included in as C source +file called graphics_lib.c:: + + add_custom_command(OUTPUT logo.h + COMMAND bmp2h -i ${COMPONENT_PATH}/logo.bmp -o log.h + DEPENDS ${COMPONENT_PATH}/logo.bmp + VERBATIM) + + add_custom_target(logo DEPENDS logo.h) + add_dependencies(${COMPONENT_NAME} logo) + + set_property(DIRECTORY "${COMPONENT_PATH}" APPEND PROPERTY + ADDITIONAL_MAKE_CLEAN_FILES logo.h) + +This answer is adapted from the `CMake FAQ entry `_, which contains some other examples that will also work with ESP-IDF builds. + +In this example, logo.h will be generated in the +current directory (the build directory) while logo.bmp comes with the +component and resides under the component path. Because logo.h is a +generated file, it should be cleaned when the project is cleaned. For this reason +it is added to the `ADDITIONAL_MAKE_CLEAN_FILES`_ property. + +.. note:: + + If generating files as part of the project CMakeLists.txt file, not a component CMakeLists.txt, then use ``${PROJECT_PATH}`` instead of ``${COMPONENT_PATH}`` and ``${PROJECT_NAME}.elf`` instead of ``${COMPONENT_NAME}``.) + +If a a source file from another component included ``logo.h``, then ``add_dependencies`` would need to be called to add a dependency between +the two components, to ensure that the component source files were always compiled in the correct order. + +Embedding Binary Data +--------------------- + +Sometimes you have a file with some binary or text data that you'd like to make available to your component - but you don't want to reformat the file as C source. + +You can set a variable ``COMPONENT_EMBED_FILES`` in your component's CMakeLists, giving space-delimited names of the files to embed:: + + set(COMPONENT_EMBED_FILES server_root_cert.der) + +Or if the file is a string, you can use the variable ``COMPONENT_EMBED_TXTFILES``. This will embed the contents of the text file as a null-terminated string:: + + set(COMPONENT_EMBED_TXTFILES server_root_cert.pem) + +.. highlight:: c + +The file's contents will be added to the .rodata section in flash, and are available via symbol names as follows:: + + extern const uint8_t server_root_cert_pem_start[] asm("_binary_server_root_cert_pem_start"); + extern const uint8_t server_root_cert_pem_end[] asm("_binary_server_root_cert_pem_end"); + +The names are generated from the full name of the file, as given in ``COMPONENT_EMBED_FILES``. Characters /, ., etc. are replaced with underscores. The _binary prefix in the symbol name is added by objcopy and is the same for both text and binary files. + +.. highlight:: cmake + +To embed a file into a project, rather than a component, you can call the function ``target_add_binary_data`` like this:: + + target_add_binary_data(myproject.elf "main/data.bin" TEXT) + +Place this line after the ``project()`` line in your project CMakeLists.txt file. Replace ``myproject.elf`` with your project name. The final argument can be ``TEXT`` to embed a null-terminated string, or ``BINARY`` to embed the content as-is. + +For an example of using this technique, see :example:`protocols/https_request` - the certificate file contents are loaded from the text .pem file at compile time. + +.. _component-build-full-override: + +Fully Overriding The Component Build Process +-------------------------------------------- + +.. highlight:: cmake + +Obviously, there are cases where all these recipes are insufficient for a +certain component, for example when the component is basically a wrapper +around another third-party component not originally intended to be +compiled under this build system. In that case, it's possible to forego +the ESP-IDF build system entirely by using a CMake feature called ExternalProject_. Example component CMakeLists:: + + # External build process for quirc, runs in source dir and + # produces libquirc.a + externalproject_add(quirc_build + PREFIX ${COMPONENT_PATH} + SOURCE_DIR ${COMPONENT_PATH}/quirc + CONFIGURE_COMMAND "" + BUILD_IN_SOURCE 1 + BUILD_COMMAND make CC=${CMAKE_C_COMPILER} libquirc.a + INSTALL_COMMAND "" + ) + + # Add libquirc.a to the build process + # + add_library(quirc STATIC IMPORTED GLOBAL) + add_dependencies(quirc quirc_build) + + set_target_properties(quirc PROPERTIES IMPORTED_LOCATION + ${COMPONENT_PATH}/quirc/libquirc.a) + set_target_properties(quirc PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + ${COMPONENT_PATH}/quirc/lib) + + set_directory_properties( PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES + "${COMPONENT_PATH}/quirc/libquirc.a") + +(The above CMakeLists.txt can be used to create a component named ``quirc`` that builds the quirc_ project using its own Makefile.) + +- ``externalproject_add`` defines an external build system. + + - ``SOURCE_DIR``, ``CONFIGURE_COMMAND``, ``BUILD_COMMAND`` and ``INSTALL_COMMAND`` should always be set. ``CONFIGURE_COMMAND`` can be set to an empty string if the build system has no "configure" step. ``INSTALL_COMMAND`` will generally be empty for ESP-IDF builds. + - Setting ``BUILD_IN_SOURCE`` means the build directory is the same as the source directory. Otherwise you can set ``BUILD_DIR``. + - Consult the ExternalProject_ documentation for more details about ``externalproject_add()`` + +- The second set of commands adds a library target, which points to the "imported" library file built by the external system. Some properties need to be set in order to add include directories and tell CMake where this file is. +- Finally, the generated library is added to `ADDITIONAL_MAKE_CLEAN_FILES`_. This means ``make clean`` will delete this library. (Note that the other object files from the build won't be deleted.) + +.. _ADDITIONAL_MAKE_CLEAN_FILES_note: + +ExternalProject dependencies, clean builds +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +CMake has some unusual behaviour around external project builds: + +- `ADDITIONAL_MAKE_CLEAN_FILES`_ only works when "make" is used as the build system. If Ninja_ or an IDE build system is used, it won't delete these files when cleaning. +- However, the ExternalProject_ configure & build commands will *always* be re-run after a clean is run. +- Therefore, there are two alternative recommended ways to configure the external build command: + + 1. Have the external ``BUILD_COMMAND`` run a full clean compile of all sources. The build command will be run if any of the dependencies passed to ``externalproject_add`` with ``DEPENDS`` have changed, or if this is a clean build (ie any of ``idf.py clean``, ``ninja clean``, or ``make clean`` was run.) + 2. Have the external ``BUILD_COMMAND`` be an incremental build command. Pass the parameter ``BUILD_ALWAYS 1`` to ``externalproject_add``. This means the external project will be built each time a build is run, regardless of dependencies. This is only recommended if the external project has correct incremental build behaviour, and doesn't take too long to run. + +The best of these approaches for building an external project will depend on the project itself, its build system, and whether you anticipate needing to frequently recompile the project. + +.. _custom-sdkconfig-defaults-cmake: + +Custom sdkconfig defaults +========================= + +For example projects or other projects where you don't want to specify a full sdkconfig configuration, but you do want to override some key values from the ESP-IDF defaults, it is possible to create a file ``sdkconfig.defaults`` in the project directory. This file will be used when creating a new config from scratch, or when any new config value hasn't yet been set in the ``sdkconfig`` file. + +To override the name of this file, set the ``SDKCONFIG_DEFAULTS`` environment variable. + + +Flash arguments +=============== + +There are some scenarios that we want to flash the target board without IDF. For this case we want to save the built binaries, esptool.py and esptool write_flash arguments. It's simple to write a script to save binaries and esptool.py. + +After running a project build, the build directory contains binary output files (``.bin`` files) for the project and also the following flashing data files: + +- ``flash_project_args`` contains arguments to flash the entire project (app, bootloader, partition table, PHY data if this is configured). +- ``flash_app_args`` contains arguments to flash only the app. +- ``flash_bootloader_args`` contains arguments to flash only the bootloader. + +.. highlight:: bash + +You can pass any of these flasher argument files to ``esptool.py`` as follows:: + + python esptool.py --chip esp32 write_flash @build/flash_project_args + +Alternatively, it is possible to manually copy the parameters from the argument file and pass them on the command line. + +The build directory also contains a generated file ``flasher_args.json`` which contains project flash information, in JSON format. This file is used by ``idf.py`` and can also be used by other tools which need information about the project build. + +Building the Bootloader +======================= + +The bootloader is built by default as part of ``idf.py build``, or can be built standalone via ``idf.py bootloader``. + +The bootloader is a special "subproject" inside :idf:`/components/bootloader/subproject`. It has its own project CMakeLists.txt file and builds separate .ELF and .BIN files to the main project. However it shares its configuration and build directory with the main project. + +The subproject is inserted as an external project from the top-level project, by the file :idf_file:`/components/bootloader/project_include.cmake`. The main build process runs CMake for the subproject, which includes discovering components (a subset of the main components) and generating a bootloader-specific config (derived from the main ``sdkconfig``). + +Writing Pure CMake Components +============================= + +The ESP-IDF build system "wraps" CMake with the concept of "components", and helper functions to automatically integrate these components into a project build. + +However, underneath the concept of "components" is a full CMake build system. It is also possible to make a component which is pure CMake. + +.. highlight:: cmake + +Here is an example minimal "pure CMake" component CMakeLists file for a component named ``json``:: + + add_library(json STATIC + cJSON/cJSON.c + cJSON/cJSON_Utils.c) + + target_include_directories(json PUBLIC cJSON) + +- This is actually an equivalent declaration to the IDF ``json`` component :idf_file:`/components/json/CMakeLists.txt`. +- This file is quite simple as there are not a lot of source files. For components with a large number of files, the globbing behaviour of ESP-IDF's component logic can make the component CMakeLists style simpler.) +- Any time a component adds a library target with the component name, the ESP-IDF build system will automatically add this to the build, expose public include directories, etc. If a component wants to add a library target with a different name, dependencies will need to be added manually via CMake commands. + + +File Globbing & Incremental Builds +================================== + +.. highlight:: cmake + +The preferred way to include source files in an ESP-IDF component is to set ``COMPONENT_SRC_DIRS``:: + + set(COMPONENT_SRCDIRS library platform) + +The build system will automatically find (via "file globbing") all source files in this directory. Alternatively, files can be specified individually:: + + set(COMPONENT_SRCS library/a.c library/b.c platform/platform.c) + +CMake_ recommends always to name all files individually (ie ``COMPONENT_SRCS``). This is because CMake is automatically re-run whenever a CMakeLists file changes. If a new source file is added and file globbing is used, then CMake won't know to automatically re-run and this file won't be added to the build. + +The trade-off is acceptable when you're adding the file yourself, because you can trigger a clean build or run ``idf.py reconfigure`` to manually re-run CMake_. However, the problem gets harder when you share your project with others who may check out a new version using a source control tool like Git... + +For components which are part of ESP-IDF, we use a third party Git CMake integration module (:idf_file:`/tools/cmake/third_party/GetGitRevisionDescription.cmake`) which automatically re-runs CMake any time the repository commit changes. This means if you check out a new ESP-IDF version, CMake will automatically rerun. + +For project CMakeLists files, ``MAIN_SRCS`` is a list of source files. Therefore if a new file is added, CMakeLists will change and this triggers a re-run of CMake. (This is the approach which CMake_ recommends.) + +For project components (not part of ESP-IDF), there are a few different options: + +- If keeping your project file in Git, ESP-IDF will automatically track the Git revision and re-run CMake if the revision changes. +- If some components are kept in a third git repository (not the project repository or ESP-IDF repository), you can add a call to the ``git_describe`` function in a component CMakeLists file in order to automatically trigger re-runs of CMake when the Git revision changes. +- If not using Git, remember to manually run ``idf.py reconfigure`` whenever a source file may change. +- To avoid this problem entirely, use ``COMPONENT_SRCS`` to list all source files in project components. + +The best option will depend on your particular project and its users. + +Build System Metadata +===================== + +For integration into IDEs and other build systems, when CMake runs the build process generates a number of metadata files in the ``build/`` directory. To regenerate these files, run ``cmake`` or ``idf.py reconfigure`` (or any other ``idf.py`` build command). + +- ``compile_commands.json`` is a standard format JSON file which describes every source file which is compiled in the project. A CMake feature generates this file, and many IDEs know how to parse it. +- ``project_description.json`` contains some general information about the ESP-IDF project, configured paths, etc. +- ``flasher_args.json`` contains esptool.py arguments to flash the project's binary files. There are also ``flash_*_args`` files which can be used directly with esptool.py. See `Flash arguments`_. +- ``CMakeCache.txt`` is the CMake cache file which contains other information about the CMake process, toolchain, etc. +- ``config/sdkconfig.json`` is a JSON-formatted version of the project configuration values. +- ``config/kconfig_menus.json`` is a JSON-formatted version of the menus shown in menuconfig, for use in external IDE UIs. + +JSON Configuration Server +------------------------- + +.. highlight :: json + +A tool called ``confserver.py`` is provided to allow IDEs to easily integrate with the configuration system logic. ``confserver.py`` is designed to run in the background and interact with a calling process by reading and writing JSON over process stdin & stdout. + +You can run ``confserver.py`` from a project via ``idf.py confserver`` or ``ninja confserver``, or a similar target triggered from a different build generator. + +The config server outputs human-readable errors and warnings on stderr and JSON on stdout. On startup, it will output the full values of each configuration item in the system as a JSON dictionary, and the available ranges for values which are range constrained. The same information is contained in ``sdkconfig.json``:: + + {"version": 1, "values": { "ITEM": "value", "ITEM_2": 1024, "ITEM_3": false }, "ranges" : { "ITEM_2" : [ 0, 32768 ] } } + +Only visible configuration items are sent. Invisible/disabled items can be parsed from the static ``kconfig_menus.json`` file which also contains the menu structure and other metadata (descriptions, types, ranges, etc.) + +The Configuration Server will then wait for input from the client. The client passes a request to change one or more values, as a JSON object followed by a newline:: + + {"version": "1", "set": {"SOME_NAME": false, "OTHER_NAME": true } } + +The Configuration Server will parse this request, update the project ``sdkconfig`` file, and return a full list of changes:: + + {"version": 1, "values": {"SOME_NAME": false, "OTHER_NAME": true , "DEPENDS_ON_SOME_NAME": null}} + +Items which are now invisible/disabled will return value ``null``. Any item which is newly visible will return its newly visible current value. + +If the range of a config item changes, due to conditional range depending on another value, then this is also sent:: + + {"version": 1, "values": {"OTHER_NAME": true }, "ranges" : { "HAS_RANGE" : [ 3, 4 ] } } + +If invalid data is passed, an "error" field is present on the object:: + + {"version": 1, "values": {}, "error": ["The following config symbol(s) were not visible so were not updated: NOT_VISIBLE_ITEM"]} + +By default, no config changes are written to the sdkconfig file. Changes are held in memory until a "save" command is sent:: + + {"version": 1, "save": null } + +To reload the config values from a saved file, discarding any changes in memory, a "load" command can be sent:: + + {"version": 1, "load": null } + +The value for both "load" and "save" can be a new pathname, or "null" to load/save the previous pathname. + +The response to a "load" command is always the full set of config values and ranges, the same as when the server is initially started. + +Any combination of "load", "set", and "save" can be sent in a single command and commands are executed in that order. Therefore it's possible to load config from a file, set some config item values and then save to a file in a single command. + +.. note:: The configuration server does not automatically load any changes which are applied externally to the ``sdkconfig`` file. Send a "load" command or restart the server if the file is externally edited. + +.. note:: The configuration server does not re-run CMake to regenerate other build files or metadata files after ``sdkconfig`` is updated. This will happen automatically the next time ``CMake`` or ``idf.py`` is run. + +.. _gnu-make-to-cmake: + +Migrating from ESP-IDF GNU Make System +====================================== + +Some aspects of the CMake-based ESP-IDF build system are very similar to the older GNU Make-based system. For example, to adapt a ``component.mk`` file to ``CMakeLists.txt`` variables like ``COMPONENT_ADD_INCLUDEDIRS`` and ``COMPONENT_SRCDIRS`` can stay the same and the syntax only needs changing to CMake syntax. + +Automatic Conversion Tool +------------------------- + +.. highlight:: bash + +An automatic project conversion tool is available in :idf_file:`/tools/cmake/convert_to_cmake.py`. Run this command line tool with the path to a project like this:: + + $IDF_PATH/tools/cmake/convert_to_cmake.py /path/to/project_dir + +The project directory must contain a Makefile, and GNU Make (``make``) must be installed and available on the PATH. + +The tool will convert the project Makefile and any component ``component.mk`` files to their equivalent ``CMakeLists.txt`` files. + +It does so by running ``make`` to expand the ESP-IDF build system variables which are set by the build, and then producing equivalent CMakelists files to set the same variables. + +The conversion tool is not capable of dealing with complex Makefile logic or unusual targets. These will need to be converted by hand. + +'main' is no longer a component +------------------------------- + +In the GNU Make build system ``main`` is a component with a ``component.mk`` file like other components. + +Due to CMake requirements for building executables, ``main`` source files are now linked directly into the final binary. The source files in ``main`` must be listed in the ``MAIN_SRCS`` variable (see :ref:`project mandatory variables ` for more details). At least one source file has to be listed here (although it doesn't need to contain anything in particular). + +In general, it's better not to have too many source files in ``MAIN_SRCS``. If you find that you are adding many source files here, see if you can reorganize and group some into project components (see the :ref:`example project structure `, above). + +No Longer Available in CMake +---------------------------- + +Some features are significantly different or removed in the CMake-based system. The following variables no longer exist in the CMake-based build system: + +- ``COMPONENT_BUILD_DIR``: Use ``CMAKE_CURRENT_BINARY_DIR`` instead. +- ``COMPONENT_LIBRARY``: Defaulted to ``$(COMPONENT_NAME).a``, but the library name could be overriden by the component. The name of the component library can no longer be overriden by the component. +- ``CC``, ``LD``, ``AR``, ``OBJCOPY``: Full paths to each tool from the gcc xtensa cross-toolchain. Use ``CMAKE_C_COMPILER``, ``CMAKE_C_LINK_EXECUTABLE``, ``CMAKE_OBJCOPY``, etc instead. `Full list here `_. +- ``HOSTCC``, ``HOSTLD``, ``HOSTAR``: Full names of each tool from the host native toolchain. These are no longer provided, external projects should detect any required host toolchain manually. +- ``COMPONENT_ADD_LDFLAGS``: Used to override linker flags. Use the CMake `target_link_libraries`_ command instead. +- ``COMPONENT_ADD_LINKER_DEPS``: List of files that linking should depend on. `target_link_libraries`_ will usually infer these dependencies automatically. For linker scripts, use the provided custom CMake function ``target_linker_scripts``. +- ``COMPONENT_SUBMODULES``: No longer used, the build system will automatically enumerate all submodules in the ESP-IDF repository. +- ``COMPONENT_EXTRA_INCLUDES``: Used to be an alternative to ``COMPONENT_PRIV_INCLUDEDIRS`` for absolute paths. Use ``COMPONENT_PRIV_INCLUDEDIRS`` for all cases now (can be relative or absolute). +- ``COMPONENT_OBJS``: Previously, component sources could be specified as a list of object files. Now they can be specified as an list of source files via ``COMPONENT_SRCS``. +- ``COMPONENT_OBJEXCLUDE``: Has been replaced with ``COMPONENT_SRCEXCLUDE``. Specify source files (as absolute paths or relative to component directory), instead. +- ``COMPONENT_EXTRA_CLEAN``: Set property ``ADDITIONAL_MAKE_CLEAN_FILES`` instead but note :ref:`CMake has some restrictions around this functionality `. +- ``COMPONENT_OWNBUILDTARGET`` & ``COMPONENT_OWNCLEANTARGET``: Use CMake `ExternalProject`_ instead. See :ref:`component-build-full-override` for full details. +- ``COMPONENT_CONFIG_ONLY``: Call ``register_config_only_component()`` instead. See `Configuration-Only Components`_. +- ``CFLAGS``, ``CPPFLAGS``, ``CXXFLAGS``: Use equivalent CMake commands instead. See `Controlling Component Compilation`_. + + +No Default Values +----------------- + +The following variables no longer have default values: + +- ``COMPONENT_SRCDIRS`` +- ``COMPONENT_ADD_INCLUDEDIRS`` + +No Longer Necessary +------------------- + +It is no longer necessary to set ``COMPONENT_SRCDIRS`` if setting ``COMPONENT_SRCS`` (in fact, in the CMake-based system ``COMPONENT_SRCDIRS`` is ignored if ``COMPONENT_SRCS`` is set). + + +.. _esp-idf-template: https://github.com/espressif/esp-idf-template +.. _cmake: https://cmake.org +.. _ninja: https://ninja-build.org +.. _esptool.py: https://github.com/espressif/esptool/#readme +.. _CMake v3.5 documentation: https://cmake.org/cmake/help/v3.5/index.html +.. _cmake command line documentation: https://cmake.org/cmake/help/v3.5/manual/cmake.1.html#options +.. _cmake add_library: https://cmake.org/cmake/help/v3.5/command/project.html +.. _cmake if: https://cmake.org/cmake/help/v3.5/command/if.html +.. _cmake list: https://cmake.org/cmake/help/v3.5/command/list.html +.. _cmake project: https://cmake.org/cmake/help/v3.5/command/project.html +.. _cmake set: https://cmake.org/cmake/help/v3.5/command/set.html +.. _cmake string: https://cmake.org/cmake/help/v3.5/command/string.html +.. _cmake faq generated files: https://cmake.org/Wiki/CMake_FAQ#How_can_I_generate_a_source_file_during_the_build.3F +.. _ADDITIONAL_MAKE_CLEAN_FILES: https://cmake.org/cmake/help/v3.5/prop_dir/ADDITIONAL_MAKE_CLEAN_FILES.html +.. _ExternalProject: https://cmake.org/cmake/help/v3.5/module/ExternalProject.html +.. _cmake language variables: https://cmake.org/cmake/help/v3.5/manual/cmake-variables.7.html#variables-for-languages +.. _set_source_files_properties: https://cmake.org/cmake/help/v3.5/command/set_source_files_properties.html +.. _target_compile_options: https://cmake.org/cmake/help/v3.5/command/target_compile_options.html +.. _target_link_libraries: https://cmake.org/cmake/help/v3.5/command/target_link_libraries.html#command:target_link_libraries +.. _cmake_toolchain_file: https://cmake.org/cmake/help/v3.5/variable/CMAKE_TOOLCHAIN_FILE.html +.. _quirc: https://github.com/dlbeer/quirc +.. _pyenv: https://github.com/pyenv/pyenv#README +.. _virtualenv: https://virtualenv.pypa.io/en/stable/ + diff --git a/docs/en/api-guides/build-system.rst b/docs/en/api-guides/build-system.rst index a5054fe63..e638a36d0 100644 --- a/docs/en/api-guides/build-system.rst +++ b/docs/en/api-guides/build-system.rst @@ -1,19 +1,17 @@ Build System ************ -.. note:: - This is documentation for the CMake-based build system which is currently in preview release. The documentation may have gaps, and you may enocunter bugs (please report either of these). To view documentation for the older GNU Make based build system, switch versions to the 'latest' master branch or a stable release. +This document explains the Espressif IoT Development Framework build system and the +concept of "components" -This document explains the implementation of the CMake-based ESP-IDF build system and the concept of "components". +Read this document if you want to know how to organise a new ESP-IDF project. -Read this document if you want to know how to organise and build a new ESP-IDF project or component using the CMake-based build system. +We recommend using the esp-idf-template_ project as a starting point for your project. -For information relating to the older GNU Make-based build system, see here: +Using the Build System +====================== -.. toctree:: - :maxdepth: 1 - - gnu-make-build-system +The esp-idf README file contains a description of how to use the build system to build your project. Overview ======== @@ -21,7 +19,7 @@ Overview An ESP-IDF project can be seen as an amalgamation of a number of components. For example, for a webserver that shows the current humidity, there could be: -- The ESP32 base libraries (libc, ROM bindings, etc) +- The ESP32 base libraries (libc, rom bindings etc) - The WiFi drivers - A TCP/IP stack - The FreeRTOS operating system @@ -30,480 +28,425 @@ For example, for a webserver that shows the current humidity, there could be: - Main code tying it all together ESP-IDF makes these components explicit and configurable. To do that, -when a project is compiled, the build system will look up all the +when a project is compiled, the build environment will look up all the components in the ESP-IDF directories, the project directories and (optionally) in additional custom component directories. It then allows the user to configure the ESP-IDF project using a a text-based menu system to customize each component. After the components in the -project are configured, the build system will compile the project. +project are configured, the build process will compile the project. Concepts -------- - A "project" is a directory that contains all the files and configuration to build a single "app" (executable), as well as additional supporting output such as a partition table, data/filesystem partitions, and a bootloader. -- "Project configuration" is held in a single file called ``sdkconfig`` in the root directory of the project. This configuration file is modified via ``idf.py menuconfig`` to customise the configuration of the project. A single project contains exactly one project configuration. +- "Project configuration" is held in a single file called sdkconfig in the root directory of the project. This configuration file is modified via ``make menuconfig`` to customise the configuration of the project. A single project contains exactly one project configuration. - An "app" is an executable which is built by esp-idf. A single project will usually build two apps - a "project app" (the main executable, ie your custom firmware) and a "bootloader app" (the initial bootloader program which launches the project app). -- "components" are modular pieces of standalone code which are compiled into static libraries (.a files) and linked into an app. Some are provided by ESP-IDF itself, others may be sourced from other places. +- "components" are modular pieces of standalone code which are compiled into static libraries (.a files) and linked into an app. Some are provided by esp-idf itself, others may be sourced from other places. Some things are not part of the project: - "ESP-IDF" is not part of the project. Instead it is standalone, and linked to the project via the ``IDF_PATH`` environment variable which holds the path of the ``esp-idf`` directory. This allows the IDF framework to be decoupled from your project. -- The toolchain for compilation is not part of the project. The toolchain should be installed in the system command line PATH. +- The toolchain for compilation is not part of the project. The toolchain should be installed in the system command line PATH, or the path to the toolchain can be set as part of the compiler prefix in the project configuration. -Using the Build System -====================== - -.. _idf.py: - -idf.py ------- - -The ``idf.py`` command line tool provides a front-end for easily managing your project builds. It manages the following tools: - -- CMake_, which configures the project to be built -- A command line build tool (either Ninja_ build or `GNU Make`) -- `esptool.py`_ for flashing ESP32. - -The :ref:`getting started guide ` contains a brief introduction to how to set up ``idf.py`` to configure, build, and flash projects. - -``idf.py`` should be run in an ESP-IDF "project" directory, ie one containing a ``CMakeLists.txt`` file. Older style projects with a Makefile will not work with ``idf.py``. - -Type ``idf.py --help`` for a full list of commands. Here are a summary of the most useful ones: - -- ``idf.py menuconfig`` runs the "menuconfig" tool to configure the project. -- ``idf.py build`` will build the project found in the current directory. This can involve multiple steps: - - Create the build directory if needed. The subdirectory ``build`` is used to hold build output, although this can be changed with the ``-B`` option. - - Run CMake_ as necessary to configure the project and generate build files for the main build tool. - - Run the main build tool (Ninja_ or `GNU Make`). By default, the build tool is automatically detected but it can be explicitly set by passing the ``-G`` option to ``idf.py``. - Building is incremental so if no source files or configuration has changed since the last build, nothing will be done. -- ``idf.py clean`` will "clean" the project by deleting build output files from the build directory, forcing a "full rebuild" the next time the project is built. Cleaning doesn't delete CMake configuration output and some other files. -- ``idf.py fullclean`` will delete the entire "build" directory contents. This includes all CMake configuration output. The next time the project is built, CMake will configure it from scratch. Note that this option recursively deletes *all* files in the build directory, so use with care. Project configuration is not deleted. -- ``idf.py reconfigure`` re-runs CMake_ even if it doesn't seem to need re-running. This isn't necessary during normal usage, but can be useful after adding/removing files from the source tree. -- ``idf.py flash`` will automatically build the project if necessary, and then flash it to an ESP32. The ``-p`` and ``-b`` options can be used to set serial port name and flasher baud rate, respectively. -- ``idf.py monitor`` will display serial output from the ESP32. The ``-p`` option can be used to set the serial port name. Type ``Ctrl-]`` to exit the monitor. See :doc:`/get-started/idf-monitor` for more details about using the monitor. - -Multiple ``idf.py`` commands can be combined into one. For example, ``idf.py -p COM4 clean flash monitor`` will clean the source tree, then build the project and flash it to the ESP32 before running the serial monitor. - -.. note:: The environment variables ``ESPPORT`` and ``ESPBAUD`` can be used to set default values for the ``-p`` and ``-b`` options, respectively. Providing these options on the command line overrides the default. - -Advanced Commands -^^^^^^^^^^^^^^^^^ - -- ``idf.py app``, ``idf.py bootloader``, ``idf.py partition_table`` can be used to build only the app, bootloader, or partition table from the project as applicable. -- There are matching commands ``idf.py app-flash``, etc. to flash only that single part of the project to the ESP32. -- ``idf.py -p PORT erase_flash`` will use esptool.py to erase the ESP32's entire flash chip. -- ``idf.py size`` prints some size information about the app. ``size-components`` and ``size-files`` are similar commands which print more detailed per-component or per-source-file information, respectively. - -The order of multiple ``idf.py`` commands on the same invocation is not important, they will automatically be executed in the correct order for everything to take effect (ie building before flashing, erasing before flashing, etc.). - -Using CMake Directly --------------------- - -:ref:`idf.py` is a wrapper around CMake_ for convenience. However, you can also invoke CMake directly if you prefer. - -.. highlight:: bash - -When ``idf.py`` does something, it prints each command that it runs for easy reference. For example, the ``idf.py build`` command is the same as running these commands in a bash shell (or similar commands for Windows Command Prompt):: - - mkdir -p build - cd build - cmake .. -G Ninja # or 'GNU Make' - ninja - -In the above list, the ``cmake`` command configures the project and generates build files for use with the final build tool. In this case the final build tool is Ninja_: runnning ``ninja`` actually builds the project. - -It's not necessary to run ``cmake`` more than once. After the first build, you only need to run ``ninja`` each time. ``ninja`` will automatically re-invoke ``cmake`` if the project needs reconfiguring. - -If using CMake with ``ninja`` or ``make``, there are also targets for more of the ``idf.py`` subcommands - for example running ``make menuconfig`` or ``ninja menuconfig`` in the build directory will work the same as ``idf.py menuconfig``. - -.. note:: - If you're already familiar with CMake_, you may find the ESP-IDF CMake-based build system unusual because it wraps a lot of CMake's functionality to reduce boilerplate. See `writing pure CMake components`_ for some information about writing more "CMake style" components. - -Using CMake in an IDE ---------------------- - -You can also use an IDE with CMake integration. The IDE will want to know the path to the project's ``CMakeLists.txt`` file. IDEs with CMake integration often provide their own build tools (CMake calls these "generators") to build the source files as part of the IDE. - -When adding custom non-build steps like "flash" to the IDE, it is recommended to execute ``idf.py`` for these "special" commands. - -For more detailed information about integrating ESP-IDF with CMake into an IDE, see `Build System Metadata`_. - -.. setting-python-interpreter: - -Setting the Python Interpreter ------------------------------- - -Currently, ESP-IDF only works with Python 2.7. If you have a system where the default ``python`` interpreter is Python 3.x, this can lead to problems. - -If using ``idf.py``, running ``idf.py`` as ``python2 $IDF_PATH/tools/idf.py ...`` will work around this issue (``idf.py`` will tell other Python processes to use the same Python interpreter). You can set up a shell alias or another script to simplify the command. - -If using CMake directly, running ``cmake -D PYTHON=python2 ...`` will cause CMake to override the default Python interpreter. - -If using an IDE with CMake, setting the ``PYTHON`` value as a CMake cache override in the IDE UI will override the default Python interpreter. - -To manage the Python version more generally via the command line, check out the tools pyenv_ or virtualenv_. These let you change the default python version. - -.. _example-project-structure: Example Project -=============== - -.. highlight:: none +--------------- An example project directory tree might look like this:: - myProject/ - - CMakeLists.txt + - Makefile - sdkconfig - - components/ - component1/ - CMakeLists.txt + - components/ - component1/ - component.mk - Kconfig - src1.c - - component2/ - CMakeLists.txt + - component2/ - component.mk - Kconfig - src1.c - include/ - component2.h - main/ - src1.c - src2.c + - component.mk - build/ This example "myProject" contains the following elements: -- A top-level project CMakeLists.txt file. This is the primary file which CMake uses to learn how to build the project. The project CMakeLists.txt file sets the ``MAIN_SRCS`` variable which lists all of the source files in the "main" directory (part of this project's executable). It may set other project-wide CMake variables, as well. Then it includes the file :idf_file:`/tools/cmake/project.cmake` which - implements the rest of the build system. Finally, it sets the project name and defines the project. +- A top-level project Makefile. This Makefile set the ``PROJECT_NAME`` variable and (optionally) defines + other project-wide make variables. It includes the core ``$(IDF_PATH)/make/project.mk`` makefile which + implements the rest of the ESP-IDF build system. - "sdkconfig" project configuration file. This file is created/updated when "make menuconfig" runs, and holds configuration for all of the components in the project (including esp-idf itself). The "sdkconfig" file may or may not be added to the source control system of the project. - Optional "components" directory contains components that are part of the project. A project does not have to contain custom components of this kind, but it can be useful for structuring reusable code or including third party components that aren't part of ESP-IDF. -- "main" directory is a special "by convention" directory that contains source code for the project executable itself. These source files are listed in the project's CMakeLists file. You don't need to name this directory "main", but we recommend you follow this convention. If you have a lot of source files in your project, we recommend grouping most into components instead of putting them all in "main". +- "main" directory is a special "pseudo-component" that contains source code for the project itself. "main" is a default name, the Makefile variable ``COMPONENT_DIRS`` includes this component but you can modify this variable (or set ``EXTRA_COMPONENT_DIRS``) to look for components in other places. -- "build" directory is where build output is created. This directory is created by ``idf.py`` if it doesn't already exist. CMake configures the project and generates interim build files in this directory. Then, after the main build process is run, this directory will also contain interim object files and libraries as well as final binary output files. This directory is usually not added to source control or distributed with the project source code. +- "build" directory is where build output is created. After the make process is run, this directory will contain interim object files and libraries as well as final binary output files. This directory is usually not added to source control or distributed with the project source code. -Component directories each contain a component ``CMakeLists.txt`` file. This file contains variable definitions -to control the build process of the component, and its integration into the overall project. See `Component CMakeLists Files`_ for more details. +Component directories contain a component makefile - ``component.mk``. This may contain variable definitions +to control the build process of the component, and its integration into the overall project. See `Component Makefiles`_ for more details. -Each component may also include a ``Kconfig`` file defining the `component configuration`_ options that can be set via ``menuconfig``. Some components may also include ``Kconfig.projbuild`` and ``project_include.cmake`` files, which are special files for `overriding parts of the project`_. +Each component may also include a ``Kconfig`` file defining the `component configuration` options that can be set via the project configuration. Some components may also include ``Kconfig.projbuild`` and ``Makefile.projbuild`` files, which are special files for `overriding parts of the project`. -Project CMakeLists File -======================= +Project Makefiles +----------------- -Each project has a single top-level ``CMakeLists.txt`` file that contains build settings for the entire project. By default, the project CMakeLists can be quite minimal. +Each project has a single Makefile that contains build settings for the entire project. By default, the project Makefile can be quite minimal. -Minimal Example CMakeLists --------------------------- +Minimal Example Makefile +^^^^^^^^^^^^^^^^^^^^^^^^ -.. highlight:: cmake +:: -Minimal project:: - - cmake_minimum_required(VERSION 3.5) - - set(MAIN_SRCS main/src1.c main/src2.c) - - include($ENV{IDF_PATH}/tools/cmake/project.cmake) - project(myProject) + PROJECT_NAME := myProject + + include $(IDF_PATH)/make/project.mk -.. _project-mandatory-parts: - -Mandatory Parts ---------------- - -The inclusion of these four lines, in the order shown above, is necessary for every project: - -- ``cmake_minimum_required(VERSION 3.5)`` tells CMake what version is required to build the project. ESP-IDF is designed to work with CMake 3.5 or newer. This line must be the first line in the CMakeLists.txt file. -- ``set(MAIN_SRCS xxx)`` sets a variable - ``MAIN_SRCS`` to be a list of the "main" source files in the project. Paths are relative to the CMakeLists. They don't specifically need to be under the "main" subdirectory, but this structure is encouraged. - - It is *strongly recommended not to add a lot of files to the MAIN_SRCS list*. If you have a lot of source files then it recommended to organise them functionally into individual components under the project "components" directory. This will make your project more maintainable, reusable, and easier to configure. Components are further explained below. - - ``MAIN_SRCS`` must name at least one source file (although that file doesn't need to necessarily include an ``app_main()`` function or anything else). -- ``include($ENV{IDF_PATH}/tools/cmake/project.cmake)`` pulls in the rest of the CMake functionality to configure the project, discover all the components, etc. -- ``project(myProject)`` creates the project itself, and specifies the project name. The project name is used for the final binary output files of the app - ie ``myProject.elf``, ``myProject.bin``. Only one project can be defined per CMakeLists file. +Mandatory Project Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- ``PROJECT_NAME``: Name of the project. Binary output files will use this name - ie myProject.bin, myProject.elf. Optional Project Variables --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ -These variables all have default values that can be overridden for custom behaviour. Look in :idf_file:`/tools/cmake/project.cmake` for all of the implementation details. +These variables all have default values that can be overridden for custom behaviour. Look in ``make/project.mk`` for all of the implementation details. -- ``COMPONENT_DIRS``: Directories to search for components. Defaults to `${IDF_PATH}/components`, `${PROJECT_PATH}/components`, and ``EXTRA_COMPONENT_DIRS``. Override this variable if you don't want to search for components in these places. -- ``EXTRA_COMPONENT_DIRS``: Optional list of additional directories to search for components. Paths can be relative to the project directory, or absolute. -- ``COMPONENTS``: A list of component names to build into the project. Defaults to all components found in the ``COMPONENT_DIRS`` directories. Use this variable to "trim down" the project for faster build times. Note that any component which "requires" another component via ``COMPONENT_REQUIRES`` will automatically have it added to this list, so the ``COMPONENTS`` list can be very short. -- ``COMPONENT_REQUIRES_COMMON``: A list of components that every component requires. These components are automatically added to every component's ``COMPONENT_PRIV_REQUIRES`` list and also the project's ``COMPONENTS`` list. By default, this variable is set to the minimal set of core "system" components needed for any ESP-IDF project. Usually, you would not change this variable in your project. +- ``PROJECT_PATH``: Top-level project directory. Defaults to the directory containing the Makefile. Many other project variables are based on this variable. The project path cannot contain spaces. +- ``BUILD_DIR_BASE``: The build directory for all objects/libraries/binaries. Defaults to ``$(PROJECT_PATH)/build``. +- ``COMPONENT_DIRS``: Directories to search for components. Defaults to `$(IDF_PATH)/components`, `$(PROJECT_PATH)/components`, ``$(PROJECT_PATH)/main`` and ``EXTRA_COMPONENT_DIRS``. Override this variable if you don't want to search for components in these places. +- ``EXTRA_COMPONENT_DIRS``: Optional list of additional directories to search for components. +- ``COMPONENTS``: A list of component names to build into the project. Defaults to all components found in the COMPONENT_DIRS directories. +- ``EXCLUDE_COMPONENTS``: Optional list of component names to exclude during the build process. Note that this decreases build time, but not binary size. -Any paths in these variables can be absolute paths, or set relative to the project directory. +Any paths in these Makefile variables should be absolute paths. You can convert relative paths using ``$(PROJECT_PATH)/xxx``, ``$(IDF_PATH)/xxx``, or use the Make function ``$(abspath xxx)``. -To set these variables, use the `cmake set command `_ ie ``set(VARIABLE "VALUE")``. The ``set()`` commands should be placed after the ``cmake_minimum(...)`` line but before the ``include(...)`` line. +These variables should all be set before the line ``include $(IDF_PATH)/make/project.mk`` in the Makefile. -Component CMakeLists Files -========================== +Component Makefiles +------------------- -Each project contains one or more components. Components can be part of esp-idf, part of the project's own components directory, or added from custom component directories (see above). +Each project contains one or more components, which can either be part of esp-idf or added from other component directories. -A component is any directory in the ``COMPONENT_DIRS`` list which contains a ``CMakeLists.txt`` file. +A component is any directory that contains a ``component.mk`` file. Searching for Components ------------------------ -The list of directories in ``COMPONENT_DIRS`` is searched for the project's components. Directories in this list can either be components themselves (ie they contain a `CMakeLists.txt` file), or they can be top-level directories whose subdirectories are components. +The list of directories in ``COMPONENT_DIRS`` is searched for the project's components. Directories in this list can either be components themselves (ie they contain a `component.mk` file), or they can be top-level directories whose subdirectories are components. -When CMake runs to configure the project, it logs the components included in the build. This list can be useful for debugging the inclusion/exclusion of certain components. +Running the ``make list-components`` target dumps many of these variables and can help debug the discovery of component directories. Multiple components with the same name --------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -When ESP-IDF is collecting all the components to compile, it will do this in the order specified by ``COMPONENT_DIRS``; by default, this means ESP-IDF's internal components first, then the project's components, and finally any components set in ``EXTRA_COMPONENT_DIRS``. If two or more of these directories -contain component subdirectories with the same name, the component in the last place searched is used. This allows, for example, overriding ESP-IDF components -with a modified version by copying that component from the ESP-IDF components directory to the project components directory and then modifying it there. -If used in this way, the ESP-IDF directory itself can remain untouched. +When esp-idf is collecting all the components to compile, it will do this in the order specified by ``COMPONENT_DIRS``; by default, this means the +idf components first, the project components second and optionally the components in ``EXTRA_COMPONENT_DIRS`` last. If two or more of these directories +contain component subdirectories with the same name, the component in the last place searched is used. This allows, for example, overriding esp-idf components +with a modified version by simply copying the component from the esp-idf component directory to the project component tree and then modifying it there. +If used in this way, the esp-idf directory itself can remain untouched. -Minimal Component CMakeLists ----------------------------- +Minimal Component Makefile +^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. highlight:: cmake +The minimal ``component.mk`` file is an empty file(!). If the file is empty, the default component behaviour is set: -The minimal component ``CMakeLists.txt`` file is as follows:: +- All source files in the same directory as the makefile (``*.c``, ``*.cpp``, ``*.cc``, ``*.S``) will be compiled into the component library +- A sub-directory "include" will be added to the global include search path for all other components. +- The component library will be linked into the project app. - set(COMPONENT_SRCDIRS ".") - set(COMPONENT_ADD_INCLUDEDIRS "include") - register_component() +See `example component makefiles`_ for more complete component makefile examples. -- ``COMPONENT_SRCDIRS`` is a (space-separated) list of directories to search for source files. Source files (``*.c``, ``*.cpp``, ``*.cc``, ``*.S``) in these directories will be compiled into the component library. -- ``COMPONENT_ADD_INCLUDEDIRS`` is a (space-separated) list of directories to add to the global include search path for any component which requires this component, and also the main source files. -- ``register_component()`` is required to add the component (using the variables set above) to the build. A library with the name of the component will be built and linked into the final app. If this step is skipped (perhaps due to use of a CMake `if function `_ or similar), this component will not be part of the build. +Note that there is a difference between an empty ``component.mk`` file (which invokes default component build behaviour) and no ``component.mk`` file (which means no default component build behaviour will occur.) It is possible for a component to have no `component.mk` file, if it only contains other files which influence the project configuration or build process. -Directories are usually specified relative to the ``CMakeLists.txt`` file itself, although they can be absolute. - -See `example component CMakeLists`_ for more complete component ``CMakeLists.txt`` examples. - -.. _component variables: +.. component variables: Preset Component Variables --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ -The following component-specific variables are available for use inside component CMakeLists, but should not be modified: +The following component-specific variables are available for use inside ``component.mk``, but should not be modified: -- ``COMPONENT_PATH``: The component directory. Evaluates to the absolute path of the directory containing ``component.mk``. The component path cannot contain spaces. This is the same as the ``CMAKE_CURRENT_SOURCE_DIR`` variable. -- ``COMPONENT_NAME``: Name of the component. Same as the name of the component directory. +- ``COMPONENT_PATH``: The component directory. Evaluates to the absolute path of the directory containing ``component.mk``. The component path cannot contain spaces. +- ``COMPONENT_NAME``: Name of the component. Defaults to the name of the component directory. +- ``COMPONENT_BUILD_DIR``: The component build directory. Evaluates to the absolute path of a directory inside `$(BUILD_DIR_BASE)` where this component's source files are to be built. This is also the Current Working Directory any time the component is being built, so relative paths in make targets, etc. will be relative to this directory. +- ``COMPONENT_LIBRARY``: Name of the static library file (relative to the component build directory) that will be built for this component. Defaults to ``$(COMPONENT_NAME).a``. -The following variables are set at the project level, but available for use in component CMakeLists: +The following variables are set at the project level, but exported for use in the component build: - ``PROJECT_NAME``: Name of the project, as set in project Makefile -- ``PROJECT_PATH``: Absolute path of the project directory containing the project Makefile. Same as the ``CMAKE_SOURCE_DIR`` variable. -- ``COMPONENTS``: Names of all components that are included in this build, formatted as a semicolon-delimited CMake list. -- ``CONFIG_*``: Each value in the project configuration has a corresponding variable available in make. All names begin with ``CONFIG_``. :doc:`More information here `. -- ``IDF_VER``: Git version of ESP-IDF (produced by ``git describe``) +- ``PROJECT_PATH``: Absolute path of the project directory containing the project Makefile. +- ``COMPONENTS``: Name of all components that are included in this build. +- ``CONFIG_*``: Each value in the project configuration has a corresponding variable available in make. All names begin with ``CONFIG_``. +- ``CC``, ``LD``, ``AR``, ``OBJCOPY``: Full paths to each tool from the gcc xtensa cross-toolchain. +- ``HOSTCC``, ``HOSTLD``, ``HOSTAR``: Full names of each tool from the host native toolchain. +- ``IDF_VER``: ESP-IDF version, retrieved from either ``$(IDF_PATH)/version.txt`` file (if present) else using git command ``git describe``. Recommended format here is single liner that specifies major IDF release version, e.g. ``v2.0`` for a tagged release or ``v2.0-275-g0efaa4f`` for an arbitrary commit. Application can make use of this by calling :cpp:func:`esp_get_idf_version`. -If you modify any of these variables inside ``CMakeLists.txt`` then this will not prevent other components from building but it may make your component hard to build and/or debug. +If you modify any of these variables inside ``component.mk`` then this will not prevent other components from building but it may make your component hard to build and/or debug. -- ``COMPONENT_ADD_INCLUDEDIRS``: Paths, relative to the component directory, which will be added to the include search path for - all other components which require this one. If an include directory is only needed to compile this specific component, - add it to ``COMPONENT_PRIV_INCLUDEDIRS`` instead. -- ``COMPONENT_REQUIRES`` is a (space-separated) list of components that are required to include this project's header files into other components. If this component has a header file in a ``COMPONENT_ADD_INCLUDEDIRS`` directory that includes a header from another component, that component should be listed in ``COMPONENT_REQUIRES``. Requirements are recursive. +Optional Project-Wide Component Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - The ``COMPONENT_REQUIRES`` list can be empty because some very common components (like newlib for libc, freertos for RTOS functions, etc) are always required by all components. This list is found in the project-level variable ``COMPONENT_REQUIRES_COMMON``. +The following variables can be set inside ``component.mk`` to control build settings across the entire project: - If a component only requires another component's headers to compile its source files (not for including this component's headers), then these components should be listed in ``COMPONENT_PRIV_REQUIRES`` instead. +- ``COMPONENT_ADD_INCLUDEDIRS``: Paths, relative to the component + directory, which will be added to the include search path for + all components in the project. Defaults to ``include`` if not overridden. If an include directory is only needed to compile + this specific component, add it to ``COMPONENT_PRIV_INCLUDEDIRS`` instead. +- ``COMPONENT_ADD_LDFLAGS``: Add linker arguments to the LDFLAGS for + the app executable. Defaults to ``-l$(COMPONENT_NAME)``. If + adding pre-compiled libraries to this directory, add them as + absolute paths - ie $(COMPONENT_PATH)/libwhatever.a +- ``COMPONENT_DEPENDS``: Optional list of component names that should + be compiled before this component. This is not necessary for + link-time dependencies, because all component include directories + are available at all times. It is necessary if one component + generates an include file which you then want to include in another + component. Most components do not need to set this variable. +- ``COMPONENT_ADD_LINKER_DEPS``: Optional list of component-relative paths + to files which should trigger a re-link of the ELF file if they change. + Typically used for linker script files and binary libraries. Most components do + not need to set this variable. + +The following variable only works for components that are part of esp-idf itself: + +- ``COMPONENT_SUBMODULES``: Optional list of git submodule paths + (relative to COMPONENT_PATH) used by the component. These will be + checked (and initialised if necessary) by the build process. This + variable is ignored if the component is outside the IDF_PATH + directory. - See `Component Requirements` for more details. Optional Component-Specific Variables -------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following variables can be set inside ``component.mk`` to control the build of that component: - ``COMPONENT_PRIV_INCLUDEDIRS``: Directory paths, must be relative to the component directory, which will be added to the include search path for this component's source files only. -- ``COMPONENT_PRIV_REQUIRES`` is a (space-separated) list of components that are required to either compile or link this component's source files. These components' header paths do not propagate to other components which require it, they are only used to compile this component's sources. See `Component Requirements` for more details. -- ``COMPONENT_SRCDIRS``: Directory paths, must be relative to the component directory, which will be searched for source files (``*.cpp``, - ``*.c``, ``*.S``). Set this to specify a list of directories which contain source files. -- ``COMPONENT_SRCS``: Paths to individual source files to compile. Setting this causes ``COMPONENT_SRCDIRS`` to be ignored. Setting this variable instead gives you finer grained control over which files are compiled. - If you don't set ``COMPONENT_SRCDIRS`` or ``COMPONENT_SRCS``, your component won't compile a library but it may still add include paths for use when compiling other components or the source files listed in ``MAIN_SRCS``. -- ``COMPONENT_SRCEXCLUDE``: Paths to source files to exclude from component. Can be set in conjunction with ``COMPONENT_SRCDIRS`` if there is a directory with a large number of source files to include in the component but one or more source files which should not be. Paths can be specified relative to the component directory or absolute. +- ``COMPONENT_EXTRA_INCLUDES``: Any extra include paths used when + compiling the component's source files. These will be prefixed with + '-I' and passed as-is to the compiler. Similar to the + ``COMPONENT_PRIV_INCLUDEDIRS`` variable, except these paths are not + expanded relative to the component directory. +- ``COMPONENT_SRCDIRS``: Directory paths, must be relative to the + component directory, which will be searched for source files (``*.cpp``, + ``*.c``, ``*.S``). Defaults to '.', ie the component directory + itself. Override this to specify a different list of directories + which contain source files. +- ``COMPONENT_OBJS``: Object files to compile. Default value is a .o + file for each source file that is found in ``COMPONENT_SRCDIRS``. + Overriding this list allows you to exclude source files in + ``COMPONENT_SRCDIRS`` that would otherwise be compiled. See + `Specifying source files` +- ``COMPONENT_EXTRA_CLEAN``: Paths, relative to the component build + directory, of any files that are generated using custom make rules + in the component.mk file and which need to be removed as part of + ``make clean``. See `Source Code Generation`_ for an example. +- ``COMPONENT_OWNBUILDTARGET`` & ``COMPONENT_OWNCLEANTARGET``: These + targets allow you to fully override the default build behaviour for + the component. See `Fully Overriding The Component Makefile`_ for + more details. +- ``COMPONENT_CONFIG_ONLY``: If set, this flag indicates that the component + produces no built output at all (ie ``COMPONENT_LIBRARY`` is not built), + and most other component variables are ignored. This flag is used for IDF + internal components which contain only ``KConfig.projbuild`` and/or + ``Makefile.projbuild`` files to configure the project, but no source files. +- ``CFLAGS``: Flags passed to the C compiler. A default set of + ``CFLAGS`` is defined based on project settings. Component-specific + additions can be made via ``CFLAGS +=``. It is also possible + (although not recommended) to override this variable completely for + a component. +- ``CPPFLAGS``: Flags passed to the C preprocessor (used for .c, .cpp + and .S files). A default set of ``CPPFLAGS`` is defined based on + project settings. Component-specific additions can be made via + ``CPPFLAGS +=``. It is also possible (although not recommended) to + override this variable completely for a component. +- ``CXXFLAGS``: Flags passed to the C++ compiler. A default set of + ``CXXFLAGS`` is defined based on project + settings. Component-specific additions can be made via ``CXXFLAGS + +=``. It is also possible (although not recommended) to override + this variable completely for a component. -Controlling Component Compilation ---------------------------------- +To apply compilation flags to a single source file, you can add a variable override as a target, ie:: -.. highlight:: cmake - -To pass compiler options when compiling source files belonging to a particular component, use the ``component_compile_options`` function:: - - component_compile_options(-Wno-unused-variable) - -This is a wrapper around the CMake `target_compile_options`_ command. - -To apply the compilation flags to a single source file, use the CMake `set_source_files_properties`_ command:: - - set_source_files_properties(mysrc.c - PROPERTIES COMPILE_FLAGS - -Wno-unused-variable - ) + apps/dhcpserver.o: CFLAGS += -Wno-unused-variable This can be useful if there is upstream code that emits warnings. -When using these commands, place them after the ``register_component()`` line in the component CMakeLists file. - Component Configuration -======================= +----------------------- -Each component can also have a ``Kconfig`` file, alongside ``CMakeLists.txt``. This contains -configuration settings to add to the configuration menu for this component. +Each component can also have a Kconfig file, alongside ``component.mk``. This contains contains +configuration settings to add to the "make menuconfig" for this component. These settings are found under the "Component Settings" menu when menuconfig is run. -To create a component Kconfig file, it is easiest to start with one of the Kconfig files distributed with esp-idf. +To create a component KConfig file, it is easiest to start with one of the KConfig files distributed with esp-idf. For an example, see `Adding conditional configuration`_. Preprocessor Definitions -======================== - -The ESP-IDF build system adds the following C preprocessor definitions on the command line: - -- ``ESP_PLATFORM`` — Can be used to detect that build happens within ESP-IDF. -- ``IDF_VER`` — Defined to a git version string. E.g. ``v2.0`` for a tagged release or ``v1.0-275-g0efaa4f`` for an arbitrary commit. - -Component Requirements -====================== - -When compiling each component, the ESP-IDF build system recursively evaluates its components. - -Each component's source file is compiled with these include path directories: - -- The current component's ``COMPONENT_ADD_INCLUDEDIRS`` and ``COMPONENT_PRIV_INCLUDEDIRS``. -- The ``COMPONENT_ADD_INCLUDEDIRS`` set by all components in the current component's ``COMPONENT_REQUIRES`` and ``COMPONENT_PRIV_REQUIRES`` variables (ie all the current component's public and private dependencies). -- All of the ``COMPONENT_REQUIRES`` of those components, evaluated recursively (ie all public dependencies of this component's dependencies, recursively expanded). - -When writing a component ------------------------ -- ``COMPONENT_REQUIRES`` should be set to all components whose header files are #included from the *public* header files of this component. -- ``COMPONENT_PRIV_REQUIRES`` should be set to all components whose header files are #included from *any source files* of this component, unless already listed in ``COMPONENT_REQUIRES``. Or any component which is required to be linked in order for this component to function correctly. -- ``COMPONENT_REQUIRES`` and/or ``COMPONENT_PRIV_REQUIRES`` should be set before calling ``register_component()``. -- The values of ``COMPONENT_REQUIRES`` and ``COMPONENT_PRIV_REQUIRES`` should not depend on any configuration choices (``CONFIG_xxx`` macros). This is because requirements are expanded before configuration is loaded. Other component variables (like include paths or source files) can depend on configuration choices. -- Not setting either or both ``REQUIRES`` variables is fine. If the component has no requirements except for the "common" components needed for RTOS, libc, etc (``COMPONENT_REQUIRES_COMMON``) then both variables can be empty or unset. +ESP-IDF build systems adds the following C preprocessor definitions on the command line: -When creating a project ------------------------ - -- By default, every component is included in the build. -- If you set the ``COMPONENTS`` variable to a minimal list of components used directly by your project, then the build will include: - - Components mentioned explicitly in ``COMPONENTS``. - - Those components' requirements (evaluated recursively). - - The "common" components that every component depends on. -- Setting ``COMPONENTS`` to the minimal list of components you need can significantly reduce your project's compile time. -- When compiling the project's source files (``MAIN_SRCS``), the public header directories (``COMPONENT_ADD_INCLUDEDIRS`` list) of all components included in the build are available. - -.. _component-requirements-implementation: - -Requirements in the build system implementation ------------------------------------------------ - -- Very early in the CMake configuration process, the script ``expand_requirements.cmake`` is run. This script does a partial evaluation of all component CMakeLists.txt files and builds a graph of component requirements (this graph may have cycles). The graph is used to generate a file ``component_depends.cmake`` in the build directory. -- The main CMake process then includes this file and uses it to determine the list of components to include in the build (internal ``BUILD_COMPONENTS`` variable). -- Configuration is then evaluated for the components included in the build. -- Each component is included in the build normally and the CMakeLists.txt file is evaluated again to add the component libraries to the build. +- ``ESP_PLATFORM`` — Can be used to detect that build happens within ESP-IDF. +- ``IDF_VER`` — ESP-IDF version, see `Preset Component Variables`_ for more details. Build Process Internals -======================= +----------------------- -For full details about CMake_ and CMake commands, see the `CMake v3.5 documentation`. +Top Level: Project Makefile +^^^^^^^^^^^^^^^^^^^^^^^^^^^ -project.cmake contents ----------------------- +- "make" is always run from the project directory and the project makefile, typically named Makefile. +- The project makefile sets ``PROJECT_NAME`` and optionally customises other `optional project variables` +- The project makefile includes ``$(IDF_PATH)/make/project.mk`` which contains the project-level Make logic. +- ``project.mk`` fills in default project-level make variables and includes make variables from the project configuration. If the generated makefile containing project configuration is out of date, then it is regenerated (via targets in ``project_config.mk``) and then the make process restarts from the top. +- ``project.mk`` builds a list of components to build, based on the default component directories or a custom list of components set in `optional project variables`. +- Each component can set some `optional project-wide component variables`_. These are included via generated makefiles named ``component_project_vars.mk`` - there is one per component. These generated makefiles are included into ``project.mk``. If any are missing or out of date, they are regenerated (via a recursive make call to the component makefile) and then the make process restarts from the top. +- `Makefile.projbuild` files from components are included into the make process, to add extra targets or configuration. +- By default, the project makefile also generates top-level build & clean targets for each component and sets up `app` and `clean` targets to invoke all of these sub-targets. +- In order to compile each component, a recursive make is performed for the component makefile. -When included from a project CMakeLists file, the ``project.cmake`` file defines some utility modules and global variables and then sets ``IDF_PATH`` if it was not set in the system environmenmt. +To better understand the project make process, have a read through the ``project.mk`` file itself. -It also defines an overriden custom version of the built-in CMake_ ``project`` function. This function is overriden to add all of the ESP-IDF specific project functionality. +Second Level: Component Makefiles +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -project function ----------------- +- Each call to a component makefile goes via the ``$(IDF_PATH)/make/component_wrapper.mk`` wrapper makefile. +- This component wrapper includes all component ``Makefile.componentbuild`` files, making any recipes, variables etc in these files available to every component. +- The ``component_wrapper.mk`` is called with the current directory set to the component build directory, and the ``COMPONENT_MAKEFILE`` variable is set to the absolute path to ``component.mk``. +- ``component_wrapper.mk`` sets default values for all `component variables`, then includes the `component.mk` file which can override or modify these. +- If ``COMPONENT_OWNBUILDTARGET`` and ``COMPONENT_OWNCLEANTARGET`` are not defined, default build and clean targets are created for the component's source files and the prerequisite ``COMPONENT_LIBRARY`` static library file. +- The ``component_project_vars.mk`` file has its own target in ``component_wrapper.mk``, which is evaluated from ``project.mk`` if this file needs to be rebuilt due to changes in the component makefile or the project configuration. -The custom ``project()`` function performs the following steps: +To better understand the component make process, have a read through the ``component_wrapper.mk`` file and some of the ``component.mk`` files included with esp-idf. -- Evaluates component dependencies and builds the ``BUILD_COMPONENTS`` list of components to include in the build (see :ref:`above`). -- Finds all components in the project (searching ``COMPONENT_DIRS`` and filtering by ``COMPONENTS`` if this is set). -- Loads the project configuration from the ``sdkconfig`` file and produces a ``sdkconfig.cmake`` file and ``sdkconfig.h`` header, to define config values in CMake and C/C++, respectively. If the project configuration changes, cmake will automatically be re-run to reconfigure the project. -- Sets the `CMAKE_TOOLCHAIN_FILE`_ variable to the ESP-IDF toolchain file with the Xtensa ESP32 toolchain. -- Declare the actual cmake-level project by calling the `CMake project function `_. -- Load the git version. This includes some magic which will automatically re-run CMake if a new revision is checked out in git. See `File Globbing & Incremental Builds`_. -- Include ``project_include.cmake`` files from any components which have them. -- Add each component to the build. Each component CMakeLists file calls ``register_component``, calls the CMake `add_library `_ function to add a library and then adds source files, compile options, etc. -- Add the final app executable to the build. -- Go back and add inter-component dependencies between components (ie adding the public header directories of each component to each other component). +Running Make Non-Interactively +------------------------------ -Browse the :idf_file:`/tools/cmake/project.cmake` file and supporting functions in :idf_file:`/tools/cmake/idf_functions.cmake` for more details. +When running ``make`` in a situation where you don't want interactive prompts (for example: inside an IDE or an automated build system) append ``BATCH_BUILD=1`` to the make arguments (or set it as an environment variable). -Debugging CMake ---------------- +Setting ``BATCH_BUILD`` implies the following: -Some tips for debugging the esp-idf CMake-based build system: +- Verbose output (same as ``V=1``, see below). If you don't want verbose output, also set ``V=0``. +- If the project configuration is missing new configuration items (from new components or esp-idf updates) then the project use the default values, instead of prompting the user for each item. +- If the build system needs to invoke ``menuconfig``, an error is printed and the build fails. -- When CMake runs, it prints quite a lot of diagnostic information including lists of components and component paths. -- Running ``cmake`` with the ``--trace`` or ``--trace-expand`` options will give a lot of information about control flow. See the `cmake command line documentation`_. +Debugging The Make Process +-------------------------- + +Some tips for debugging the esp-idf build system: + +- Appending ``V=1`` to the make arguments (or setting it as an environment variable) will cause make to echo all commands executed, and also each directory as it is entered for a sub-make. +- Running ``make -w`` will cause make to echo each directory as it is entered for a sub-make - same as ``V=1`` but without also echoing all commands. +- Running ``make --trace`` (possibly in addition to one of the above arguments) will print out every target as it is built, and the dependency which caused it to be built. +- Running ``make -p`` prints a (very verbose) summary of every generated target in each makefile. + +For more debugging tips and general make information, see the `GNU Make Manual`. .. _warn-undefined-variables: Warning On Undefined Variables ------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -By default, ``idf.py`` passes the ``--warn-uninitialized`` flag to CMake_ so it will print a warning if an undefined variable is referenced in the build. This can be very useful to find buggy CMake files. +By default, the build process will print a warning if an undefined variable is referenced (like ``$(DOES_NOT_EXIST)``). This can be useful to find errors in variable names. -If you don't want this behaviour, it can be disabled by passing ``--no-warnings`` to ``idf.py``. +If you don't want this behaviour, it can be disabled in menuconfig's top level menu under `SDK tool configuration`. + +Note that this option doesn't trigger a warning if ``ifdef`` or ``ifndef`` are used in Makefiles. Overriding Parts of the Project ------------------------------- -project_include.cmake -^^^^^^^^^^^^^^^^^^^^^ +Makefile.projbuild +^^^^^^^^^^^^^^^^^^ -For components that have build requirements which must be evaluated before any component CMakeLists -files are evaluated, you can create a file called ``project_include.cmake`` in the -component directory. This CMake file is included when ``project.cmake`` is evaluating the entire project. +For components that have build requirements that must be evaluated in the top-level +project make pass, you can create a file called ``Makefile.projbuild`` in the +component directory. This makefile is included when ``project.mk`` is evaluated. -``project_include.cmake`` files are used inside ESP-IDF, for defining project-wide build features such as ``esptool.py`` command line arguments and the ``bootloader`` "special app". +For example, if your component needs to add to CFLAGS for the entire +project (not just for its own source files) then you can set +``CFLAGS +=`` in Makefile.projbuild. -Note that ``project_include.cmake`` isn't necessary for the most common component uses - such as adding include directories to the project, or ``LDFLAGS`` to the final linking step. These values can be customised via the ``CMakeLists.txt`` file itself. See `Optional Project Variables`_ for details. +``Makefile.projbuild`` files are used heavily inside esp-idf, for defining project-wide build features such as ``esptool.py`` command line arguments and the ``bootloader`` "special app". -Take great care when setting variables or targets in a ``project_include.cmake`` file. As the values are included into the top-level project CMake pass, they can influence or break functionality across all components! +Note that ``Makefile.projbuild`` isn't necessary for the most common component uses - such as adding include directories to the project, or LDFLAGS to the final linking step. These values can be customised via the ``component.mk`` file itself. See `Optional Project-Wide Component Variables`_ for details. + +Take care when setting variables or targets in this file. As the values are included into the top-level project makefile pass, they can influence or break functionality across all components! KConfig.projbuild ^^^^^^^^^^^^^^^^^ -This is an equivalent to ``project_include.cmake`` for `component configuration` KConfig files. If you want to include -configuration options at the top-level of menuconfig, rather than inside the "Component Configuration" sub-menu, then these can be defined in the KConfig.projbuild file alongside the ``CMakeLists.txt`` file. +This is an equivalent to ``Makefile.projbuild`` for `component configuration` KConfig files. If you want to include +configuration options at the top-level of menuconfig, rather than inside the "Component Configuration" sub-menu, then these can be defined in the KConfig.projbuild file alongside the ``component.mk`` file. Take care when adding configuration values in this file, as they will be included across the entire project configuration. Where possible, it's generally better to create a KConfig file for `component configuration`. +Makefile.componentbuild +^^^^^^^^^^^^^^^^^^^^^^^ + +For components that e.g. include tools to generate source files from other files, it is necessary to be able to add recipes, macros or variable definitions +into the component build process of every components. This is done by having a ``Makefile.componentbuild`` in a component directory. This file gets included +in ``component_wrapper.mk``, before the ``component.mk`` of the component is included. As with the Makefile.projbuild, take care with these files: as they're +included in each component build, a ``Makefile.componentbuild`` error may only show up when compiling an entirely different component. + Configuration-Only Components ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Special components which contain no source files, only ``Kconfig.projbuild`` and ``KConfig``, can have a one-line ``CMakeLists.txt`` file which calls the function ``register_config_only_component()``. This function will include the component in the project build, but no library will be built *and* no header files will be added to any include paths. +Some special components which contain no source files, only ``Kconfig.projbuild`` and ``Makefile.projbuild``, may set the flag ``COMPONENT_CONFIG_ONLY`` in the component.mk file. If this flag is set, most other component variables are ignored and no build step is run for the component. -If a CMakeLists.txt file doesn't call ``register_component()`` or ``register_config_only_component()``, it will be excluded from the project entirely. This may sometimes be desirable, depending on the project configuration. - -Example Component CMakeLists -============================ +Example Component Makefiles +--------------------------- Because the build environment tries to set reasonable defaults that will work most -of the time, component ``CMakeLists.txt`` can be very small or even empty (see `Minimal Component CMakeLists`_). However, overriding `component variables`_ is usually required for some functionality. +of the time, component.mk can be very small or even empty (see `Minimal Component Makefile`_). However, overriding `component variables` is usually required for some functionality. -Here are some more advanced examples of component CMakeLists files. +Here are some more advanced examples of ``component.mk`` makefiles: + + +Adding source directories +^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, sub-directories are ignored. If your project has sources in sub-directories +instead of in the root of the component then you can tell that to the build +system by setting ``COMPONENT_SRCDIRS``:: + + COMPONENT_SRCDIRS := src1 src2 + +This will compile all source files in the src1/ and src2/ sub-directories +instead. + +Specifying source files +^^^^^^^^^^^^^^^^^^^^^^^ + +The standard component.mk logic adds all .S and .c files in the source +directories as sources to be compiled unconditionally. It is possible +to circumvent that logic and hard-code the objects to be compiled by +manually setting the ``COMPONENT_OBJS`` variable to the name of the +objects that need to be generated:: + + COMPONENT_OBJS := file1.o file2.o thing/filea.o thing/fileb.o anotherthing/main.o + COMPONENT_SRCDIRS := . thing anotherthing + +Note that ``COMPONENT_SRCDIRS`` must be set as well. Adding conditional configuration --------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The configuration system can be used to conditionally compile some files -depending on the options selected in the project configuration. - -.. highlight:: none +depending on the options selected in ``make menuconfig``. For this, ESP-IDF +has the compile_only_if and compile_only_if_not macros: ``Kconfig``:: @@ -512,15 +455,17 @@ depending on the options selected in the project configuration. help This enables the BAR feature of the FOO component. -``CMakeLists.txt``:: +``component.mk``:: - set(COMPONENT_SRCS "foo.c" "more_foo.c") + $(call compile_only_if,$(CONFIG_FOO_ENABLE_BAR),bar.o) - if(CONFIG_FOO_ENABLE_BAR) - list(APPEND COMPONENT_SRCS "bar.c") - endif(CONFIG_FOO_ENABLE_BAR) -This example makes use of the CMake `if function `_ and `list APPEND `_ function. +As can be seen in the example, the ``compile_only_if`` macro takes a condition and a +list of object files as parameters. If the condition is true (in this case: if the +BAR feature is enabled in menuconfig) the object files (in this case: bar.o) will +always be compiled. The opposite goes as well: if the condition is not true, bar.o +will never be compiled. ``compile_only_if_not`` does the opposite: compile if the +condition is false, not compile if the condition is true. This can also be used to select or stub out an implementation, as such: @@ -543,24 +488,28 @@ This can also be used to select or stub out an implementation, as such: help Select this to output temperature plots -.. highlight:: cmake -``CMakeLists.txt``:: +``component.mk``:: - if(CONFIG_ENABLE_LCD_OUTPUT) - set(COMPONENT_SRCS lcd-real.c lcd-spi.c) - else() - set(COMPONENT_SRCS lcd-dummy.c) - endif() + # If LCD is enabled, compile interface to it, otherwise compile dummy interface + $(call compile_only_if,$(CONFIG_ENABLE_LCD_OUTPUT),lcd-real.o lcd-spi.o) + $(call compile_only_if_not,$(CONFIG_ENABLE_LCD_OUTPUT),lcd-dummy.o) - # We need font if either console or plot is enabled - if(CONFIG_ENABLE_LCD_CONSOLE OR CONFIG_NEABLE_LCD_PLOT) - list(APPEND COMPONENT_SRCS "font.c") - endif() + #We need font if either console or plot is enabled + $(call compile_only_if,$(or $(CONFIG_ENABLE_LCD_CONSOLE),$(CONFIG_ENABLE_LCD_PLOT)), font.o) +Note the use of the Make 'or' function to include the font file. Other substitution functions, +like 'and' and 'if' will also work here. Variables that do not come from menuconfig can also +be used: ESP-IDF uses the default Make policy of judging a variable which is empty or contains +only whitespace to be false while a variable with any non-whitespace in it is true. + +(Note: Older versions of this document advised conditionally adding object file names to +``COMPONENT_OBJS``. While this still is possible, this will only work when all object +files for a component are named explicitely, and will not clean up deselected object files +in a ``make clean`` pass.) Source Code Generation ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ Some components will have a situation where a source file isn't supplied with the component itself but has to be generated from @@ -569,369 +518,104 @@ converted binary data of a BMP file, converted using a hypothetical tool called bmp2h. The header file is then included in as C source file called graphics_lib.c:: - add_custom_command(OUTPUT logo.h - COMMAND bmp2h -i ${COMPONENT_PATH}/logo.bmp -o log.h - DEPENDS ${COMPONENT_PATH}/logo.bmp - VERBATIM) + COMPONENT_EXTRA_CLEAN := logo.h - add_custom_target(logo DEPENDS logo.h) - add_dependencies(${COMPONENT_NAME} logo) + graphics_lib.o: logo.h - set_property(DIRECTORY "${COMPONENT_PATH}" APPEND PROPERTY - ADDITIONAL_MAKE_CLEAN_FILES logo.h) + logo.h: $(COMPONENT_PATH)/logo.bmp + bmp2h -i $^ -o $@ -This answer is adapted from the `CMake FAQ entry `_, which contains some other examples that will also work with ESP-IDF builds. -In this example, logo.h will be generated in the +In this example, graphics_lib.o and logo.h will be generated in the current directory (the build directory) while logo.bmp comes with the component and resides under the component path. Because logo.h is a -generated file, it should be cleaned when the project is cleaned. For this reason -it is added to the `ADDITIONAL_MAKE_CLEAN_FILES`_ property. +generated file, it needs to be cleaned when make clean is called which +why it is added to the COMPONENT_EXTRA_CLEAN variable. -(Note: If generating files as part of the project CMakeLists, not a component CMakeLists, use ``${PROJECT_PATH}`` instead of ``${COMPONENT_PATH}`` and ``${PROJECT_NAME}.elf`` instead of ``${COMPONENT_NAME}``.) +Cosmetic Improvements +^^^^^^^^^^^^^^^^^^^^^ -If a a source file from another component included ``logo.h``, then ``add_dependencies`` would need to be called to add a dependency between -the two components, to ensure that the component source files were always compiled in the correct order. +Because logo.h is a generated file, it needs to be cleaned when make +clean is called which why it is added to the COMPONENT_EXTRA_CLEAN +variable. + +Adding logo.h to the ``graphics_lib.o`` dependencies causes it to be +generated before ``graphics_lib.c`` is compiled. + +If a a source file in another component included ``logo.h``, then this +component's name would have to be added to the other component's +``COMPONENT_DEPENDS`` list to ensure that the components were built +in-order. Embedding Binary Data ---------------------- +^^^^^^^^^^^^^^^^^^^^^ Sometimes you have a file with some binary or text data that you'd like to make available to your component - but you don't want to reformat the file as C source. -You can set a variable ``COMPONENT_EMBED_FILES`` in your component's CMakeLists, giving the names of the files to embed in this way:: +You can set a variable COMPONENT_EMBED_FILES in component.mk, giving the names of the files to embed in this way:: - set(COMPONENT_EMBED_FILES server_root_cert.der) + COMPONENT_EMBED_FILES := server_root_cert.der -Or if the file is a string, you can use the variable ``COMPONENT_EMBED_TXTFILES``. This will embed the contents of the text file as a null-terminated string:: +Or if the file is a string, you can use the variable COMPONENT_EMBED_TXTFILES. This will embed the contents of the text file as a null-terminated string:: - set(COMPONENT_EMBED_TXTFILES server_root_cert.pem) - -.. highlight:: c + COMPONENT_EMBED_TXTFILES := server_root_cert.pem The file's contents will be added to the .rodata section in flash, and are available via symbol names as follows:: extern const uint8_t server_root_cert_pem_start[] asm("_binary_server_root_cert_pem_start"); extern const uint8_t server_root_cert_pem_end[] asm("_binary_server_root_cert_pem_end"); -The names are generated from the full name of the file, as given in ``COMPONENT_EMBED_FILES``. Characters /, ., etc. are replaced with underscores. The _binary prefix in the symbol name is added by objcopy and is the same for both text and binary files. - -.. highlight:: cmake - -To embed a file into a project, rather than a component, you can call the function ``target_add_binary_data`` like this:: - - target_add_binary_data(myproject.elf "main/data.bin" TEXT) - -Place this line after the ``project()`` line in your project CMakeLists.txt file. Replace ``myproject.elf`` with your project name. The final argument can be ``TEXT`` to embed a null-terminated string, or ``BINARY`` to embed the content as-is. +The names are generated from the full name of the file, as given in COMPONENT_EMBED_FILES. Characters /, ., etc. are replaced with underscores. The _binary prefix in the symbol name is added by objcopy and is the same for both text and binary files. For an example of using this technique, see :example:`protocols/https_request` - the certificate file contents are loaded from the text .pem file at compile time. -.. _component-build-full-override: -Fully Overriding The Component Build Process --------------------------------------------- - -.. highlight:: cmake +Fully Overriding The Component Makefile +--------------------------------------- Obviously, there are cases where all these recipes are insufficient for a certain component, for example when the component is basically a wrapper around another third-party component not originally intended to be compiled under this build system. In that case, it's possible to forego -the esp-idf build system entirely by using a CMake feature called ExternalProject_. Example component CMakeLists:: +the esp-idf build system entirely by setting COMPONENT_OWNBUILDTARGET and +possibly COMPONENT_OWNCLEANTARGET and defining your own targets named ``build`` and ``clean`` in ``component.mk`` +target. The build target can do anything as long as it creates +$(COMPONENT_LIBRARY) for the project make process to link into the app binary. - # External build process for quirc, runs in source dir and - # produces libquirc.a - externalproject_add(quirc_build - PREFIX ${COMPONENT_PATH} - SOURCE_DIR ${COMPONENT_PATH}/quirc - CONFIGURE_COMMAND "" - BUILD_IN_SOURCE 1 - BUILD_COMMAND make CC=${CMAKE_C_COMPILER} libquirc.a - INSTALL_COMMAND "" - ) +(Actually, even this is not strictly necessary - if the COMPONENT_ADD_LDFLAGS variable +is overridden then the component can instruct the linker to link other binaries instead.) - # Add libquirc.a to the build process - # - add_library(quirc STATIC IMPORTED GLOBAL) - add_dependencies(quirc quirc_build) - set_target_properties(quirc PROPERTIES IMPORTED_LOCATION - ${COMPONENT_PATH}/quirc/libquirc.a) - set_target_properties(quirc PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - ${COMPONENT_PATH}/quirc/lib) +.. _esp-idf-template: https://github.com/espressif/esp-idf-template +.. _GNU Make Manual: https://www.gnu.org/software/make/manual/make.html - set_directory_properties( PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES - "${COMPONENT_PATH}/quirc/libquirc.a") - -(The above CMakeLists.txt can be used to create a component named ``quirc`` that builds the quirc_ project using its own Makefile.) - -- ``externalproject_add`` defines an external build system. - - ``SOURCE_DIR``, ``CONFIGURE_COMMAND``, ``BUILD_COMMAND`` and ``INSTALL_COMMAND`` should always be set. ``CONFIGURE_COMMAND`` can be set to an empty string if the build system has no "configure" step. ``INSTALL_COMMAND`` will generally be empty for ESP-IDF builds. - - Setting ``BUILD_IN_SOURCE`` means the build directory is the same as the source directory. Otherwise you can set ``BUILD_DIR``. - - Consult the ExternalProject_ documentation for more details about ``externalproject_add()`` - -- The second set of commands adds a library target, which points to the "imported" library file built by the external system. Some properties need to be set in order to add include directories and tell CMake where this file is. -- Finally, the generated library is added to `ADDITIONAL_MAKE_CLEAN_FILES`_. This means ``make clean`` will delete this library. (Note that the other object files from the build won't be deleted.) - -.. _ADDITIONAL_MAKE_CLEAN_FILES_note: - -ExternalProject dependencies, clean builds -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -CMake has some unusual behaviour around external project builds: - -- `ADDITIONAL_MAKE_CLEAN_FILES`_ only works when "make" is used as the build system. If Ninja_ or an IDE build system is used, it won't delete these files when cleaning. -- However, the ExternalProject_ configure & build commands will *always* be re-run after a clean is run. -- Therefore, there are two alternative recommended ways to configure the external build command: - - 1. Have the external ``BUILD_COMMAND`` run a full clean compile of all sources. The build command will be run if any of the dependencies passed to ``externalproject_add`` with ``DEPENDS`` have changed, or if this is a clean build (ie any of ``idf.py clean``, ``ninja clean``, or ``make clean`` was run.) - 2. Have the external ``BUILD_COMMAND`` be an incremental build command. Pass the parameter ``BUILD_ALWAYS 1`` to ``externalproject_add``. This means the external project will be built each time a build is run, regardless of dependencies. This is only recommended if the external project has correct incremental build behaviour, and doesn't take too long to run. - -The best of these approaches for building an external project will depend on the project itself, its build system, and whether you anticipate needing to frequently recompile the project. .. _custom-sdkconfig-defaults: Custom sdkconfig defaults -========================= +------------------------- -For example projects or other projects where you don't want to specify a full sdkconfig configuration, but you do want to override some key values from the esp-idf defaults, it is possible to create a file ``sdkconfig.defaults`` in the project directory. This file will be used when creating a new config from scratch, or when any new config value hasn't yet been set in the ``sdkconfig`` file. +For example projects or other projects where you don't want to specify a full sdkconfig configuration, but you do want to override some key values from the esp-idf defaults, it is possible to create a file ``sdkconfig.defaults`` in the project directory. This file will be used when running ``make defconfig``, or creating a new config from scratch. To override the name of this file, set the ``SDKCONFIG_DEFAULTS`` environment variable. -Flash arguments -=============== +Save flash arguments +-------------------- -There're some scenarios that we want to flash the target board without IDF. For this case we want to save the built binaries, esptool.py and esptool write_flash arguments. It's simple to write a script to save binaries and esptool.py. +There're some scenarios that we want to flash the target board without IDF. For this case we want to save the built binaries, esptool.py and esptool write_flash arguments. It's simple to write a script to save binaries and esptool.py. We can use command ``make print_flash_cmd``, it will print the flash arguments:: -After running a project build, the build directory contains binary output files (``.bin`` files) for the project and also the following flashing data files: + --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 bootloader/bootloader.bin 0x10000 example_app.bin 0x8000 partition_table_unit_test_app.bin -- ``flash_project_args`` contains arguments to flash the entire project (app, bootloader, partition table, PHY data if this is configured). -- ``flash_app_args`` contains arguments to flash only the app. -- ``flash_bootloader_args`` contains arguments to flash only the bootloader. +Then use flash arguments as the arguemnts for esptool write_flash arguments:: -.. highlight:: bash - -You can pass any of these flasher argument files to ``esptool.py`` as follows:: - - python esptool.py --chip esp32 write_flash @build/flash_project_args - -Alternatively, it is possible to manually copy the parameters from the argument file and pass them on the command line. - -The build directory also contains a generated file ``flasher_args.json`` which contains project flash information, in JSON format. This file is used by ``idf.py`` and can also be used by other tools which need information about the project build. + python esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 bootloader/bootloader.bin 0x10000 example_app.bin 0x8000 partition_table_unit_test_app.bin Building the Bootloader ======================= -The bootloader is built by default as part of ``idf.py build``, or can be built standalone via ``idf.py bootloader``. +The bootloader is built by default as part of "make all", or can be built standalone via "make bootloader-clean". There is also "make bootloader-list-components" to see the components included in the bootloader build. -The bootloader is a special "subproject" inside :idf:`/components/bootloader/subproject`. It has its own project CMakeLists.txt file and builds separate .ELF and .BIN files to the main project. However it shares its configuration and build directory with the main project. - -The subproject is inserted as an external project from the top-level project, by the file :idf_file:`/components/bootloader/project_include.cmake`. The main build process runs CMake for the subproject, which includes discovering components (a subset of the main components) and generating a bootloader-specific config (derived from the main ``sdkconfig``). - -Writing Pure CMake Components -============================= - -The ESP-IDF build system "wraps" CMake with the concept of "components", and helper functions to automatically integrate these components into a project build. - -However, underneath the concept of "components" is a full CMake build system. It is also possible to make a component which is pure CMake. - -.. highlight:: cmake - -Here is an example minimal "pure CMake" component CMakeLists file for a component named ``json``:: - - add_library(json STATIC - cJSON/cJSON.c - cJSON/cJSON_Utils.c) - - target_include_directories(json PUBLIC cJSON) - -- This is actually an equivalent declaration to the IDF ``json`` component :idf_file:`/components/json/CMakeLists.txt`. -- This file is quite simple as there are not a lot of source files. For components with a large number of files, the globbing behaviour of ESP-IDF's component logic can make the component CMakeLists style simpler.) -- Any time a component adds a library target with the component name, the ESP-IDF build system will automatically add this to the build, expose public include directories, etc. If a component wants to add a library target with a different name, dependencies will need to be added manually via CMake commands. - - -File Globbing & Incremental Builds -================================== - -.. highlight:: cmake - -The preferred way to include source files in an ESP-IDF component is to set ``COMPONENT_SRC_DIRS``:: - - set(COMPONENT_SRCDIRS library platform) - -The build system will automatically find (via "file globbing") all source files in this directory. Alternatively, files can be specified individually:: - - set(COMPONENT_SRCS library/a.c library/b.c platform/platform.c) - -Usually, CMake_ recommends always to name all files individually (ie ``COMPONENT_SRCS``). This is because CMake is automatically re-run whenever a CMakeLists file changes. If a new source file is added and file globbing is used, then CMake won't know to automatically re-run and this file won't be added to the build. - -The tradeoff is acceptable when you're adding the file yourself, because you can trigger a clean build or run ``idf.py reconfigure`` to manually re-run CMake_. However, the problem gets harder when you share your project with others who may check out a new version using a source control tool like Git... - -For components which are part of ESP-IDF, we use a third party Git CMake integration module (:idf_file:`/tools/cmake/third_party/GetGitRevisionDescription.cmake`) which automatically re-runs CMake any time the repository commit changes. This means if you check out a new ESP-IDF version, CMake will automatically rerun. - -For project CMakeLists files, ``MAIN_SRCS`` is a list of source files. Therefore if a new file is added, CMakeLists will change and this triggers a re-run of CMake. (This is "the CMake way" to do things.) - -For project components (not part of ESP-IDF), there are a few options: - -- If keeping your project file in Git, ESP-IDF will automatically track the Git revision and re-run CMake if the revision changes. -- If some components are kept in a third git repo (not the project repo or ESP-IDF repo), you can add a call to the ``git_describe`` function in a component CMakeLists file in order to trigger re-runs of CMake. -- If not using Git, you remember to manually run ``idf.py reconfigure`` whenever a source file may change. -- Use ``COMPONENT_SRCS`` to list all source files in project components. - -The best option will depend on your particular project and its users. - -Build System Metadata -===================== - -For integration into IDEs and other build systems, when CMake runs the build process generates a number of metadata files in the ``build/`` directory. To regenerate these files, run ``cmake`` or ``idf.py reconfigure`` (or any other ``idf.py`` build command). - -- ``compile_commands.json`` is a standard format JSON file which describes every source file which is compiled in the project. A CMake feature generates this file, and many IDEs know how to parse it. -- ``project_description.json`` contains some general information about the ESP-IDF project, configured paths, etc. -- ``flasher_args.json`` contains esptool.py arguments to flash the project's binary files. There are also ``flash_*_args`` files which can be used directly with esptool.py. See `Flash arguments`_. -- ``CMakeCache.txt`` is the CMake cache file which contains other information about the CMake process, toolchain, etc. -- ``config/sdkconfig.json`` is a JSON-formatted version of the project configuration values. -- ``config/kconfig_menus.json`` is a JSON-formatted version of the menus shown in menuconfig, for use in external IDE UIs. - -JSON Configuration Server -------------------------- - -.. highlight :: json - -A tool called ``confserver.py`` is provided to allow IDEs to easily integrate with the configuration system logic. ``confserver.py`` is designed to run in the background and interact with a calling process by reading and writing JSON over process stdin & stdout. - -You can run ``confserver.py`` from a project via ``idf.py confserver`` or ``ninja confserver``, or a similar target triggered from a different build generator. - -The config server outputs human-readable errors and warnings on stderr and JSON on stdout. On startup, it will output the full values of each configuration item in the system as a JSON dictionary, and the available ranges for values which are range constrained. The same information is contained in ``sdkconfig.json``:: - - {"version": 1, "values": { "ITEM": "value", "ITEM_2": 1024, "ITEM_3": false }, "ranges" : { "ITEM_2" : [ 0, 32768 ] } } - -Only visible configuration items are sent. Invisible/disabled items can be parsed from the static ``kconfig_menus.json`` file which also contains the menu structure and other metadata (descriptions, types, ranges, etc.) - -The Configuration Server will then wait for input from the client. The client passes a request to change one or more values, as a JSON object followed by a newline:: - - {"version": "1", "set": {"SOME_NAME": false, "OTHER_NAME": true } } - -The Configuration Server will parse this request, update the project ``sdkconfig`` file, and return a full list of changes:: - - {"version": 1, "values": {"SOME_NAME": false, "OTHER_NAME": true , "DEPENDS_ON_SOME_NAME": null}} - -Items which are now invisible/disabled will return value ``null``. Any item which is newly visible will return its newly visible current value. - -If the range of a config item changes, due to conditional range depending on another value, then this is also sent:: - - {"version": 1, "values": {"OTHER_NAME": true }, "ranges" : { "HAS_RANGE" : [ 3, 4 ] } } - -If invalid data is passed, an "error" field is present on the object:: - - {"version": 1, "values": {}, "error": ["The following config symbol(s) were not visible so were not updated: NOT_VISIBLE_ITEM"]} - -By default, no config changes are written to the sdkconfig file. Changes are held in memory until a "save" command is sent:: - - {"version": 1, "save": null } - -To reload the config values from a saved file, discarding any changes in memory, a "load" command can be sent:: - - {"version": 1, "load": null } - -The value for both "load" and "save" can be a new pathname, or "null" to load/save the previous pathname. - -The response to a "load" command is always the full set of config values and ranges, the same as when the server is initially started. - -Any combination of "load", "set", and "save" can be sent in a single command and commands are executed in that order. Therefore it's possible to load config from a file, set some config item values and then save to a file in a single command. - -.. note:: The configuration server does not automatically load any changes which are applied externally to the ``sdkconfig`` file. Send a "load" command or restart the server if the file is externally edited. - -.. note:: The configuration server does not re-run CMake to regenerate other build files or metadata files after ``sdkconfig`` is updated. This will happen automatically the next time ``CMake`` or ``idf.py`` is run. - -.. _gnu-make-to-cmake: - -Migrating from ESP-IDF GNU Make System -====================================== - -Some aspects of the CMake-based ESP-IDF build system are very similar to the older GNU Make-based system. For example, to adapt a ``component.mk`` file to ``CMakeLists.txt`` variables like ``COMPONENT_ADD_INCLUDEDIRS`` and ``COMPONENT_SRCDIRS`` can stay the same and the syntax only needs changing to CMake syntax. - -Automatic Conversion Tool -------------------------- - -.. highlight:: bash - -An automatic project conversion tool is available in :idf_file:`/tools/cmake/convert_to_cmake.py`. Run this command line tool with the path to a project like this:: - - $IDF_PATH/tools/cmake/convert_to_cmake.py /path/to/project_dir - -The project directory must contain a Makefile, and GNU Make (``make``) must be installed and available on the PATH. - -The tool will convert the project Makefile and any component ``component.mk`` files to their equivalent ``CMakeLists.txt`` files. - -It does so by running ``make`` to expand the ESP-IDF build system variables which are set by the build, and then producing equivalent CMakelists files to set the same variables. - -The conversion tool is not capable of dealing with complex Makefile logic or unusual targets. These will need to be converted by hand. - -'main' is no longer a component -------------------------------- - -In the GNU Make build system ``main`` is a component with a ``component.mk`` file like other components. - -Due to CMake requirements for building executables, ``main`` source files are now linked directly into the final binary. The source files in ``main`` must be listed in the ``MAIN_SRCS`` variable (see :ref:`project mandatory variables ` for more details). At least one source file has to be listed here (although it doesn't need to contain anything in particular). - -In general, it's better not to have too many source files in ``MAIN_SRCS``. If you find that you are adding many source files here, see if you reorganize and group some into project components (see the :ref:`example project structure `, above). - -No Longer Available in CMake ----------------------------- - -Some features are significantly different or removed in the CMake-based system. The following variables no longer exist in the CMake-based build system: - -- ``COMPONENT_BUILD_DIR``: Use ``CMAKE_CURRENT_BINARY_DIR`` instead. -- ``COMPONENT_LIBRARY``: Defaulted to ``$(COMPONENT_NAME).a``, but the library name could be overriden by the component. The name of the component library can no longer be overriden by the component. -- ``CC``, ``LD``, ``AR``, ``OBJCOPY``: Full paths to each tool from the gcc xtensa cross-toolchain. Use ``CMAKE_C_COMPILER``, ``CMAKE_C_LINK_EXECUTABLE``, ``CMAKE_OBJCOPY``, etc instead. `Full list here `_. -- ``HOSTCC``, ``HOSTLD``, ``HOSTAR``: Full names of each tool from the host native toolchain. These are no longer provided, external projects should detect any required host toolchain manually. -- ``COMPONENT_ADD_LDFLAGS``: Used to override linker flags. Use the CMake `target_link_libraries`_ command instead. -- ``COMPONENT_ADD_LINKER_DEPS``: List of files that linking should depend on. `target_link_libraries`_ will usually infer these dependencies automatically. For linker scripts, use the provided custom CMake function ``target_linker_scripts``. -- ``COMPONENT_SUBMODULES``: No longer used, the build system will automatically enumerate all submodules in the ESP-IDF repo. -- ``COMPONENT_EXTRA_INCLUDES``: Used to be an alternative to ``COMPONENT_PRIV_INCLUDEDIRS`` for absolute paths. Use ``COMPONENT_PRIV_INCLUDEDIRS`` for all cases now (can be relative or absolute). -- ``COMPONENT_OBJS``: Previously, component sources could be specified as a list of object files. Now they can be specified as an list of source files via ``COMPONENT_SRCS``. -- ``COMPONENT_OBJEXCLUDE``: Has been replaced with ``COMPONENT_SRCEXCLUDE``. Specify source files (as absolute paths or relative to component directory), instead. -- ``COMPONENT_EXTRA_CLEAN``: Set property ``ADDITIONAL_MAKE_CLEAN_FILES`` instead but note :ref:`CMake has some restrictions around this functionality `. -- ``COMPONENT_OWNBUILDTARGET`` & ``COMPONENT_OWNCLEANTARGET``: Use CMake `ExternalProject`_ instead. See :ref:`component-build-full-override` for full details. -- ``COMPONENT_CONFIG_ONLY``: Call ``register_config_only_component()`` instead. See `Configuration-Only Components`_. -- ``CFLAGS``, ``CPPFLAGS``, ``CXXFLAGS``: Use equivalent CMake commands instead. See `Controlling Component Compilation`_. - - -No Default Values ------------------ - -The following variables no longer have default values: - -- ``COMPONENT_SRCDIRS`` -- ``COMPONENT_ADD_INCLUDEDIRS`` - -No Longer Necessary -------------------- - -It is no longer necessary to set ``COMPONENT_SRCDIRS`` if setting ``COMPONENT_SRCS`` (in fact, in the CMake-based system ``COMPONENT_SRCDIRS`` is ignored if ``COMPONENT_SRCS`` is set). - - -.. _esp-idf-template: https://github.com/espressif/esp-idf-template -.. _cmake: https://cmake.org -.. _ninja: https://ninja-build.org -.. _esptool.py: https://github.com/espressif/esptool/#readme -.. _CMake v3.5 documentation_: https://cmake.org/cmake/help/v3.5/index.html -.. _cmake command line documentation: https://cmake.org/cmake/help/v3.5/manual/cmake.1.html#options -.. _cmake add_library: https://cmake.org/cmake/help/v3.5/command/project.html -.. _cmake if: https://cmake.org/cmake/help/v3.5/command/if.html -.. _cmake list: https://cmake.org/cmake/help/v3.5/command/list.html -.. _cmake project: https://cmake.org/cmake/help/v3.5/command/project.html -.. _cmake set: https://cmake.org/cmake/help/v3.5/command/set.html -.. _cmake string: https://cmake.org/cmake/help/v3.5/command/string.html -.. _cmake faq generated files: https://cmake.org/Wiki/CMake_FAQ#How_can_I_generate_a_source_file_during_the_build.3F -.. _ADDITIONAL_MAKE_CLEAN_FILES: https://cmake.org/cmake/help/v3.5/prop_dir/ADDITIONAL_MAKE_CLEAN_FILES.html -.. _ExternalProject: https://cmake.org/cmake/help/v3.5/module/ExternalProject.html -.. _cmake language variables: https://cmake.org/cmake/help/v3.5/manual/cmake-variables.7.html#variables-for-languages -.. _set_source_files_properties: https://cmake.org/cmake/help/v3.5/command/set_source_files_properties.html -.. _target_compile_options: https://cmake.org/cmake/help/v3.5/command/target_compile_options.html -.. _target_link_libraries: https://cmake.org/cmake/help/v3.5/command/target_link_libraries.html#command:target_link_libraries -.. _cmake_toolchain_file: https://cmake.org/cmake/help/v3.5/variable/CMAKE_TOOLCHAIN_FILE.html -.. _quirc: https://github.com/dlbeer/quirc -.. _pyenv: https://github.com/pyenv/pyenv#README -.. _virtualenv: https://virtualenv.pypa.io/en/stable/ +The component in IDF components/bootloader is special, as the second stage bootloader is a separate .ELF and .BIN file to the main project. However it shares its configuration and build directory with the main project. +This is accomplished by adding a subproject under components/bootloader/subproject. This subproject has its own Makefile, but it expects to be called from the project's own Makefile via some glue in the components/bootloader/Makefile.projectbuild file. See these files for more details. diff --git a/docs/en/api-guides/gnu-make-build-system.rst b/docs/en/api-guides/gnu-make-build-system.rst deleted file mode 100644 index d1a8a41f9..000000000 --- a/docs/en/api-guides/gnu-make-build-system.rst +++ /dev/null @@ -1,55 +0,0 @@ -GNU Make Build System -********************* - -This document contains a "cheat sheet" for users of the older ESP-IDF GNU Make build system and the newer CMake build system. - -Currently, this version of ESP-IDF contains support for both build systems, and either build system can be used. However, the rest of the documentation for this version has been updated for the CMake build system. - -.. note:: - This is documentation for the CMake-based build system which is currently in preview release. The documentation may have gaps, and you may enocunter bugs (please report either of these). To view dedicated documentation for the older GNU Make based build system, switch versions to the 'latest' master branch or a stable release. - -Dependencies -============ - -For Linux & Mac OS, the dependencies for the GNU Make and CMake-based build systems are very similar. The only additional tool required for GNU Make is ``make`` 3.81 or newer. This is pre-installed on Mac OS and can be installed on Linux via the distribution package manager. - -For Windows, the requirements are different as the GNU Make based build system requires MSYS2 for a Unix compatibility layer. Consult the Getting Started docs for IDF v3.0 for steps to set up MSYS2. - -Cheat Sheet -=========== - -Equivalents between GNU make-based build system commands and the CMake-based build system: - -==================== ================== ================= -Summary CMake-based GNU Make based -==================== ================== ================= -Configure project idf.py menuconfig make menuconfig -Build project idf.py build make -Flash project idf.py flash make flash -Monitor project idf.py monitor make monitor -Clean project idf.py fullclean make clean -==================== ================== ================= - -To override the default build directory: - -- CMake based: ``idf.py -b (directory) build`` -- GNU Make based: ``make BUILD_DIR_BASE=(directory)``. - -To set the serial port for flashing/monitoring: - -- CMake based: ``idf.py -p (port) flash`` -- GNU Make based: ``make flash ESPPORT=/dev/ttyUSB0``, or set in ``menuconfig``. - -(Note: ``idf.py`` will also use the ``ESPPORT`` environment variable for a default serial port, if no ``-p`` argument is provided.) - -To set the baud rate for flashing: - -- CMake based: ``idf.py -b 921600 flash`` -- GNU Make based: ``make flash ESPBAUD=921600``, or set in ``menuconfig``. - -(Note: ``idf.py`` will also use the ``ESPBAUD`` environment variable for a default baud rate, if no ``-b`` argument is provided.) - -Porting GNU Make Based Components to CMake -========================================== - -See :ref:`gnu-make-to-cmake`. diff --git a/docs/en/api-guides/index.rst b/docs/en/api-guides/index.rst index 3e8b2ece5..21ec7d69a 100644 --- a/docs/en/api-guides/index.rst +++ b/docs/en/api-guides/index.rst @@ -6,6 +6,7 @@ API Guides General Notes Build System + Build System (CMake) Deep Sleep Wake Stubs ESP32 Core Dump Flash Encryption <../security/flash-encryption> diff --git a/docs/en/cmake-pending-features.rst b/docs/en/cmake-pending-features.rst new file mode 100644 index 000000000..1ea28a913 --- /dev/null +++ b/docs/en/cmake-pending-features.rst @@ -0,0 +1,10 @@ +.. important:: + The following features are not yet supported with the CMake-based build system: + + - Eclipse IDE Documentation + - Secure Boot + - Flash Encryption + - ULP toolchain. + + Support for these features will be available before CMake becomes the default build system. + diff --git a/docs/en/cmake-warning.rst b/docs/en/cmake-warning.rst new file mode 100644 index 000000000..3f97614f4 --- /dev/null +++ b/docs/en/cmake-warning.rst @@ -0,0 +1,4 @@ +.. note:: + This is documentation for the CMake-based build system which is currently in preview release. If you encounter any gaps or bugs, please report them in the `Issues `_ section of the ESP-IDF repository. + + The CMake-based build system will become the default build system in ESP-IDF V4.0. The existing GNU Make based build system will be deprecated in ESP-IDF V5.0. diff --git a/docs/en/get-started-cmake/add-idf_path-to-profile.rst b/docs/en/get-started-cmake/add-idf_path-to-profile.rst new file mode 100644 index 000000000..a3b3a471e --- /dev/null +++ b/docs/en/get-started-cmake/add-idf_path-to-profile.rst @@ -0,0 +1,73 @@ +Add IDF_PATH & idf.py PATH to User Profile (CMake) +================================================== + +.. include:: ../cmake-warning.rst + +To use the CMake-based build system and the idf.py tool, two modifications need to be made to system environment variables: + +- ``IDF_PATH`` needs to be set to the path of the directory containing ESP-IDF. +- System ``PATH`` variable to include the directory containing the ``idf.py`` tool (part of ESP-IDF). + +To preserve setting of these variables between system restarts, add them to the user profile by following the instructions below. + +.. note:: If using an IDE, you can optionally set these environment variables in your IDE's project environment rather than from the command line as described below. + +.. note:: If you don't ever use the command line ``idf.py`` tool, but run cmake directly or via an IDE, then it is not necessary to set the ``PATH`` variable - only ``IDF_PATH``. However it can be useful to set both. + +.. note:: If you only ever use the command line ``idf.py`` tool, and never use cmake directly or via an IDE, then it is not necessary to set the ``IDF_PATH`` variable - ``idf.py`` will detect the directory it is contained within and set ``IDF_PATH`` appropriately if it is missing. + +.. _add-paths-to-profile-windows-cmake: + +Windows +------- + +To edit Environment Variables on Windows 10, search for "Edit Environment Variables" under the Start menu. + +On earlier Windows versions, open the System Control Panel then choose "Advanced" and look for the Environment Variables button. + +You can set these environment variables for all users, or only for the current user, depending on whether other users of your computer will be using ESP-IDF. + +- Click ``New...`` to add a new system variable named ``IDF_PATH``. Set the path to directory containing ESP-IDF, for example ``C:\Users\user-name\esp\esp-idf``. +- Locate the ``Path`` environment variable and double-click to edit it. Append the following to the end: ``;%IDF_PATH%\tools``. This will allow you to run ``idf.py`` and other tools from Windows Command Prompt. + +If you got here from section :ref:`get-started-setup-path-cmake`, while installing s/w for ESP32 development, then go back to section :ref:`get-started-start-project-cmake`. + + +.. _add-idf_path-to-profile-linux-macos-cmake: + +Linux and MacOS +--------------- + +Set up ``IDF_PATH`` and add ``idf.py`` to the PATH by adding the following two lines to your ``~/.profile`` file:: + + export IDF_PATH=~/esp/esp-idf + export PATH="$PATH:$IDF_PATH/tools" + +.. note:: + + ``~/.profile`` means a file named ``.profile`` in your user's home directory (which is abbreviated ``~`` in the shell). + +Log off and log in back to make this change effective. + +.. note:: + + Not all shells use ``.profile``. If you have ``/bin/bash`` and ``.bash_profile`` exists then update this file instead. For ``zsh``, update ``.zprofile``. Other shells may use other profile files (consult the shell's documentation). + +Run the following command to check if ``IDF_PATH`` is set:: + + printenv IDF_PATH + +The path previously entered in ``~/.profile`` file (or set manually) should be printed out. + +To verify idf.py is now on the ``PATH``, you can run the following:: + + which idf.py + +A path like ``${IDF_PATH}/tools/idf.py`` should be printed. + +If you do not like to have ``IDF_PATH`` or ``PATH`` modifications set, you can enter it manually in terminal window on each restart or logout:: + + export IDF_PATH=~/esp/esp-idf + export PATH="$PATH:$IDF_PATH/tools" + +If you got here from section :ref:`get-started-setup-path-cmake`, while installing s/w for ESP32 development, then go back to section :ref:`get-started-start-project-cmake`. diff --git a/docs/en/get-started-cmake/eclipse-setup.rst b/docs/en/get-started-cmake/eclipse-setup.rst new file mode 100644 index 000000000..ccc546f34 --- /dev/null +++ b/docs/en/get-started-cmake/eclipse-setup.rst @@ -0,0 +1,10 @@ +**************************************** +Build and Flash with Eclipse IDE (CMake) +**************************************** + +.. include:: ../cmake-warning.rst + +Documentation for Eclipse setup with CMake-based build system and Eclipse CDT is coming soon. + +.. _eclipse.org: https://www.eclipse.org/ + diff --git a/docs/en/get-started-cmake/establish-serial-connection.rst b/docs/en/get-started-cmake/establish-serial-connection.rst new file mode 100644 index 000000000..ca0e4dd2c --- /dev/null +++ b/docs/en/get-started-cmake/establish-serial-connection.rst @@ -0,0 +1,131 @@ +Establish Serial Connection with ESP32 (CMake) +============================================== + + +This section provides guidance how to establish serial connection between ESP32 and PC. + + +Connect ESP32 to PC +-------------------- + +Connect the ESP32 board to the PC using the USB cable. If device driver does not install automatically, identify USB to serial converter chip on your ESP32 board (or external converter dongle), search for drivers in internet and install them. + +Below are the links to drivers for ESP32 boards produced by Espressif: + +* ESP32-PICO-KIT and ESP32-DevKitC - `CP210x USB to UART Bridge VCP Drivers `_ + +* ESP32-WROVER-KIT and ESP32 Demo Board - `FTDI Virtual COM Port Drivers `_ + +Above drivers are primarily for reference. They should already be bundled with the operating system and installed automatically once one of listed boards is connected to the PC. + + +Check port on Windows +--------------------- + +Check the list of identified COM ports in the Windows Device Manager. Disconnect ESP32 and connect it back, to verify which port disappears from the list and then shows back again. + +Figures below show serial port for ESP32 DevKitC and ESP32 WROVER KIT + +.. figure:: ../../_static/esp32-devkitc-in-device-manager.png + :align: center + :alt: USB to UART bridge of ESP32-DevKitC in Windows Device Manager + :figclass: align-center + + USB to UART bridge of ESP32-DevKitC in Windows Device Manager + +.. figure:: ../../_static/esp32-wrover-kit-in-device-manager.png + :align: center + :alt: Two USB Serial Ports of ESP-WROVER-KIT in Windows Device Manager + :figclass: align-center + + Two USB Serial Ports of ESP-WROVER-KIT in Windows Device Manager + + +Check port on Linux and MacOS +----------------------------- + +To check the device name for the serial port of your ESP32 board (or external converter dongle), run this command two times, first with the board / dongle unplugged, then with plugged in. The port which appears the second time is the one you need: + +Linux :: + + ls /dev/tty* + +MacOS :: + + ls /dev/cu.* + + +.. note: MacOS users: if you don't see the serial port then check you have the USB/serial drivers installed as shown in the Getting Started guide for your particular development board. For MacOS High Sierra (10.13), you may also have to explicitly allow the drivers to load. Open System Preferences -> Security & Privacy -> General and check if there is a message shown here about "System Software from developer ..." where the developer name is Silicon Labs or FTDI. + +.. _linux-dialout-group-cmake: + +Adding user to ``dialout`` on Linux +----------------------------------- + +The currently logged user should have read and write access the serial port over USB. On most Linux distributions, this is done by adding the user to ``dialout`` group with the following command:: + + sudo usermod -a -G dialout $USER + +Make sure you re-login to enable read and write permissions for the serial port. + + +Verify serial connection +------------------------ + +Now verify that the serial connection is operational. You can do this using a serial terminal program. In this example we will use `PuTTY SSH Client `_ that is available for both Windows and Linux. You can use other serial program and set communication parameters like below. + +Run terminal, set identified serial port, baud rate = 115200, data bits = 8, stop bits = 1, and parity = N. Below are example screen shots of setting the port and such transmission parameters (in short described as 115200-8-1-N) on Windows and Linux. Remember to select exactly the same serial port you have identified in steps above. + +.. figure:: ../../_static/putty-settings-windows.png + :align: center + :alt: Setting Serial Communication in PuTTY on Windows + :figclass: align-center + + Setting Serial Communication in PuTTY on Windows + +.. figure:: ../../_static/putty-settings-linux.png + :align: center + :alt: Setting Serial Communication in PuTTY on Linux + :figclass: align-center + + Setting Serial Communication in PuTTY on Linux + + +Then open serial port in terminal and check, if you see any log printed out by ESP32. The log contents will depend on application loaded to ESP32. An example log by ESP32 is shown below. + +.. highlight:: none + +:: + + ets Jun 8 2016 00:22:57 + + rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) + ets Jun 8 2016 00:22:57 + + rst:0x7 (TG0WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) + configsip: 0, SPIWP:0x00 + clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 + mode:DIO, clock div:2 + load:0x3fff0008,len:8 + load:0x3fff0010,len:3464 + load:0x40078000,len:7828 + load:0x40080000,len:252 + entry 0x40080034 + I (44) boot: ESP-IDF v2.0-rc1-401-gf9fba35 2nd stage bootloader + I (45) boot: compile time 18:48:10 + + ... + +If you see some legible log, it means serial connection is working and you are ready to proceed with installation and finally upload of application to ESP32. + +.. note:: + + For some serial port wiring configurations, the serial RTS & DTR pins need to be disabled in the terminal program before the ESP32 will boot and produce serial output. This depends on the hardware itself, most development boards (including all Espressif boards) *do not* have this issue. The issue is present if RTS & DTR are wired directly to the EN & GPIO0 pins. See the `esptool documentation`_ for more details. + +.. note:: + + Close serial terminal after verification that communication is working. In next step we are going to use another application to upload ESP32. This application will not be able to access serial port while it is open in terminal. + +If you got here from section :ref:`get-started-connect-cmake` when installing s/w for ESP32 development, then go back to section :ref:`get-started-configure-cmake`. + +.. _esptool documentation: https://github.com/espressif/esptool/wiki/ESP32-Boot-Mode-Selection#automatic-bootloader diff --git a/docs/en/get-started-cmake/get-started-devkitc-v2.rst b/docs/en/get-started-cmake/get-started-devkitc-v2.rst new file mode 100644 index 000000000..fd566387e --- /dev/null +++ b/docs/en/get-started-cmake/get-started-devkitc-v2.rst @@ -0,0 +1,80 @@ +ESP32-DevKitC V2 Getting Started Guide (CMake) +============================================== + +This user guide shows how to get started with ESP32-DevKitC development board. + + +What You Need +------------- + +* 1 × :ref:`ESP32-DevKitC V2 board ` +* 1 × USB A / micro USB B cable +* 1 × PC loaded with Windows, Linux or Mac OS + + +Overview +-------- + +ESP32-DevKitC is a small-sized ESP32-based development board produced by `Espressif `_. Most of the I/O pins are broken out to the pin headers on both sides for easy interfacing. Developers can connect these pins to peripherals as needed. Standard headers also make development easy and convenient when using a breadboard. + + +Functional Description +---------------------- + +The following list and figure below describe key components, interfaces and controls of ESP32-DevKitC board. + +ESP-WROOM-32 + Standard `ESP-WROOM-32 `_ module soldered to the ESP32-DevKitC board. +EN + Reset button: pressing this button resets the system. +Boot + Download button: holding down the **Boot** button and pressing the **EN** button initiates the firmware download mode. Then user can download firmware through the serial port. +USB + USB interface. It functions as the power supply for the board and the communication interface between PC and ESP-WROOM-32. +I/O + Most of the pins on the ESP-WROOM-32 are broken out to the pin headers on the board. Users can program ESP32 to enable multiple functions such as PWM, ADC, DAC, I2C, I2S, SPI, etc. + +.. _get-started-esp32-devkitc-v2-board-front-cmake: + +.. figure:: ../../_static/esp32-devkitc-v2-functional-overview.png + :align: center + :alt: ESP32-DevKitC V2 board layout + :figclass: align-center + + ESP32-DevKitC V2 board layout + + +Power Supply Options +-------------------- + +There following options are available to provide power supply to this board: + +1. Micro USB port, this is default power supply connection +2. 5V / GND header pins +3. 3V3 / GND header pins + +.. warning:: + + Above options are mutually exclusive, i.e. the power supply may be provided using only one of the above options. Attempt to power the board using more than one connection at a time may damage the board and/or the power supply source. + + +Start Application Development +------------------------------ + +Before powering up the ESP32-DevKitC, please make sure that the board has been received in good condition with no obvious signs of damage. + +To start development of applications, proceed to section :doc:`index`, that will walk you through the following steps: + +* :ref:`get-started-setup-toolchain-cmake` in your PC to develop applications for ESP32 in C language +* :ref:`get-started-connect-cmake` the module to the PC and verify if it is accessible +* :ref:`get-started-build-cmake` for an example application +* :ref:`get-started-flash-cmake` to run code on the ESP32 +* :ref:`get-started-build-monitor-cmake` instantly what the application is doing + + +Related Documents +----------------- + +* `ESP32-DevKitC schematic `_ (PDF) +* `ESP32 Datasheet `_ (PDF) +* `ESP-WROOM-32 Datasheet `_ (PDF) diff --git a/docs/en/get-started-cmake/get-started-devkitc.rst b/docs/en/get-started-cmake/get-started-devkitc.rst new file mode 100644 index 000000000..20b2d86f6 --- /dev/null +++ b/docs/en/get-started-cmake/get-started-devkitc.rst @@ -0,0 +1,114 @@ +ESP32-DevKitC V4 Getting Started Guide (CMake) +============================================== + +This user guide shows how to get started with ESP32-DevKitC V4 development board. For description of other versions of the ESP32-DevKitC check :doc:`../hw-reference/index`. + + +What You Need +------------- + +* 1 × :ref:`ESP32-DevKitC V4 board ` +* 1 × USB A / micro USB B cable +* 1 × PC loaded with Windows, Linux or Mac OS + + +Overview +-------- + +ESP32-DevKitC V4 is a small-sized ESP32-based development board produced by `Espressif `_. Most of the I/O pins are broken out to the pin headers on both sides for easy interfacing. Developers can connect these pins to peripherals as needed. Standard headers also make development easy and convenient when using a breadboard. + +The board comes in two versions, either with :ref:`esp-modules-and-boards-esp-wroom-32` or :ref:`esp-modules-and-boards-esp32-wrover` module soldered. + + +Functional Description +---------------------- + +The following list and figure below describe key components, interfaces and controls of ESP32-DevKitC V4 board. + +ESP-WROOM-32 + :ref:`esp-modules-and-boards-esp-wroom-32` module soldered to the ESP32-DevKitC V4 board. +ESP32-WROVER + Optionally :ref:`esp-modules-and-boards-esp32-wrover` module may be soldered instead of the ESP-WROOM-32. +USB-UART Bridge + A single chip USB-UART bridge provides up to 3 Mbps transfers rates. +Boot + Download button: holding down the **Boot** button and pressing the **EN** button initiates the firmware download mode. Then user can download firmware through the serial port. +Micro USB Port + USB interface. It functions as the power supply for the board and the communication interface between PC and the ESP module. +5V Power On LED + This LED lights when the USB or an external 5V power supply is applied to the board. For details see schematic in `Related Documents`_. +EN + Reset button: pressing this button resets the system. +I/O + Most of the pins on the ESP module are broken out to the pin headers on the board. Users can program ESP32 to enable multiple functions such as PWM, ADC, DAC, I2C, I2S, SPI, etc. + + .. note:: + + Some of broken out pins are used internally be the ESP32 module to communicate with SPI memory. They are grouped on one side of the board besides the USB connector and labeled D0, D1, D2, D3, CMD and CLK. In general these pins should be left unconnected or access to the SPI flash memory / SPI RAM may be disturbed. + + .. note:: + + GPIO16 and 17 are used internally by the ESP32-WROVER module. They are broken out and avialable for use only for boards that have the ESP-WROOM-32 module installed. + + +.. _get-started-esp32-devkitc-board-front-cmake: + +.. figure:: ../../_static/esp32-devkitc-functional-overview.jpg + :align: center + :alt: ESP32-DevKitC V4 with ESP-WROOM-32 module soldered + :figclass: align-center + + ESP32-DevKitC V4 with ESP-WROOM-32 module soldered + + +Power Supply Options +-------------------- + +There following options are available to provide power supply to this board: + +1. Micro USB port, this is default power supply connection +2. 5V / GND header pins +3. 3V3 / GND header pins + +.. warning:: + + Above options are mutually exclusive, i.e. the power supply may be provided using only one of the above options. Attempt to power the board using more than one connection at a time may damage the board and/or the power supply source. + + +Start Application Development +------------------------------ + +Before powering up the ESP32-DevKitC, please make sure that the board has been received in good condition with no obvious signs of damage. + +To start development of applications, proceed to section :doc:`index`, that will walk you through the following steps: + +* :ref:`get-started-setup-toolchain-cmake` in your PC to develop applications for ESP32 in C language +* :ref:`get-started-connect-cmake` the module to the PC and verify if it is accessible +* :ref:`get-started-build-cmake` for an example application +* :ref:`get-started-flash-cmake` to run code on the ESP32 +* :ref:`get-started-build-monitor-cmake` instantly what the application is doing + + +Board Dimensions +---------------- + +.. figure:: ../../_static/esp32-devkitc-dimensions-back.jpg + :align: center + :alt: ESP32 DevKitC board dimensions - back + :figclass: align-center + + ESP32 DevKitC board dimensions - back + + +Related Documents +----------------- + +* `ESP32-DevKitC V4 schematic `_ (PDF) +* `ESP32 Datasheet `_ (PDF) +* `ESP-WROOM-32 Datasheet `_ (PDF) +* `ESP32-WROVER Datasheet `_ (PDF) + +.. toctree:: + :hidden: + + get-started-devkitc-v2 diff --git a/docs/en/get-started-cmake/get-started-pico-kit-v3.rst b/docs/en/get-started-cmake/get-started-pico-kit-v3.rst new file mode 100644 index 000000000..3abd213d4 --- /dev/null +++ b/docs/en/get-started-cmake/get-started-pico-kit-v3.rst @@ -0,0 +1,67 @@ +ESP32-PICO-KIT V3 Getting Started Guide (CMake) +=============================================== + +This user guide shows how to get started with the ESP32-PICO-KIT V3 mini development board. For description of other versions of the ESP32-PICO-KIT check :doc:`../hw-reference/index`. + + +What You Need +------------- + +* 1 × ESP32-PICO-KIT V3 mini development board +* 1 × USB A / Micro USB B cable +* 1 × PC loaded with Windows, Linux or Mac OS + + +Overview +-------- + +ESP32-PICO-KIT V3 is a mini development board based on the ESP32-PICO-D4 SIP module produced by `Espressif `_. All the IO signals and system power on ESP32-PICO-D4 are led out through two standard 20 pin x 0.1" pitch headers on both sides for easy interfacing. The development board integrates a USB-UART Bridge circuit, allowing the developers to connect the development board to a PC's USB port for downloads and debugging. + + +Functional Description +---------------------- + +The following list and figure below describe key components, interfaces and controls of ESP32-PICO-KIT V3 board. + +ESP32-PICO-D4 + Standard ESP32-PICO-D4 module soldered to the ESP32-PICO-KIT V3 board. The complete system of the ESP32 chip has been integrated into the SIP module, requiring only external antenna with LC matching network, decoupling capacitors and pull-up resistors for EN signals to function properly. +USB-UART Bridge + A single chip USB-UART bridge provides up to 1 Mbps transfers rates. +I/O + All the pins on ESP32-PICO-D4 are broken out to the pin headers on the board. Users can program ESP32 to enable multiple functions such as PWM, ADC, DAC, I2C, I2S, SPI, etc. +Micro USB Port + USB interface. It functions as the power supply for the board and the communication interface between PC and ESP32-PICO-KIT V3. +EN Button + Reset button; pressing this button resets the system. +BOOT Button + Holding down the Boot button and pressing the EN button initiates the firmware download mode. Then user can download firmware through the serial port. + +.. figure:: ../../_static/esp32-pico-kit-v3-layout.jpg + :align: center + :alt: ESP32-PICO-KIT V3 board layout + :figclass: align-center + + ESP32-PICO-KIT V3 board layout + + +Start Application Development +------------------------------ + +Before powering up the ESP32-PICO-KIT V3, please make sure that the board has been received in good condition with no obvious signs of damage. + +To start development of applications, proceed to section :doc:`index`, that will walk you through the following steps: + +* :ref:`get-started-setup-toolchain-cmake` in your PC to develop applications for ESP32 in C language +* :ref:`get-started-connect-cmake` the module to the PC and verify if it is accessible +* :ref:`get-started-build-cmake` for an example application +* :ref:`get-started-flash-cmake` to run code on the ESP32 +* :ref:`get-started-build-monitor-cmake` instantly what the application is doing + + +Related Documents +----------------- + +* `ESP32-PICO-KIT V3 schematic `_ (PDF) +* `ESP32-PICO-D4 Datasheet `_ (PDF) +* :doc:`../hw-reference/index` + diff --git a/docs/en/get-started-cmake/get-started-pico-kit.rst b/docs/en/get-started-cmake/get-started-pico-kit.rst new file mode 100644 index 000000000..9d73f34cb --- /dev/null +++ b/docs/en/get-started-cmake/get-started-pico-kit.rst @@ -0,0 +1,213 @@ +ESP32-PICO-KIT V4 Getting Started Guide (CMake) +=============================================== + + +This user guide shows how to get started with the ESP32-PICO-KIT V4 mini development board. For description of other versions of the ESP32-PICO-KIT check :doc:`../hw-reference/index`. + + +What You Need +------------- + +* 1 × :ref:`ESP32-PICO-KIT V4 mini development board ` +* 1 × USB A / Micro USB B cable +* 1 × PC loaded with Windows, Linux or Mac OS + +If you like to start using this board right now, go directly to section `Start Application Development`_. + + +Overview +-------- + +ESP32-PICO-KIT V4 is a mini development board produced by `Espressif `_. At the core of this board is the ESP32-PICO-D4, a System-in-Package (SIP) module with complete Wi-Fi and Bluetooth functionalities. Comparing to other ESP32 chips, the ESP32-PICO-D4 integrates several peripheral components in one single package, that otherwise would need to be installed separately. This includes a 40 MHz crystal oscillator, 4 MB flash, filter capacitors and RF matching links in. This greatly reduces quantity and costs of additional components, subsequent assembly and testing cost, as well as overall product complexity. + +The development board integrates a USB-UART Bridge circuit, allowing the developers to connect the board to a PC's USB port for downloads and debugging. + +For easy interfacing, all the IO signals and system power on ESP32-PICO-D4 are led out through two rows of 20 x 0.1" pitch header pads on both sides of the development board. To make the ESP32-PICO-KIT V4 fit into mini breadboards, the header pads are populated with two rows of 17 pin headers. Remaining 2 x 3 pads grouped on each side of the board besides the antenna are not populated. The remaining 2 x 3 pin headers may be soldered later by the user. + +.. note:: + + The 2 x 3 pads not populated with pin headers are internally connected to the flash memory embedded in the ESP32-PICO-D4 SIP module. For more details see module's datasheet in `Related Documents`_. + +The board dimensions are 52 x 20.3 x 10 mm (2.1" x 0.8" x 0.4"), see section `Board Dimensions`_. An overview functional block diagram is shown below. + +.. figure:: ../../_static/esp32-pico-kit-v4-functional-block-diagram.png + :align: center + :alt: ESP32-PICO-KIT V4 functional block diagram + :figclass: align-center + + ESP32-PICO-KIT V4 functional block diagram + + +Functional Description +---------------------- + +The following list and figure below describe key components, interfaces and controls of ESP32-PICO-KIT V4 board. + +ESP32-PICO-D4 + Standard ESP32-PICO-D4 module soldered to the ESP32-PICO-KIT V4 board. The complete system of the ESP32 chip has been integrated into the SIP module, requiring only external antenna with LC matching network, decoupling capacitors and pull-up resistors for EN signals to function properly. +LDO + 5V-to-3.3V Low dropout voltage regulator (LDO). +USB-UART Bridge + A single chip USB-UART bridge provides up to 1 Mbps transfers rates. +Micro USB Port + USB interface. It functions as the power supply for the board and the communication interface between PC and ESP32-PICO-KIT V4. +5V Power On LED + This light emitting diode lits when the USB or an external 5V power supply is applied to the board. For details see schematic in `Related Documents`_. +I/O + All the pins on ESP32-PICO-D4 are broken out to the pin headers on the board. Users can program ESP32 to enable multiple functions such as PWM, ADC, DAC, I2C, I2S, SPI, etc. For details please see section `Pin Descriptions`_. +BOOT Button + Holding down the Boot button and pressing the EN button initiates the firmware download mode. Then user can download firmware through the serial port. +EN Button + Reset button; pressing this button resets the system. + +.. _get-started-pico-kit-v4-board-front-cmake: + +.. figure:: ../../_static/esp32-pico-kit-v4-layout.jpg + :align: center + :alt: ESP32-PICO-KIT V4 board layout + :figclass: align-center + + ESP32-PICO-KIT V4 board layout + + +Power Supply Options +-------------------- + +There following options are available to provide power supply to the ESP32-PICO-KIT V4: + +1. Micro USB port, this is default power supply connection +2. 5V / GND header pins +3. 3V3 / GND header pins + +.. warning:: + + Above options are mutually exclusive, i.e. the power supply may be provided using only one of the above options. Attempt to power the board using more than one connection at a time may damage the board and/or the power supply source. + + +Start Application Development +----------------------------- + +Before powering up the ESP32-PICO-KIT V4, please make sure that the board has been received in good condition with no obvious signs of damage. + +To start development of applications, proceed to section :doc:`index`, that will walk you through the following steps: + +* :ref:`get-started-setup-toolchain-cmake` in your PC to develop applications for ESP32 in C language +* :ref:`get-started-connect-cmake` the module to the PC and verify if it is accessible +* :ref:`get-started-build-cmake` for an example application +* :ref:`get-started-flash-cmake` to run code on the ESP32 +* :ref:`get-started-build-monitor-cmake` instantly what the application is doing + + +Pin Descriptions +---------------- + +The two tables below provide the **Name** and **Function** of I/O headers on both sides of the board, see :ref:`get-started-pico-kit-v4-board-front-cmake`. The pin numbering and header names are the same as on a schematic in `Related Documents`_. + + +Header J2 +""""""""" + +====== ================= ====== ====================================================== +No. Name Type Function +====== ================= ====== ====================================================== +1 FLASH_SD1 (FSD1) I/O | GPIO8, SD_DATA1, SPID, HS1_DATA1 :ref:`(1) ` , U2CTS +2 FLASH_SD3 (FSD3) I/O | GPIO7, SD_DATA0, SPIQ, HS1_DATA0 :ref:`(1) ` , U2RTS +3 FLASH_CLK (FCLK) I/O | GPIO6, SD_CLK, SPICLK, HS1_CLK :ref:`(1) ` , U1CTS +4 IO21 I/O | GPIO21, VSPIHD, EMAC_TX_EN +5 IO22 I/O | GPIO22, VSPIWP, U0RTS, EMAC_TXD1 +6 IO19 I/O | GPIO19, VSPIQ, U0CTS, EMAC_TXD0 +7 IO23 I/O | GPIO23, VSPID, HS1_STROBE +8 IO18 I/O | GPIO18, VSPICLK, HS1_DATA7 +9 IO5 I/O | GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK +10 IO10 I/O | GPIO10, SD_DATA3, SPIWP, HS1_DATA3, U1TXD +11 IO9 I/O | GPIO9, SD_DATA2, SPIHD, HS1_DATA2, U1RXD +12 RXD0 I/O | GPIO3, U0RXD :ref:`(4) ` , CLK_OUT2 +13 TXD0 I/O | GPIO1, U0TXD :ref:`(4) ` , CLK_OUT3, EMAC_RXD2 +14 IO35 I | ADC1_CH7, RTC_GPIO5 +15 IO34 I | ADC1_CH6, RTC_GPIO4 +16 IO38 I | GPIO38, ADC1_CH2, ADC_PRE_AMP :ref:`(2b) ` , RTC_GPIO2 +17 IO37 I | GPIO37, ADC_PRE_AMP :ref:`(2a) ` , ADC1_CH1, RTC_GPIO1 +18 EN I | CHIP_PU +19 GND P | Ground +20 VDD33 (3V3) P | 3.3V power supply +====== ================= ====== ====================================================== + + +Header J3 +""""""""" + +====== ================= ====== ====================================================== +No. Name Type Function +====== ================= ====== ====================================================== +1 FLASH_CS (FCS) I/O | GPIO16, HS1_DATA4 :ref:`(1) ` , U2RXD, EMAC_CLK_OUT +2 FLASH_SD0 (FSD0) I/O | GPIO17, HS1_DATA5 :ref:`(1) ` , U2TXD, EMAC_CLK_OUT_180 +3 FLASH_SD2 (FSD2) I/O | GPIO11, SD_CMD, SPICS0, HS1_CMD :ref:`(1) ` , U1RTS +4 SENSOR_VP (FSVP) I | GPIO36, ADC1_CH0, ADC_PRE_AMP :ref:`(2a) ` , RTC_GPIO0 +5 SENSOR_VN (FSVN) I | GPIO39, ADC1_CH3, ADC_PRE_AMP :ref:`(2b) ` , RTC_GPIO3 +6 IO25 I/O | GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 +7 IO26 I/O | GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 +8 IO32 I/O | 32K_XP :ref:`(3a) ` , ADC1_CH4, TOUCH9, RTC_GPIO9 +9 IO33 I/O | 32K_XN :ref:`(3b) ` , ADC1_CH5, TOUCH8, RTC_GPIO8 +10 IO27 I/O | GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17 + | EMAC_RX_DV +11 IO14 I/O | ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, + | HS2_CLK, SD_CLK, EMAC_TXD2 +12 IO12 I/O | ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI :ref:`(5) ` , HSPIQ, + | HS2_DATA2, SD_DATA2, EMAC_TXD3 +13 IO13 I/O | ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, + | HS2_DATA3, SD_DATA3, EMAC_RX_ER +14 IO15 I/O | ADC2_CH3, TOUCH3, RTC_GPIO13, MTDO, HSPICS0 + | HS2_CMD, SD_CMD, EMAC_RXD3 +15 IO2 I/O | ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, + | HS2_DATA0, SD_DATA0 +16 IO4 I/O | ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, + | HS2_DATA1, SD_DATA1, EMAC_TX_ER +17 IO0 I/O | ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1 + | EMAC_TX_CLK +18 VDD33 (3V3) P | 3.3V power supply +19 GND P | Ground +20 EXT_5V (5V) P | 5V power supply +====== ================= ====== ====================================================== + + +.. _get-started-pico-kit-v4-pin-notes-cmake: + +**Notes to** `Pin Descriptions`_ + + 1. This pin is connected to the flash pin of ESP32-PICO-D4. + 2. When used as ADC_PRE_AMP, connect 270 pF capacitors between: (a) SENSOR_VP and IO37, (b) SENSOR_VN and IO38. + 3. 32.768 kHz crystal oscillator: (a) input, (b) output. + 4. This pin is connected to the pin of the USB bridge chip on the board. + 5. The operating voltage of ESP32-PICO-KIT’s embedded SPI flash is 3.3V. Therefore, the strapping pin MTDI should hold bit ”0” during the module power-on reset. + + +Board Dimensions +---------------- + +.. figure:: ../../_static/esp32-pico-kit-v4-dimensions-back.jpg + :align: center + :alt: ESP32-PICO-KIT V4 dimensions - back + :figclass: align-center + + ESP32-PICO-KIT V4 dimensions - back + +.. figure:: ../../_static/esp32-pico-kit-v4-dimensions-side.jpg + :align: center + :alt: ESP32-PICO-KIT V4 dimensions - side + :figclass: align-center + + ESP32-PICO-KIT V4 dimensions - side + + +Related Documents +----------------- + +* `ESP32-PICO-KIT V4 schematic `_ (PDF) +* `ESP32-PICO-D4 Datasheet `_ (PDF) +* :doc:`../hw-reference/index` + + +.. toctree:: + :hidden: + + get-started-pico-kit-v3 diff --git a/docs/en/get-started-cmake/get-started-wrover-kit-v2.rst b/docs/en/get-started-cmake/get-started-wrover-kit-v2.rst new file mode 100644 index 000000000..c10325fb3 --- /dev/null +++ b/docs/en/get-started-cmake/get-started-wrover-kit-v2.rst @@ -0,0 +1,192 @@ +ESP-WROVER-KIT V2 Getting Started Guide (CMake) +=============================================== + +This user guide shows how to get started with ESP-WROVER-KIT V2 development board including description of its functionality and configuration options. For description of other versions of the ESP-WROVER-KIT check :doc:`../hw-reference/index`. + +If you like to start using this board right now, go directly to section :ref:`esp-wrover-kit-v2-start-development-cmake`. + + +What You Need +------------- + +* 1 × ESP-WROVER-KIT V2 board +* 1 x Micro USB 2.0 Cable, Type A to Micro B +* 1 × PC loaded with Windows, Linux or Mac OS + + +Overview +^^^^^^^^ + +The ESP-WROVER-KIT is a development board produced by `Espressif `_ built around ESP32. This board is compatible with ESP32 modules, including the ESP-WROOM-32 and ESP32-WROVER. The ESP-WROVER-KIT features support for an LCD and MicroSD card. The I/O pins have been broken out from the ESP32 module for easy extension. The board carries an advanced multi-protocol USB bridge (the FTDI FT2232HL), enabling developers to use JTAG directly to debug the ESP32 through the USB interface. The development board makes secondary development easy and cost-effective. + +.. note:: + + ESP-WROVER-KIT V2 integrates the ESP-WROOM-32 module by default. + + +Functionality Overview +^^^^^^^^^^^^^^^^^^^^^^ + +Block diagram below presents main components of ESP-WROVER-KIT and interconnections between components. + +.. figure:: ../../_static/esp32-wrover-kit-block-diagram.png + :align: center + :alt: ESP-WROVER-KIT block diagram + :figclass: align-center + + ESP-WROVER-KIT block diagram + + +Functional Description +^^^^^^^^^^^^^^^^^^^^^^ + +The following list and figures below describe key components, interfaces and controls of ESP-WROVER-KIT board. + +32.768 kHz + An external precision 32.768 kHz crystal oscillator provides the chip with a clock of low-power consumption during the Deep-sleep mode. +ESP32 Module + ESP-WROVER-KIT is compatible with both ESP-WROOM-32 and ESP32-WROVER. The ESP32-WROVER module features all the functions of ESP-WROOM-32 and integrates an external 32-MBit PSRAM for flexible extended storage and data processing capabilities. + + .. note:: + + GPIO16 and GPIO17 are used as the CS and clock signal for PSRAM. To ensure reliable performance, the two GPIOs are not broken out. + +CTS/RTS + Serial port flow control signals: the pins are not connected to the circuitry by default. To enable them, respective pins of JP14 must be shorted with jumpers. +UART + Serial port: the serial TX/RX signals on FT2232HL and ESP32 are broken out to the two sides of JP11. By default, the two signals are connected with jumpers. To use the ESP32 module serial interface only, the jumpers may be removed and the module can be connected to another external serial device. +SPI + SPI interface: the SPI interface connects to an external flash (PSRAM). To interface another SPI device, an extra CS signal is needed. If an ESP32-WROVER is being used, please note that the electrical level on the flash and SRAM is 1.8V. +JTAG + JTAG interface: the JTAG signals on FT2232HL and ESP32 are broken out to the two sides of JP8. By default, the two signals are disconnected. To enable JTAG, shorting jumpers are required on the signals. +FT2232 + FT2232 chip is a multi-protocol USB-to-serial bridge. The FT2232 chip features USB-to-UART and USB-to-JTAG functionalities. Users can control and program the FT2232 chip through the USB interface to establish communication with ESP32. + + The embedded FT2232 chip is one of the distinguishing features of the ESP-WROVER-KIT. It enhances users’ convenience in terms of application development and debugging. In addition, uses do not need to buy a JTAG debugger separately, which reduces the development cost, see `ESP-WROVER-KIT V2 schematic`_. +EN + Reset button: pressing this button resets the system. +Boot + Download button: holding down the **Boot** button and pressing the **EN** button initiates the firmware download mode. Then user can download firmware through the serial port. +USB + USB interface. It functions as the power supply for the board and the communication interface between PC and ESP32 module. +Power Select + Power supply selection interface: the ESP-WROVER-KIT can be powered through the USB interface or the 5V Input interface. The user can select the power supply with a jumper. More details can be found in section :ref:`esp-wrover-kit-v2-setup-options-cmake`, jumper header JP7. +Power Key + Power on/off button: toggling to the right powers the board on; toggling to the left powers the board off. +5V Input + The 5V power supply interface is used as a backup power supply in case of full-load operation. +LDO + NCP1117(1A). 5V-to-3.3V LDO. (There is an alternative pin-compatible LDO — LM317DCY, with an output current of up to 1.5A). NCP1117 can provide a maximum current of 1A. The LDO solutions are available with both fixed output voltage and variable output voltage. For details please refer to `ESP-WROVER-KIT V2 schematic`_. +Camera + Camera interface: a standard OV7670 camera module is supported. +RGB + Red, green and blue (RGB) light emitting diodes (LEDs), which may be controlled by pulse width modulation (PWM). +I/O + All the pins on the ESP32 module are led out to the pin headers on the ESPWROVER-KIT. Users can program ESP32 to enable multiple functions such as PWM, ADC, DAC, I2C, I2S, SPI, etc. + +Micro SD Card + Micro SD card slot for data storage: when ESP32 enters the download mode, GPIO2 cannot be held high. However, a pull-up resistor is required on GPIO2 to enable the Micro SD Card. By default, GPIO2 and the pull-up resistor R153 are disconnected. To enable the SD Card, use jumpers on JP1 as shown in section :ref:`esp-wrover-kit-v2-setup-options-cmake`. +LCD + ESP-WROVER-KIT supports mounting and interfacing a 3.2” SPI (standard 4-wire Serial Peripheral Interface) LCD, as shown on figure :ref:`esp-wrover-kit-v2-board-back-cmake`. + +.. figure:: ../../_static/esp-wrover-kit-v2-layout-front.png + :align: center + :alt: ESP-WROVER-KIT board layout - front + :figclass: align-center + + ESP-WROVER-KIT board layout - front + +.. _esp-wrover-kit-v2-board-back-cmake: + +.. figure:: ../../_static/esp-wrover-kit-v2-layout-back.png + :align: center + :alt: ESP-WROVER-KIT board layout - back + :figclass: align-center + + ESP-WROVER-KIT board layout - back + + +.. _esp-wrover-kit-v2-setup-options-cmake: + +Setup Options +^^^^^^^^^^^^^ + +There are five jumper headers available to set up the board functionality. Typical options to select from are listed in table below. + ++--------+----------------------+-------------------------------------------------+ +| Header | Jumper Setting | Description of Functionality | ++--------+----------------------+-------------------------------------------------+ +| JP1 | |jp1-sd_io2| | Enable pull up for the Micro SD Card | ++--------+----------------------+-------------------------------------------------+ +| JP1 | |jp1-both| | Assert GPIO2 low during each download | +| | | (by jumping it to GPIO0) | ++--------+----------------------+-------------------------------------------------+ +| JP7 | |jp7-ext_5v| | Power ESP-WROVER-KIT board from an external | +| | | power supply | ++--------+----------------------+-------------------------------------------------+ +| JP7 | |jp7-usb_5v| | Power ESP-WROVER-KIT board from an USB port | ++--------+----------------------+-------------------------------------------------+ +| JP8 | |jp8| | Enable JTAG functionality | ++--------+----------------------+-------------------------------------------------+ +| JP11 | |jp11-rx-tx| | Enable UART communication | ++--------+----------------------+-------------------------------------------------+ +| JP14 | |jp14| | Enable RTS/CTS flow control for serial | +| | | communication | ++--------+----------------------+-------------------------------------------------+ + + +.. _esp-wrover-kit-v2-start-development-cmake: + +Start Application Development +----------------------------- + +Before powering up the ESP-WROVER-KIT, please make sure that the board has been received in good condition with no obvious signs of damage. + + +Initial Setup +^^^^^^^^^^^^^ + +Select the source of power supply for the board by setting jumper JP7. The options are either USB port or an external power supply. For this application selection of USB port is sufficient. Enable UART communication by installing jumpers on JP11. Both selections are shown in table below. + ++----------------------+----------------------+ +| Power up | Enable UART | +| from USB port | communication | ++----------------------+----------------------+ +| |jp7-usb_5v| | |jp11-rx-tx| | ++----------------------+----------------------+ + +Do not install any other jumpers. + + +Now to Development +^^^^^^^^^^^^^^^^^^ + +To start development of applications for ESP32-DevKitC, proceed to section :doc:`index`, that will walk you through the following steps: + +* :ref:`get-started-setup-toolchain-cmake` in your PC to develop applications for ESP32 in C language +* :ref:`get-started-connect-cmake` the module to the PC and verify if it is accessible +* :ref:`get-started-build-cmake` for an example application +* :ref:`get-started-flash-cmake` to run code on the ESP32 +* :ref:`get-started-build-monitor-cmake` instantly what the application is doing + + +Related Documents +----------------- + +* `ESP-WROVER-KIT V2 schematic`_ (PDF) +* `ESP32 Datasheet `_ (PDF) +* `ESP-WROOM-32 Datasheet `_ (PDF) +* `ESP32-WROVER Datasheet `_ (PDF) +* :doc:`../api-guides/jtag-debugging/index` +* :doc:`../hw-reference/index` + + +.. |jp1-sd_io2| image:: ../../_static/wrover-jp1-sd_io2.png +.. |jp1-both| image:: ../../_static/wrover-jp1-both.png +.. |jp7-ext_5v| image:: ../../_static/wrover-jp7-ext_5v.png +.. |jp7-usb_5v| image:: ../../_static/wrover-jp7-usb_5v.png +.. |jp8| image:: ../../_static/wrover-jp8.png +.. |jp11-rx-tx| image:: ../../_static/wrover-jp11-tx-rx.png +.. |jp14| image:: ../../_static/wrover-jp14.png + +.. _ESP-WROVER-KIT V2 schematic: https://dl.espressif.com/dl/schematics/ESP-WROVER-KIT_SCH-2.pdf diff --git a/docs/en/get-started-cmake/get-started-wrover-kit.rst b/docs/en/get-started-cmake/get-started-wrover-kit.rst new file mode 100644 index 000000000..c99c62d36 --- /dev/null +++ b/docs/en/get-started-cmake/get-started-wrover-kit.rst @@ -0,0 +1,413 @@ +ESP-WROVER-KIT V3 Getting Started Guide (CMake) +=============================================== + +This user guide shows how to get started with ESP-WROVER-KIT V3 development board including description of its functionality and configuration options. For description of other versions of the ESP-WROVER-KIT check :doc:`../hw-reference/index`. + +If you like to start using this board right now, go directly to section :ref:`get-started-esp-wrover-kit-start-development-cmake`. + + +What You Need +------------- + +* 1 × :ref:`ESP-WROVER-KIT V3 board ` +* 1 x Micro USB 2.0 Cable, Type A to Micro B +* 1 × PC loaded with Windows, Linux or Mac OS + + +Overview +^^^^^^^^ + +The ESP-WROVER-KIT is a development board produced by `Espressif `_ built around ESP32. This board is compatible with ESP32 modules, including the ESP-WROOM-32 and ESP32-WROVER. The ESP-WROVER-KIT features support for an LCD and MicroSD card. The I/O pins have been broken out from the ESP32 module for easy extension. The board carries an advanced multi-protocol USB bridge (the FTDI FT2232HL), enabling developers to use JTAG directly to debug the ESP32 through the USB interface. The development board makes secondary development easy and cost-effective. + +.. note:: + + ESP-WROVER-KIT V3 integrates the ESP32-WROVER module by default. + + +Functionality Overview +^^^^^^^^^^^^^^^^^^^^^^ + +Block diagram below presents main components of ESP-WROVER-KIT and interconnections between components. + +.. figure:: ../../_static/esp32-wrover-kit-block-diagram.png + :align: center + :alt: ESP-WROVER-KIT block diagram + :figclass: align-center + + ESP-WROVER-KIT block diagram + + +Functional Description +^^^^^^^^^^^^^^^^^^^^^^ + +The following list and figures below describe key components, interfaces and controls of ESP-WROVER-KIT board. + +32.768 kHz + An external precision 32.768 kHz crystal oscillator provides the chip with a clock of low-power consumption during the Deep-sleep mode. +0R + A zero Ohm resistor intended as a placeholder for a current shunt. May be desoldered or replaced with a current shunt to facilitate measurement of current required by ESP32 module depending on power mode. +ESP32 Module + ESP-WROVER-KIT is compatible with both ESP-WROOM-32 and ESP32-WROVER. The ESP32-WROVER module features all the functions of ESP-WROOM-32 and integrates an external 32-MBit PSRAM for flexible extended storage and data processing capabilities. + + .. note:: + + GPIO16 and GPIO17 are used as the CS and clock signal for PSRAM. To ensure reliable performance, the two GPIOs are not broken out. + +FT2232 + The FT2232 chip is a multi-protocol USB-to-serial bridge. Users can control and program the FT2232 chip through the USB interface to establish communication with ESP32. The FT2232 chip also features USB-to-JTAG interface. USB-to-JTAG is available on channel A of FT2232, USB-to-serial on channel B. The embedded FT2232 chip is one of the distinguishing features of the ESPWROVER-KIT. It enhances users’ convenience in terms of application development and debugging. In addition, users do not need to buy a JTAG debugger separately, which reduces the development cost, see `ESP-WROVER-KIT V3 schematic`_. +UART + Serial port: the serial TX/RX signals on FT2232HL and ESP32 are broken out to the two sides of JP11. By default, the two signals are connected with jumpers. To use the ESP32 module serial interface only, the jumpers may be removed and the module can be connected to another external serial device. +SPI + SPI interface: the SPI interface connects to an external flash (PSRAM). To interface another SPI device, an extra CS signal is needed. The electrical level on the flash of this module is 1.8V. If an ESP-WROOM-32 is being used, please note that the electrical level on the flash of this module is 3.3V. +CTS/RTS + Serial port flow control signals: the pins are not connected to the circuitry by default. To enable them, respective pins of JP14 must be shorted with jumpers. +JTAG + JTAG interface: the JTAG signals on FT2232HL and ESP32 are broken out to the two sides of JP8. By default, the two signals are disconnected. To enable JTAG, shorting jumpers are required on the signals. +EN + Reset button: pressing this button resets the system. +Boot + Download button: holding down the **Boot** button and pressing the **EN** button initiates the firmware download mode. Then user can download firmware through the serial port. +USB + USB interface. It functions as the power supply for the board and the communication interface between PC and ESP32 module. +Power Select + Power supply selection interface: the ESP-WROVER-KIT can be powered through the USB interface or the 5V Input interface. The user can select the power supply with a jumper. More details can be found in section :ref:`get-started-esp-wrover-kit-setup-options-cmake`, jumper header JP7. +Power Key + Power on/off button: toggling to the right powers the board on; toggling to the left powers the board off. +5V Input + The 5V power supply interface is used as a backup power supply in case of full-load operation. +LDO + NCP1117(1A). 5V-to-3.3V LDO. (There is an alternative pin-compatible LDO — LM317DCY, with an output current of up to 1.5A). NCP1117 can provide a maximum current of 1A. The LDO solutions are available with both fixed output voltage and variable output voltage. For details please refer to `ESP-WROVER-KIT V3 schematic`_. +Camera + Camera interface: a standard OV7670 camera module is supported. +RGB + Red, green and blue (RGB) light emitting diodes (LEDs), which may be controlled by pulse width modulation (PWM). +I/O + All the pins on the ESP32 module are led out to the pin headers on the ESP-WROVER-KIT. Users can program ESP32 to enable multiple functions such as PWM, ADC, DAC, I2C, I2S, SPI, etc. +Micro SD Card + Micro SD card slot for data storage. +LCD + ESP-WROVER-KIT supports mounting and interfacing a 3.2” SPI (standard 4-wire Serial Peripheral Interface) LCD, as shown on figure :ref:`get-started-esp-wrover-kit-board-back-cmake`. + +.. _get-started-esp-wrover-kit-board-front-cmake: + +.. figure:: ../../_static/esp32-wrover-kit-layout-front.jpg + :align: center + :alt: ESP-WROVER-KIT board layout - front + :figclass: align-center + + ESP-WROVER-KIT board layout - front + +.. _get-started-esp-wrover-kit-board-back-cmake: + +.. figure:: ../../_static/esp32-wrover-kit-layout-back.jpg + :align: center + :alt: ESP-WROVER-KIT board layout - back + :figclass: align-center + + ESP-WROVER-KIT board layout - back + + +.. _get-started-esp-wrover-kit-setup-options-cmake: + +Setup Options +^^^^^^^^^^^^^ + +There are five jumper headers available to set up the board functionality. Typical options to select from are listed in table below. + ++--------+------------------+--------------------------------------------------+ +| Header | Jumper Setting | Description of Functionality | ++--------+------------------+--------------------------------------------------+ +| JP7 | |jp7-ext_5v| | Power ESP-WROVER-KIT board from an external | +| | | power supply | ++--------+------------------+--------------------------------------------------+ +| JP7 | |jp7-usb_5v| | Power ESP-WROVER-KIT board from an USB port | ++--------+------------------+--------------------------------------------------+ +| JP8 | |jp8| | Enable JTAG functionality | ++--------+------------------+--------------------------------------------------+ +| JP11 | |jp11-rx-tx| | Enable UART communication | ++--------+------------------+--------------------------------------------------+ +| JP14 | |jp14| | Enable RTS/CTS flow control for serial | +| | | communication | ++--------+------------------+--------------------------------------------------+ + + +Allocation of ESP32 Pins +^^^^^^^^^^^^^^^^^^^^^^^^ + +Several pins / terminals of ESP32 module are allocated to the on board hardware. Some of them, like GPIO0 or GPIO2, have multiple functions. If certain hardware is not installed, e.g. nothing is plugged in to the Camera / JP4 header, then selected GPIOs may be used for other purposes. + + +Main I/O Connector / JP1 +"""""""""""""""""""""""" + +The JP1 connector is shown in two columns in the middle under "I/O" headers. The two columns "Shared With" outside, describe where else on the board certain GPIO is used. + ++----------------------+------+------+----------------------+ +| Shared With | I/O | I/O | Shared With | ++======================+======+======+======================+ +| | 3.3V | GND | | ++----------------------+------+------+----------------------+ +| NC/XTAL | IO32 | IO33 | NC/XTAL | ++----------------------+------+------+----------------------+ +| JTAG, MicroSD | IO12 | IO13 | JTAG, MicroSD | ++----------------------+------+------+----------------------+ +| JTAG, MicroSD | IO14 | IO27 | Camera | ++----------------------+------+------+----------------------+ +| Camera | IO26 | IO25 | Camera, LCD | ++----------------------+------+------+----------------------+ +| Camera | IO35 | IO34 | Camera | ++----------------------+------+------+----------------------+ +| Camera | IO39 | IO36 | Camera | ++----------------------+------+------+----------------------+ +| JTAG | EN | IO23 | Camera, LCD | ++----------------------+------+------+----------------------+ +| Camera, LCD | IO22 | IO21 | Camera, LCD, MicroSD | ++----------------------+------+------+----------------------+ +| Camera, LCD | IO19 | IO18 | Camera, LCD | ++----------------------+------+------+----------------------+ +| Camera, LCD | IO5 | IO17 | PSRAM | ++----------------------+------+------+----------------------+ +| PSRAM | IO16 | IO4 | LED, Camera, MicroSD | ++----------------------+------+------+----------------------+ +| LED, Boot | IO0 | IO2 | LED, Camera, MicroSD | ++----------------------+------+------+----------------------+ +| JTAG, MicroSD | IO15 | 5V | | ++----------------------+------+------+----------------------+ + +Legend: + +* NC/XTAL - :ref:`32.768 kHz Oscillator ` +* JTAG - :ref:`JTAG / JP8 ` +* Boot - Boot button / SW2 +* Camera - :ref:`Camera / JP4 ` +* LED - :ref:`RGB LED ` +* MicroSD - :ref:`MicroSD Card / J4 ` +* LCD - :ref:`LCD / U5 ` +* PSRAM - ESP32-WROVER's PSRAM, if ESP32-WROVER is installed + + +.. _get-started-esp-wrover-kit-xtal-cmake: + +32.768 kHz Oscillator +""""""""""""""""""""" + ++---+-----------+ +| | ESP32 Pin | ++===+===========+ +| 1 | GPIO32 | ++---+-----------+ +| 2 | GPIO33 | ++---+-----------+ + +.. note:: + + As GPIO32 and GPIO33 are connected to the oscillator, to maintain signal integrity, they are not connected to JP1 I/O expansion connector. This allocation may be changed from oscillator to JP1 by desoldering 0R resistors from positions R11 / R23 and installing them in positions R12 / R24. + + +.. _get-started-esp-wrover-spi-flash-header-cmake: + +SPI Flash / JP13 +"""""""""""""""" + ++---+--------------+ +| | ESP32 Pin | ++===+==============+ +| 1 | CLK / GPIO6 | ++---+--------------+ +| 2 | SD0 / GPIO7 | ++---+--------------+ +| 3 | SD1 / GPIO8 | ++---+--------------+ +| 4 | SD2 / GPIO9 | ++---+--------------+ +| 5 | SD3 / GPIO10 | ++---+--------------+ +| 6 | CMD / GPIO11 | ++---+--------------+ + +.. important:: + + The module's flash bus is connected to the pin header JP13 through 0-Ohm resistors R140 ~ R145. If the flash frequency needs to operate at 80 MHz, to improve integrity of the bus signals, it is recommended to desolder resistors R140 ~ R145. At this point, the module's flash bus is disconnected with the pin header JP13. + + +.. _get-started-esp-wrover-jtag-header-cmake: + +JTAG / JP8 +"""""""""" + ++---+---------------+-------------+ +| | ESP32 Pin | JTAG Signal | ++===+===============+=============+ +| 1 | EN | TRST_N | ++---+---------------+-------------+ +| 2 | MTDO / GPIO15 | TDO | ++---+---------------+-------------+ +| 3 | MTDI / GPIO12 | TDI | ++---+---------------+-------------+ +| 4 | MTCK / GPIO13 | TCK | ++---+---------------+-------------+ +| 5 | MTMS / GPIO14 | TMS | ++---+---------------+-------------+ + + +.. _get-started-esp-wrover-camera-header-cmake: + +Camera / JP4 +"""""""""""" + ++----+--------------+----------------------+ +| | ESP32 Pin | Camera Signal | ++====+==============+======================+ +| 1 | GPIO27 | SCCB Clock | ++----+--------------+----------------------+ +| 2 | GPIO26 | SCCB Data | ++----+--------------+----------------------+ +| 3 | GPIO21 | System Clock | ++----+--------------+----------------------+ +| 4 | GPIO25 | Vertical Sync | ++----+--------------+----------------------+ +| 5 | GPIO23 | Horizontal Reference | ++----+--------------+----------------------+ +| 6 | GPIO22 | Pixel Clock | ++----+--------------+----------------------+ +| 7 | GPIO4 | Pixel Data Bit 0 | ++----+--------------+----------------------+ +| 8 | GPIO5 | Pixel Data Bit 1 | ++----+--------------+----------------------+ +| 9 | GPIO18 | Pixel Data Bit 2 | ++----+--------------+----------------------+ +| 10 | GPIO19 | Pixel Data Bit 3 | ++----+--------------+----------------------+ +| 11 | GPIO36 | Pixel Data Bit 4 | ++----+--------------+----------------------+ +| 11 | GPIO39 | Pixel Data Bit 5 | ++----+--------------+----------------------+ +| 11 | GPIO34 | Pixel Data Bit 6 | ++----+--------------+----------------------+ +| 11 | GPIO35 | Pixel Data Bit 7 | ++----+--------------+----------------------+ +| 11 | GPIO2 | Camera Reset | ++----+--------------+----------------------+ + + +.. _get-started-esp-wrover-rgb-led-connections-cmake: + +RGB LED +""""""" + ++---+-----------+---------+ +| | ESP32 Pin | RGB LED | ++===+===========+=========+ +| 1 | GPIO0 | Red | ++---+-----------+---------+ +| 2 | GPIO2 | Blue | ++---+-----------+---------+ +| 3 | GPIO4 | Green | ++---+-----------+---------+ + + +.. _get-started-esp-wrover-microsd-card-slot-cmake: + +MicroSD Card / J4 +""""""""""""""""" + ++---+---------------+----------------+ +| | ESP32 Pin | MicroSD Signal | ++===+===============+================+ +| 1 | MTDI / GPIO12 | DATA2 | ++---+---------------+----------------+ +| 2 | MTCK / GPIO13 | CD / DATA3 | ++---+---------------+----------------+ +| 3 | MTDO / GPIO15 | CMD | ++---+---------------+----------------+ +| 4 | MTMS / GPIO14 | CLK | ++---+---------------+----------------+ +| 5 | GPIO2 | DATA0 | ++---+---------------+----------------+ +| 6 | GPIO4 | DATA1 | ++---+---------------+----------------+ +| 7 | GPIO21 | CD | ++---+---------------+----------------+ + + +.. _get-started-esp-wrover-lcd-connector-cmake: + +LCD / U5 +"""""""" + ++---+-----------+------------+ +| | ESP32 Pin | LCD Signal | ++===+===========+============+ +| 1 | GPIO18 | RESET | ++---+-----------+------------+ +| 2 | GPIO19 | SCL | ++---+-----------+------------+ +| 3 | GPIO21 | D/C | ++---+-----------+------------+ +| 4 | GPIO22 | CS | ++---+-----------+------------+ +| 5 | GPIO23 | SDA | ++---+-----------+------------+ +| 6 | GPIO25 | SDO | ++---+-----------+------------+ +| 7 | GPIO5 | Backlight | ++---+-----------+------------+ + + +.. _get-started-esp-wrover-kit-start-development-cmake: + +Start Application Development +----------------------------- + +Before powering up the ESP-WROVER-KIT, please make sure that the board has been received in good condition with no obvious signs of damage. + + +Initial Setup +^^^^^^^^^^^^^ + +Select the source of power supply for the board by setting jumper JP7. The options are either USB port or an external power supply. For this application selection of USB port is sufficient. Enable UART communication by installing jumpers on JP11. Both selections are shown in table below. + ++----------------------+----------------------+ +| Power up | Enable UART | +| from USB port | communication | ++----------------------+----------------------+ +| |jp7-usb_5v| | |jp11-rx-tx| | ++----------------------+----------------------+ + +Do not install any other jumpers. + + +Now to Development +^^^^^^^^^^^^^^^^^^ + +To start development of applications for ESP-WROVER-KIT, proceed to section :doc:`index`, that will walk you through the following steps: + +* :ref:`get-started-setup-toolchain-cmake` in your PC to develop applications for ESP32 in C language +* :ref:`get-started-connect-cmake` the module to the PC and verify if it is accessible +* :ref:`get-started-build-cmake` for an example application +* :ref:`get-started-flash-cmake` to run code on the ESP32 +* :ref:`get-started-build-monitor-cmake` instantly what the application is doing + + +Related Documents +----------------- + +* `ESP-WROVER-KIT V3 schematic`_ (PDF) +* `ESP32 Datasheet `_ (PDF) +* `ESP32-WROVER Datasheet `_ (PDF) +* `ESP-WROOM-32 Datasheet `_ (PDF) +* :doc:`../api-guides/jtag-debugging/index` +* :doc:`../hw-reference/index` + +.. |jp7-ext_5v| image:: ../../_static/esp-wrover-kit-v3-jp7-ext_5v.png +.. |jp7-usb_5v| image:: ../../_static/esp-wrover-kit-v3-jp7-usb_5v.png +.. |jp8| image:: ../../_static/esp-wrover-kit-v3-jp8.png +.. |jp11-rx-tx| image:: ../../_static/esp-wrover-kit-v3-jp11-tx-rx.png +.. |jp14| image:: ../../_static/esp-wrover-kit-v3-jp14.png + +.. _ESP-WROVER-KIT V3 schematic: https://dl.espressif.com/dl/schematics/ESP-WROVER-KIT_SCH-3.pdf + +.. toctree:: + :hidden: + + get-started-wrover-kit-v2.rst diff --git a/docs/en/get-started-cmake/idf-monitor.rst b/docs/en/get-started-cmake/idf-monitor.rst new file mode 100644 index 000000000..76bd8b411 --- /dev/null +++ b/docs/en/get-started-cmake/idf-monitor.rst @@ -0,0 +1,135 @@ +******************* +IDF Monitor (CMake) +******************* + + +The idf_monitor tool is a Python program which runs when the ``idf.py monitor`` target is invoked in IDF. + +It is mainly a serial terminal program which relays serial data to and from the target device's serial port, but it has some other IDF-specific features. + +Interacting With IDF Monitor +============================ + +- ``Ctrl-]`` will exit the monitor. +- ``Ctrl-T Ctrl-H`` will display a help menu with all other keyboard shortcuts. +- Any other key apart from ``Ctrl-]`` and ``Ctrl-T`` is sent through the serial port. + +Automatically Decoding Addresses +================================ + +Any time esp-idf prints a hexadecimal code address of the form ``0x4_______``, IDF Monitor will use addr2line_ to look up the source code location and function name. + +.. highlight:: none + +When an esp-idf app crashes and panics a register dump and backtrace such as this is produced:: + + Guru Meditation Error of type StoreProhibited occurred on core 0. Exception was unhandled. + Register dump: + PC : 0x400f360d PS : 0x00060330 A0 : 0x800dbf56 A1 : 0x3ffb7e00 + A2 : 0x3ffb136c A3 : 0x00000005 A4 : 0x00000000 A5 : 0x00000000 + A6 : 0x00000000 A7 : 0x00000080 A8 : 0x00000000 A9 : 0x3ffb7dd0 + A10 : 0x00000003 A11 : 0x00060f23 A12 : 0x00060f20 A13 : 0x3ffba6d0 + A14 : 0x00000047 A15 : 0x0000000f SAR : 0x00000019 EXCCAUSE: 0x0000001d + EXCVADDR: 0x00000000 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0x00000000 + + Backtrace: 0x400f360d:0x3ffb7e00 0x400dbf56:0x3ffb7e20 0x400dbf5e:0x3ffb7e40 0x400dbf82:0x3ffb7e60 0x400d071d:0x3ffb7e90 + +IDF Monitor will augment the dump:: + + Guru Meditation Error of type StoreProhibited occurred on core 0. Exception was unhandled. + Register dump: + PC : 0x400f360d PS : 0x00060330 A0 : 0x800dbf56 A1 : 0x3ffb7e00 + 0x400f360d: do_something_to_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:57 + (inlined by) inner_dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:52 + A2 : 0x3ffb136c A3 : 0x00000005 A4 : 0x00000000 A5 : 0x00000000 + A6 : 0x00000000 A7 : 0x00000080 A8 : 0x00000000 A9 : 0x3ffb7dd0 + A10 : 0x00000003 A11 : 0x00060f23 A12 : 0x00060f20 A13 : 0x3ffba6d0 + A14 : 0x00000047 A15 : 0x0000000f SAR : 0x00000019 EXCCAUSE: 0x0000001d + EXCVADDR: 0x00000000 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0x00000000 + + Backtrace: 0x400f360d:0x3ffb7e00 0x400dbf56:0x3ffb7e20 0x400dbf5e:0x3ffb7e40 0x400dbf82:0x3ffb7e60 0x400d071d:0x3ffb7e90 + 0x400f360d: do_something_to_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:57 + (inlined by) inner_dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:52 + 0x400dbf56: still_dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:47 + 0x400dbf5e: dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:42 + 0x400dbf82: app_main at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:33 + 0x400d071d: main_task at /home/gus/esp/32/idf/components/esp32/./cpu_start.c:254 + +Behind the scenes, the command IDF Monitor runs to decode each address is:: + + xtensa-esp32-elf-addr2line -pfiaC -e build/PROJECT.elf ADDRESS + + +Launch GDB for GDBStub +====================== + +By default, if an esp-idf app crashes then the panic handler prints registers and a stack dump as shown above, and then resets. + +Optionally, the panic handler can be configured to run a serial "gdb stub" which can communicate with a gdb_ debugger program and allow memory to be read, variables and stack frames examined, etc. This is not as versatile as JTAG debugging, but no special hardware is required. + +To enable the gdbstub, run ``idf.py menuconfig`` and set :ref:`CONFIG_ESP32_PANIC` option to ``Invoke GDBStub``. + +If this option is enabled and IDF Monitor sees the gdb stub has loaded, it will automatically pause serial monitoring and run GDB with the correct arguments. After GDB exits, the board will be reset via the RTS serial line (if this is connected.) + +Behind the scenes, the command IDF Monitor runs is:: + + xtensa-esp32-elf-gdb -ex "set serial baud BAUD" -ex "target remote PORT" -ex interrupt build/PROJECT.elf + + +Quick Compile and Flash +======================= + +The keyboard shortcut ``Ctrl-T Ctrl-F`` will pause idf_monitor, run the ``idf.py flash`` target, then resume idf_monitor. Any changed source files will be recompiled before re-flashing. + +The keyboard shortcut ``Ctrl-T Ctrl-A`` will pause idf-monitor, run the ``idf.py app-flash`` target, then resume idf_monitor. This is similar to ``idf.py flash``, but only the main app is compiled and reflashed. + + +Quick Reset +=========== + +The keyboard shortcut ``Ctrl-T Ctrl-R`` will reset the target board via the RTS line (if it is connected.) + + +Pause the Application +===================== + +The keyboard shortcut ``Ctrl-T Ctrl-P`` will reset the target into bootloader, so that the board will run nothing. This is +useful when you want to wait for another device to startup. Then shortcut ``Ctrl-T Ctrl-R`` can be used to restart the +application. + + +Toggle Output Display +===================== + +Sometimes you may want to stop new output printed to screen, to see the log before. The keyboard shortcut ``Ctrl-T Ctrl-Y`` will +toggle the display (discard all serial data when the display is off) so that you can stop to see the log, and revert +again quickly without quitting the monitor. + + +Simple Monitor +============== + +Earlier versions of ESP-IDF used the pySerial_ command line program miniterm_ as a serial console program. + +This program can still be run, via ``make simple_monitor``. + +IDF Monitor is based on miniterm and shares the same basic keyboard shortcuts. + +.. note:: This target only works in the GNU Make based build system, not the CMake-based build system preview. + +Known Issues with IDF Monitor +============================= + +Issues Observed on Windows +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- If you are using the supported Windows environment and receive the error "winpty: command not found" then run ``pacman -S winpty`` to fix. +- Arrow keys and some other special keys in gdb don't work, due to Windows Console limitations. +- Occasionally when "make" exits, it may stall for up to 30 seconds before idf_monitor resumes. +- Occasionally when "gdb" is run, it may stall for a short time before it begins communicating with the gdbstub. + + +.. _addr2line: https://sourceware.org/binutils/docs/binutils/addr2line.html +.. _gdb: https://sourceware.org/gdb/download/onlinedocs/ +.. _pySerial: https://github.com/pyserial/pyserial +.. _miniterm: https://pyserial.readthedocs.org/en/latest/tools.html#module-serial.tools.miniterm diff --git a/docs/en/get-started-cmake/index.rst b/docs/en/get-started-cmake/index.rst new file mode 100644 index 000000000..faa715c8c --- /dev/null +++ b/docs/en/get-started-cmake/index.rst @@ -0,0 +1,464 @@ +******************* +Get Started (CMake) +******************* + +.. include:: ../cmake-warning.rst + +.. include:: ../cmake-pending-features.rst + +This document is intended to help users set up the software environment for development of applications using hardware based on the Espressif ESP32. Through a simple example we would like to illustrate how to use ESP-IDF (Espressif IoT Development Framework), including the menu based configuration, compiling the ESP-IDF and firmware download to ESP32 boards. + +Introduction +============ + +ESP32 integrates Wi-Fi (2.4 GHz band) and Bluetooth 4.2 solutions on a single chip, along with dual high performance cores, Ultra Low Power co-processor and several peripherals. Powered by 40 nm technology, ESP32 provides a robust, highly integrated platform to meet the continuous demands for efficient power usage, compact design, security, high performance, and reliability. + +Espressif provides the basic hardware and software resources that help application developers to build their ideas around the ESP32 series hardware. The software development framework by Espressif is intended for rapidly developing Internet-of-Things (IoT) applications, with Wi-Fi, Bluetooth, power management and several other system features. + + +What You Need +============= + +To develop applications for ESP32 you need: + +* **PC** loaded with either Windows, Linux or Mac operating system +* **Toolchain** to compile code for ESP32 +* **Build tools** CMake and Ninja to build a full **Application** for ESP32 +* **ESP-IDF** that essentially contains API for ESP32 and scripts to operate the **Toolchain** +* A text editor to write programs (**Projects**) in C, e.g. `Eclipse `_ +* The **ESP32** board itself and a **USB cable** to connect it to the **PC** + +.. figure:: ../../_static/what-you-need-cmake.png + :align: center + :alt: Development of applications for ESP32 + :figclass: align-center + + Development of applications for ESP32 + +Steps to set up Development Environment: + +1. Setup of **Toolchain** +2. Getting **ESP-IDF** from GitHub + +Once the development environment is set up, we will follow these steps to create an ESP-IDF application: + +1. Configuration of a **Project** and writing the code +2. Compilation of the **Project** and linking it to build an **Application** +3. Flashing (uploading) the compiled **Application** to **ESP32** over a USB/serial connection +4. Monitoring / debugging of the **Application** output via USB/serial + + +Development Board Guides +======================== + +If you have one of ESP32 development boards listed below, click on the link for hardware setup: + +.. toctree:: + :maxdepth: 1 + + ESP32 DevKitC + ESP-WROVER-KIT + ESP32-PICO-KIT + +If you have different board, move to sections below. + + +.. _get-started-setup-toolchain-cmake: + +Setup Toolchain +=============== + +The quickest way to start development with ESP32 is by installing a prebuilt toolchain. Pick up your OS below and follow provided instructions. + +.. toctree:: + :hidden: + + Windows + Linux + MacOS + ++-------------------+-------------------+-------------------+ +| |windows-logo| | |linux-logo| | |macos-logo| | ++-------------------+-------------------+-------------------+ +| `Windows`_ | `Linux`_ | `Mac OS`_ | ++-------------------+-------------------+-------------------+ + +.. |windows-logo| image:: ../../_static/windows-logo.png + :target: ../get-started-cmake/windows-setup.html + +.. |linux-logo| image:: ../../_static/linux-logo.png + :target: ../get-started-cmake/linux-setup.html + +.. |macos-logo| image:: ../../_static/macos-logo.png + :target: ../get-started-cmake/macos-setup.html + +.. _Windows: ../get-started-cmake/windows-setup.html +.. _Linux: ../get-started-cmake/linux-setup.html +.. _Mac OS: ../get-started-cmake/macos-setup.html + +.. note:: + + We are an using ``esp`` subdirectory in your user's home directory (``~/esp`` on Linux and MacOS, ``%userprofile%\esp`` on Windows) to install everything needed for ESP-IDF. You can use any different directory, but will need to adjust the respective commands. + +Depending on your experience and preferences, instead of using a prebuilt toolchain, you may want to customize your environment. To set up the system your own way go to section :ref:`get-started-customized-setup-cmake`. + +Once you are done with setting up the toolchain then go to section :ref:`get-started-get-esp-idf-cmake`. + +.. _get-started-get-esp-idf-cmake: + +Get ESP-IDF +=========== + +Besides the toolchain (that contains programs to compile and build the application), you also need ESP32 specific API / libraries. They are provided by Espressif in `ESP-IDF repository `_. To get it, open terminal, navigate to the directory you want to put ESP-IDF, and clone it using ``git clone`` command. + +Linux and MacOS +~~~~~~~~~~~~~~~ + +.. code-block:: bash + + mkdir -p ~/esp + cd ~/esp + git clone --branch feature/cmake --recursive https://github.com/espressif/esp-idf.git + +ESP-IDF will be downloaded into ``~/esp/esp-idf``. + + +Windows Command Prompt +~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: batch + + mkdir %userprofile%\esp + cd %userprofile%\esp + git clone --branch feature/cmake --recursive https://github.com/espressif/esp-idf.git + +.. highlight:: bash +.. note:: + + Do not miss the ``--recursive`` option. If you have already cloned ESP-IDF without this option, run another command to get all the submodules:: + + cd esp-idf + git submodule update --init + +.. note:: + + The CMake-based build system preview uses a different Git branch to the default. This branch is ``feature/cmake``. If you missed the ``--branch`` option when cloning then you can switch branches on the command line:: + + cd esp-idf + git checkout feature/cmake + +.. _get-started-setup-path-cmake: + +Setup Environment Variables +=========================== + +ESP-IDF requires two environment variables to be set for normal operation: + +- ``IDF_PATH`` should be set to the path to the ESP-IDF root directory. +- ``PATH`` should include the path to the ``tools`` directory inside the same ``IDF_PATH`` directory. + +These two variables should be set up on your PC, otherwise projects will not build. + +Setting may be done manually, each time PC is restarted. Another option is to set them permanently in user profile. To do this, follow instructions specific to :ref:`Windows ` , :ref:`Linux and MacOS ` in section :doc:`add-idf_path-to-profile`. + +.. _get-started-start-project-cmake: + +Start a Project +=============== + +Now you are ready to prepare your application for ESP32. To start off quickly, we will use :example:`get-started/hello_world` project from :idf:`examples` directory in IDF. + +Copy :example:`get-started/hello_world` to ``~/esp`` directory: + +Linux and MacOS +~~~~~~~~~~~~~~~ + +.. code-block:: bash + + cd ~/esp + cp -r $IDF_PATH/examples/get-started/hello_world . + +Windows Command Prompt +~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: batch + + cd %userprofile%\esp + xcopy /e /i %IDF_PATH%\examples\get-started\hello_world hello_world + +You can also find a range of example projects under the :idf:`examples` directory in ESP-IDF. These example project directories can be copied in the same way as presented above, to begin your own projects. + +It is also possible to build examples in-place, without copying them first. + +.. important:: + + The esp-idf build system does not support spaces in the path to either esp-idf or to projects. + +.. _get-started-connect-cmake: + +Connect +======= + +You are almost there. To be able to proceed further, connect ESP32 board to PC, check under what serial port the board is visible and verify if serial communication works. If you are not sure how to do it, check instructions in section :doc:`establish-serial-connection`. Note the port number, as it will be required in the next step. + +.. _get-started-configure-cmake: + +Configure +========= + +Naviagate to the directory of the ``hello_world`` application copy, and run the ``menuconfig`` project configuration utility: + +Linux and MacOS +~~~~~~~~~~~~~~~ + +.. code-block:: bash + + cd ~/esp/hello_world + idf.py menuconfig + +Windows Command Prompt +~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: batch + + cd %userprofile%\esp\hello_world + idf.py menuconfig + +.. note:: If you get an error about ``idf.py`` not being found, check the ``tools`` directory is part of your Path as described above in :ref:`get-started-setup-path-cmake`. If there is no ``idf.py`` in the ``tools`` directory, check you have the correct branch for the CMake preview as shown under :ref:`get-started-get-esp-idf-cmake`. + +.. note:: Windows users, the Python 2.7 installer will try to configure Windows to associate files with a ``.py`` extension with Python 2. If a separate installed program (such as Visual Studio Python Tools) has created an association with a different version of Python, then running ``idf.py`` may not work (it opens the file in Visual Studio instead). You can either run ``C:\Python27\python idf.py`` each time instead, or change the association that Windows uses for ``.py`` files. + +.. note:: Linux users, if your default version of Python is 3.x then you may need to run ``python2 idf.py`` instead. + +If previous steps have been done correctly, the following menu will be displayed: + +.. figure:: ../../_static/project-configuration.png + :align: center + :alt: Project configuration - Home window + :figclass: align-center + + Project configuration - Home window + +Here are couple of tips on navigation and use of ``menuconfig``: + +* Use up & down arrow keys to navigate the menu. +* Use Enter key to go into a submenu, Escape key to go up a level or exit. +* Type ``?`` to see a help screen. Enter key exits the help screen. +* Use Space key, or ``Y`` and ``N`` keys to enable (Yes) and disable (No) configuration items with checkboxes "``[*]``" +* Pressing ``?`` while highlighting a configuration item displays help about that item. +* Type ``/`` to search the configuration items. + +.. _get-started-build-cmake: + +Build The Project +================= + +.. highlight:: bash + +Now you can build the project. Run:: + + idf.py build + +This command will compile the application and all the ESP-IDF components, generate bootloader, partition table, and application binaries. + +.. code-block:: none + + $ idf.py build + Running cmake in directory /path/to/hello_world/build + Executing "cmake -G Ninja --warn-uninitialized /path/to/hello_world"... + Warn about uninitialized values. + -- Found Git: /usr/bin/git (found version "2.17.0") + -- Building empty aws_iot component due to configuration + -- Component names: ... + -- Component paths: ... + + ... (more lines of build system output) + + [527/527] Generating hello-world.bin + esptool.py v2.3.1 + + Project build complete. To flash, run this command: + ../../../components/esptool_py/esptool/esptool.py -p (PORT) -b 921600 write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x10000 build/hello-world.bin build 0x1000 build/bootloader/bootloader.bin 0x8000 build/partition_table/partition-table.bin + or run 'idf.py -p PORT flash' + +If there are no errors, the build will finish by generating the firmware binary .bin file. + +.. _get-started-flash-cmake: + +Flash To A Device +================= + +Now you can flash the application to the ESP32 board. Run:: + + idf.py -p PORT flash + +Replace PORT with the name of your ESP32 board's serial port. On Windows, serial ports have names like ``COM1``. On MacOS, they start with ``/dev/cu.``. On Linux, they start with ``/dev/tty``. See :doc:`establish-serial-connection` for full details. + +This step will flash the binaries that you just built to your ESP32 board. + +.. note:: Running ``idf.py build`` before ``idf.py flash`` is not actually necessary, the flash step will automatically build the project if required before flashing. + +.. code-block:: none + + Running esptool.py in directory [...]/esp/hello_world + Executing "python [...]/esp-idf/components/esptool_py/esptool/esptool.py -b 460800 write_flash @flash_project_args"... + esptool.py -b 460800 write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x1000 bootloader/bootloader.bin 0x8000 partition_table/partition-table.bin 0x10000 hello-world.bin + esptool.py v2.3.1 + Connecting.... + Detecting chip type... ESP32 + Chip is ESP32D0WDQ6 (revision 1) + Features: WiFi, BT, Dual Core + Uploading stub... + Running stub... + Stub running... + Changing baud rate to 460800 + Changed. + Configuring flash size... + Auto-detected Flash size: 4MB + Flash params set to 0x0220 + Compressed 22992 bytes to 13019... + Wrote 22992 bytes (13019 compressed) at 0x00001000 in 0.3 seconds (effective 558.9 kbit/s)... + Hash of data verified. + Compressed 3072 bytes to 82... + Wrote 3072 bytes (82 compressed) at 0x00008000 in 0.0 seconds (effective 5789.3 kbit/s)... + Hash of data verified. + Compressed 136672 bytes to 67544... + Wrote 136672 bytes (67544 compressed) at 0x00010000 in 1.9 seconds (effective 567.5 kbit/s)... + Hash of data verified. + + Leaving... + Hard resetting via RTS pin... + +If there are no issues, at the end of flash process, the module will be reset and “hello_world” application will be running there. + +.. (Not currently supported) If you'd like to use the Eclipse IDE instead of running ``idf.py``, check out the :doc:`Eclipse guide `. + + +.. _get-started-build-monitor-cmake: + +Monitor +======= + +To see if "hello_world" application is indeed running, type ``idf.py -p PORT monitor``. This command is launching :doc:`IDF Monitor ` application:: + + $ idf.py -p /dev/ttyUSB0 monitor + Running idf_monitor in directory [...]/esp/hello_world/build + Executing "python [...]/esp-idf/tools/idf_monitor.py -b 115200 [...]/esp/hello_world/build/hello-world.elf"... + --- idf_monitor on /dev/ttyUSB0 115200 --- + --- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- + ets Jun 8 2016 00:22:57 + + rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) + ets Jun 8 2016 00:22:57 + ... + +Several lines below, after start up and diagnostic log, you should see "Hello world!" printed out by the application. + +.. code-block:: none + + ... + Hello world! + Restarting in 10 seconds... + I (211) cpu_start: Starting scheduler on APP CPU. + Restarting in 9 seconds... + Restarting in 8 seconds... + Restarting in 7 seconds... + +To exit the monitor use shortcut ``Ctrl+]``. + +.. note:: + + If instead of the messages above, you see a random garbage similar to:: + + e���)(Xn@�y.!��(�PW+)��Hn9a؅/9�!�t5��P�~�k��e�ea�5�jA + ~zY��Y(1�,1�� e���)(Xn@�y.!Dr�zY(�jpi�|�+z5Ymvp + + or monitor fails shortly after upload, your board is likely using 26MHz crystal. Most development board designs use 40MHz and the ESP-IDF uses this default value. Exit the monitor, go back to the :ref:`menuconfig `, change :ref:`CONFIG_ESP32_XTAL_FREQ_SEL` to 26MHz, then :ref:`build and flash ` the application again. This is found under ``idf.py menuconfig`` under Component config --> ESP32-specific --> Main XTAL frequency. + +.. note:: + + You can combine building, flashing and monitoring into one step as follows:: + + idf.py -p PORT flash monitor + +Check the section :doc:`IDF Monitor ` for handy shortcuts and more details on using the monitor. + +Check the section :ref:`idf.py` for a full reference of ``idf.py`` commands and options. + +That's all what you need to get started with ESP32! + +Now you are ready to try some other :idf:`examples`, or go right to developing your own applications. + + +Updating ESP-IDF +================ + +After some time of using ESP-IDF, you may want to update it to take advantage of new features or bug fixes. The simplest way to do so is by deleting existing ``esp-idf`` folder and cloning it again, exactly as when doing initial installation described in sections :ref:`get-started-get-esp-idf-cmake`. + +Another solution is to update only what has changed. This method is useful if you have a slow connection to GitHub. To do the update run the following commands: + +Linux and MacOS +~~~~~~~~~~~~~~~ + +.. code-block:: bash + + cd ~/esp/esp-idf + git pull + git submodule update --init --recursive + +Windows Command Prompt +~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: batch + + cd %userprofile%\esp\esp-idf + git pull + git submodule update --init --recursive + +The ``git pull`` command is fetching and merging changes from ESP-IDF repository on GitHub. Then ``git submodule update --init --recursive`` is updating existing submodules or getting a fresh copy of new ones. On GitHub the submodules are represented as links to other repositories and require this additional command to get them onto your PC. + +.. highlight:: bash + +It is also possible to check out a specific release of ESP-IDF, e.g. `v2.1`. + +Linux and MacOS +~~~~~~~~~~~~~~~ + +.. code-block:: bash + + cd ~/esp + git clone https://github.com/espressif/esp-idf.git esp-idf-v2.1 + cd esp-idf-v2.1/ + git checkout v2.1 + git submodule update --init --recursive + + +Windows Command Prompt +~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: batch + + cd %userprofile%\esp + git clone https://github.com/espressif/esp-idf.git esp-idf-v2.1 + cd esp-idf-v2.1/ + git checkout v2.1 + git submodule update --init --recursive + +After that remember to :doc:`add-idf_path-to-profile`, so the toolchain scripts know where to find the ESP-IDF in it's release specific location. + +.. note:: + + Different versions of ESP-IDF may have different setup or prerequisite requirements, or require different toolchain versions. If you experience any problems, carefully check the Getting Started documentation for the version you are switching to. + + +Related Documents +================= + +.. toctree:: + :maxdepth: 1 + + add-idf_path-to-profile + establish-serial-connection + eclipse-setup + idf-monitor + toolchain-setup-scratch diff --git a/docs/en/get-started-cmake/linux-setup-scratch.rst b/docs/en/get-started-cmake/linux-setup-scratch.rst new file mode 100644 index 000000000..e1d2205d8 --- /dev/null +++ b/docs/en/get-started-cmake/linux-setup-scratch.rst @@ -0,0 +1,73 @@ +****************************************** +Setup Linux Toolchain from Scratch (CMake) +****************************************** + +.. include:: ../cmake-warning.rst + +The following instructions are alternative to downloading binary toolchain from Espressif website. To quickly setup the binary toolchain, instead of compiling it yourself, backup and proceed to section :doc:`linux-setup`. + +Install Prerequisites +===================== + +To compile with ESP-IDF you need to get the following packages: + +- CentOS 7:: + + sudo yum install git wget ncurses-devel flex bison gperf python pyserial cmake ninja-build ccache + +- Ubuntu and Debian:: + + sudo apt-get install git wget libncurses-dev flex bison gperf python python-serial cmake ninja-build ccache + +- Arch:: + + sudo pacman -S --needed gcc git make ncurses flex bison gperf python2-pyserial cmake ninja ccache + +.. note:: + CMake version 3.5 or newer is required for use with ESP-IDF. Older Linux distributions may require updating, enabling of a "backports" repository, or installing of a "cmake3" package rather than "cmake". + +Compile the Toolchain from Source +================================= + +- Install dependencies: + + - CentOS 7:: + + sudo yum install gawk gperf grep gettext ncurses-devel python python-devel automake bison flex texinfo help2man libtool make + + - Ubuntu pre-16.04:: + + sudo apt-get install gawk gperf grep gettext libncurses-dev python python-dev automake bison flex texinfo help2man libtool make + + - Ubuntu 16.04:: + + sudo apt-get install gawk gperf grep gettext python python-dev automake bison flex texinfo help2man libtool libtool-bin make + + - Debian 9:: + + sudo apt-get install gawk gperf grep gettext libncurses-dev python python-dev automake bison flex texinfo help2man libtool libtool-bin make + + - Arch:: + + TODO + +Download ``crosstool-NG`` and build it:: + + cd ~/esp + git clone -b xtensa-1.22.x https://github.com/espressif/crosstool-NG.git + cd crosstool-NG + ./bootstrap && ./configure --enable-local && make install + +Build the toolchain:: + + ./ct-ng xtensa-esp32-elf + ./ct-ng build + chmod -R u+w builds/xtensa-esp32-elf + +Toolchain will be built in ``~/esp/crosstool-NG/builds/xtensa-esp32-elf``. Follow :ref:`instructions for standard setup ` to add the toolchain to your ``PATH``. + + +Next Steps +========== + +To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf-cmake`. diff --git a/docs/en/get-started-cmake/linux-setup.rst b/docs/en/get-started-cmake/linux-setup.rst new file mode 100644 index 000000000..8977a582b --- /dev/null +++ b/docs/en/get-started-cmake/linux-setup.rst @@ -0,0 +1,112 @@ +********************************************* +Standard Setup of Toolchain for Linux (CMake) +********************************************* + +.. include:: ../cmake-warning.rst + +Install Prerequisites +===================== + +To compile with ESP-IDF you need to get the following packages: + +- CentOS 7:: + + sudo yum install git wget ncurses-devel flex bison gperf python pyserial cmake ninja-build ccache + +- Ubuntu and Debian:: + + sudo apt-get install git wget libncurses-dev flex bison gperf python python-serial cmake ninja-build ccache + +- Arch:: + + sudo pacman -S --needed gcc git make ncurses flex bison gperf python2-pyserial cmake ninja ccache + +.. note:: + CMake version 3.5 or newer is required for use with ESP-IDF. Older Linux distributions may require updating, enabling of a "backports" repository, or installing of a "cmake3" package rather than "cmake". + +Toolchain Setup +=============== + +ESP32 toolchain for Linux is available for download from Espressif website: + +- for 64-bit Linux: + + https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz + +- for 32-bit Linux: + + https://dl.espressif.com/dl/xtensa-esp32-elf-linux32-1.22.0-80-g6c4433a-5.2.0.tar.gz + +1. Download this file, then extract it in ``~/esp`` directory:: + + mkdir -p ~/esp + cd ~/esp + tar -xzf ~/Downloads/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz + +.. _setup-linux-toolchain-add-it-to-path-cmake: + +2. The toolchain will be extracted into ``~/esp/xtensa-esp32-elf/`` directory. + + To use it, you will need to update your ``PATH`` environment variable in ``~/.profile`` file. To make ``xtensa-esp32-elf`` available for all terminal sessions, add the following line to your ``~/.profile`` file:: + + export PATH="$PATH:$HOME/esp/xtensa-esp32-elf/bin" + + Alternatively, you may create an alias for the above command. This way you can get the toolchain only when you need it. To do this, add different line to your ``~/.profile`` file:: + + alias get_esp32='export PATH="$PATH:$HOME/esp/xtensa-esp32-elf/bin"' + + Then when you need the toolchain you can type ``get_esp32`` on the command line and the toolchain will be added to your ``PATH``. + + .. note:: + + If you have ``/bin/bash`` set as login shell, and both ``.bash_profile`` and ``.profile`` exist, then update ``.bash_profile`` instead. + +3. Log off and log in back to make the ``.profile`` changes effective. Run the following command to verify if ``PATH`` is correctly set:: + + printenv PATH + + You are looking for similar result containing toolchain's path at the end of displayed string:: + + $ printenv PATH + /home/user-name/bin:/home/user-name/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/user-name/esp/xtensa-esp32-elf/bin + + Instead of ``/home/user-name`` there should be a home path specific to your installation. + + +Permission issues /dev/ttyUSB0 +------------------------------ + +With some Linux distributions you may get the ``Failed to open port /dev/ttyUSB0`` error message when flashing the ESP32. :ref:`This can be solved by adding the current user to the dialout group`. + + +Arch Linux Users +---------------- + +To run the precompiled gdb (xtensa-esp32-elf-gdb) in Arch Linux requires ncurses 5, but Arch uses ncurses 6. + +Backwards compatibility libraries are available in AUR_ for native and lib32 configurations: + +- https://aur.archlinux.org/packages/ncurses5-compat-libs/ +- https://aur.archlinux.org/packages/lib32-ncurses5-compat-libs/ + +Before installing these packages you might need to add the author's public key to your keyring as described in the "Comments" section at the links above. + +Alternatively, use crosstool-NG to compile a gdb that links against ncurses 6. + + +Next Steps +========== + +To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf-cmake`. + + +Related Documents +================= + +.. toctree:: + :maxdepth: 1 + + linux-setup-scratch + + +.. _AUR: https://wiki.archlinux.org/index.php/Arch_User_Repository diff --git a/docs/en/get-started-cmake/macos-setup-scratch.rst b/docs/en/get-started-cmake/macos-setup-scratch.rst new file mode 100644 index 000000000..ae6e8c43e --- /dev/null +++ b/docs/en/get-started-cmake/macos-setup-scratch.rst @@ -0,0 +1,83 @@ +*********************************************** +Setup Toolchain for Mac OS from Scratch (CMake) +*********************************************** + +.. include:: ../cmake-warning.rst + +Package Manager +=============== + +To set up the toolchain from scratch, rather than :doc:`downloading a pre-compiled toolchain`, you will need to install either the MacPorts_ or homebrew_ package manager. + +MacPorts needs a full XCode installation, while homebrew only needs XCode command line tools. + + .. _homebrew: https://brew.sh/ + .. _MacPorts: https://www.macports.org/install.php + +Install Prerequisites +===================== + +- install pip:: + + sudo easy_install pip + +- install pyserial:: + + sudo pip install pyserial + +- install CMake & Ninja build: + + - If you have HomeBrew, you can run:: + + brew install cmake ninja + + - If you have MacPorts, you can run:: + + sudo port install cmake ninja + +Compile the Toolchain from Source +================================= + +- Install dependencies: + + - with MacPorts:: + + sudo port install gsed gawk binutils gperf grep gettext wget libtool autoconf automake make + + - with homebrew:: + + brew install gnu-sed gawk binutils gperftools gettext wget help2man libtool autoconf automake make + +Create a case-sensitive filesystem image:: + + hdiutil create ~/esp/crosstool.dmg -volname "ctng" -size 10g -fs "Case-sensitive HFS+" + +Mount it:: + + hdiutil mount ~/esp/crosstool.dmg + +Create a symlink to your work directory:: + + cd ~/esp + ln -s /Volumes/ctng crosstool-NG + +Download ``crosstool-NG`` and build it:: + + cd ~/esp + git clone -b xtensa-1.22.x https://github.com/espressif/crosstool-NG.git + cd crosstool-NG + ./bootstrap && ./configure --enable-local && make install + +Build the toolchain:: + + ./ct-ng xtensa-esp32-elf + ./ct-ng build + chmod -R u+w builds/xtensa-esp32-elf + +Toolchain will be built in ``~/esp/crosstool-NG/builds/xtensa-esp32-elf``. Follow :ref:`instructions for standard setup ` to add the toolchain to your ``PATH``. + + +Next Steps +========== + +To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf-cmake`. diff --git a/docs/en/get-started-cmake/macos-setup.rst b/docs/en/get-started-cmake/macos-setup.rst new file mode 100644 index 000000000..21a780c52 --- /dev/null +++ b/docs/en/get-started-cmake/macos-setup.rst @@ -0,0 +1,90 @@ +********************************************** +Standard Setup of Toolchain for Mac OS (CMake) +********************************************** + +.. include:: ../cmake-warning.rst + +Install Prerequisites +===================== + +ESP-IDF will use the version of Python installed by default on Mac OS. + +- install pip:: + + sudo easy_install pip + +- install pyserial:: + + sudo pip install pyserial + +- install CMake & Ninja build: + + - If you have HomeBrew_, you can run:: + + brew install cmake ninja + + - If you have MacPorts_, you can run:: + + sudo port install cmake ninja + + - Otherwise, consult the CMake_ and Ninja_ home pages for Mac OS installation downloads. + +- It is strongly recommended to also install ccache_ for faster builds. If you have HomeBrew_, this can be done via ``brew install ccache`` or ``sudo port install ccache`` on MacPorts_. + +.. note:: + If an error like this is shown during any step:: + + xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun + + Then you will need to install the XCode command line tools to continue. You can install these by running ``xcode-select --install``. + +Toolchain Setup +=============== + +ESP32 toolchain for macOS is available for download from Espressif website: + +https://dl.espressif.com/dl/xtensa-esp32-elf-osx-1.22.0-80-g6c4433a-5.2.0.tar.gz + +Download this file, then extract it in ``~/esp`` directory:: + + mkdir -p ~/esp + cd ~/esp + tar -xzf ~/Downloads/xtensa-esp32-elf-osx-1.22.0-80-g6c4433a-5.2.0.tar.gz + +.. _setup-macos-toolchain-add-it-to-path-cmake: + +The toolchain will be extracted into ``~/esp/xtensa-esp32-elf/`` directory. + +To use it, you will need to update your ``PATH`` environment variable in ``~/.profile`` file. To make ``xtensa-esp32-elf`` available for all terminal sessions, add the following line to your ``~/.profile`` file:: + + export PATH=$PATH:$HOME/esp/xtensa-esp32-elf/bin + +Alternatively, you may create an alias for the above command. This way you can get the toolchain only when you need it. To do this, add different line to your ``~/.profile`` file:: + + alias get_esp32="export PATH=$PATH:$HOME/esp/xtensa-esp32-elf/bin" + +Then when you need the toolchain you can type ``get_esp32`` on the command line and the toolchain will be added to your ``PATH``. + +Log off and log in back to make the ``.profile`` changes effective. Run the following command to verify if ``PATH`` is correctly set:: + + printenv PATH + + +Next Steps +========== + +To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf-cmake`. + +Related Documents +================= + +.. toctree:: + :maxdepth: 1 + + macos-setup-scratch + +.. _cmake: https://cmake.org/ +.. _ninja: https://ninja-build.org/ +.. _ccache: https://ccache.samba.org/ +.. _homebrew: https://brew.sh/ +.. _MacPorts: https://www.macports.org/install.php diff --git a/docs/en/get-started-cmake/toolchain-setup-scratch.rst b/docs/en/get-started-cmake/toolchain-setup-scratch.rst new file mode 100644 index 000000000..b5e9f0fbd --- /dev/null +++ b/docs/en/get-started-cmake/toolchain-setup-scratch.rst @@ -0,0 +1,25 @@ +.. _get-started-customized-setup-cmake: + +************************************* +Customized Setup of Toolchain (CMake) +************************************* + +Instead of downloading binary toolchain from Espressif website (see :ref:`get-started-setup-toolchain-cmake`) you may build the toolchain yourself. + +If you can't think of a reason why you need to build it yourself, then probably it's better to stick with the binary version. However, here are some of the reasons why you might want to compile it from source: + +- if you want to customize toolchain build configuration +- if you want to use a different GCC version (such as 4.8.5) +- if you want to hack gcc or newlib or libstdc++ +- if you are curious and/or have time to spare +- if you don't trust binaries downloaded from the Internet + +In any case, here are the instructions to compile the toolchain yourself. + +.. toctree:: + :maxdepth: 1 + + windows-setup-scratch + linux-setup-scratch + macos-setup-scratch + diff --git a/docs/en/get-started-cmake/windows-setup-scratch.rst b/docs/en/get-started-cmake/windows-setup-scratch.rst new file mode 100644 index 000000000..d8381ae68 --- /dev/null +++ b/docs/en/get-started-cmake/windows-setup-scratch.rst @@ -0,0 +1,89 @@ +******************************************** +Setup Windows Toolchain from Scratch (CMake) +******************************************** + +.. include:: ../cmake-warning.rst + +This is a step-by-step alternative to running the :doc:`ESP-IDF Tools Installer ` for the CMake-based build system. Installing all of the tools by hand allows more control over the process, and also provides the information for advanced users to customize the install. + +To quickly setup the toolchain and other tools in standard way, using the ESP-IDF Tools installer, proceed to section :doc:`windows-setup`. + + +.. note:: + The GNU Make based build system requires the MSYS2_ Unix compatibility environment on Windows. The CMake-based build system does not require this environment. + +Tools +===== + +cmake +^^^^^ + +Download the latest stable release of CMake_ for Windows and run the installer. + +When the installer asks for Install Options, choose either "Add CMake to the system PATH for all users" or "Add CMake to the system PATH for the current user". + +Ninja build +^^^^^^^^^^^ + +.. note:: + Ninja currently only provides binaries for 64-bit Windows. It is possible to use CMake and ``idf.py`` with other build tools, such as mingw-make, on 32-bit windows. However this is currently undocumented. + +Download the ninja_ latest stable Windows release from the (`download page `_). + +The Ninja for Windows download is a .zip file containing a single ``ninja.exe`` file which needs to be unzipped to a directory which is then `added to your Path `_ (or you can choose a directory which is already on your Path). + + +Python 2.x +^^^^^^^^^^ + +Download the latest Python_ 2.7 for Windows installer, and run it. + +The "Customise" step of the Python installer gives a list of options. The last option is "Add python.exe to Path". Change this option to select "Will be installed". + +Once Python is installed, open a Windows Command Prompt from the Start menu and run the following command:: + + pip install pyserial + +MConf for IDF +^^^^^^^^^^^^^ + +Download the configuration tool mconf-idf from the `kconfig-frontends releases page `_. This is the ``mconf`` configuration tool with some minor customizations for ESP-IDF. + +This tool will also need to be unzipped to a directory which is then `added to your Path `_. + +Toolchain Setup +=============== + +Download the precompiled Windows toolchain from dl.espressif.com: + +https://dl.espressif.com/dl/xtensa-esp32-elf-win32-1.22.0-80-g6c4433a-5.2.0.zip + +Unzip the zip file to ``C:\Program Files`` (or some other location). The zip file contains a single directory ``xtensa-esp32-elf``. + +Next, the ``bin`` subdirectory of this directory must be `added to your Path `_. For example, the directory to add may be ``C:\Program Files\xtensa-esp32-elf\bin``. + +.. note:: + If you already have the MSYS2 environment (for use with the "GNU Make" build system) installed, you can skip the separate download and add the directory ``C:\msys32\opt\xtensa-esp32-elf\bin`` to the Path instead, as the toolchain is included in the MSYS2 environment. + + +.. _add-directory-windows-path-cmake: + +Adding Directory to Path +======================== + +To add any new directory to your Windows Path environment variable: + +Open the System control panel and navigate to the Environment Variables dialog. (On Windows 10, this is found under Advanced System Settings). + +Double-click the ``Path`` variable (either User or System Path, depending if you want other users to have this directory on their path.) Go to the end of the value, and append ``;``. + + +Next Steps +========== + +To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf-cmake`. + +.. _ninja: https://ninja-build.org/ +.. _Python: https://www.python.org/downloads/windows/ +.. _MSYS2: https://msys2.github.io/ + diff --git a/docs/en/get-started-cmake/windows-setup.rst b/docs/en/get-started-cmake/windows-setup.rst new file mode 100644 index 000000000..c7393c8b9 --- /dev/null +++ b/docs/en/get-started-cmake/windows-setup.rst @@ -0,0 +1,71 @@ +*********************************************** +Standard Setup of Toolchain for Windows (CMake) +*********************************************** + +.. include:: ../cmake-warning.rst + +.. note:: + The CMake-based build system is only supported on 64-bit versions of Windows. + +Introduction +============ + +ESP-IDF requires some prerequisite tools to be installed so you can build firmware for the ESP32. The prerequisite tools include Git, a cross-compiler and the CMake build tool. We'll go over each one in this document. + +For this Getting Started we're going to use a command prompt, but after ESP-IDF is installed you can use :doc:`Eclipse ` or another graphical IDE with CMake support instead. + +.. note:: + The GNU Make based build system requires the MSYS2_ Unix compatibility environment on Windows. The CMake-based build system does not require this environment. + +ESP-IDF Tools Installer +======================= + +The easiest way to install ESP-IDF's prerequisites is to download the ESP-IDF Tools installer from this URL: + +https://dl.espressif.com/dl/esp-idf-tools-setup-1.1.exe + +The installer will automatically install the ESP32 Xtensa gcc toolchain, Ninja_ build tool, and a configuration tool called mconf-idf_. The installer can also download and run installers for CMake_ and Python_ 2.7 if these are not already installed on the computer. + +By default, the installer updates the Windows ``Path`` environment variable so all of these tools can be run from anywhere. If you disable this option, you will need to configure the environment where you are using ESP-IDF (terminal or chosen IDE) with the correct paths. + +Note that this installer is for the ESP-IDF Tools package, it doesn't include ESP-IDF itself. + +Installing Git +============== + +The ESP-IDF tools installer does not install Git. By default, the getting started guide assumes you will be using Git on the command line. You can download and install a command line Git for Windows (along with the "Git Bash" terminal) from `Git For Windows`_. + +If you prefer to use a different graphical Git client, then you can install one such as `Github Desktop`. You will need to translate the Git commands in the Getting Started guide for use with your chosen Git client. + +Using a Terminal +================ + +For the remaining Getting Started steps, we're going to use a terminal command prompt. It doesn't matter which command prompt you use: + +- You can use the built-in Windows Command Prompt, under the Start menu. All Windows command line instructions in this documentation are "batch" commands for use with the Windows Command Prompt. +- You can use the "Git Bash" terminal which is part of `Git for Windows`_. This uses the same "bash" command prompt syntax as is given for Mac OS or Linux. You can find it in the Start menu once installed. +- If you have MSYS2_ installed (maybe from a previous ESP-IDF version), then you can also use the MSYS terminal. + +Next Steps +========== + +To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf-cmake`. + +Related Documents +================= + +For advanced users who want to customize the install process: + +.. toctree:: + :maxdepth: 1 + + windows-setup-scratch + + +.. _MSYS2: https://msys2.github.io/ +.. _cmake: https://cmake.org/download/ +.. _ninja: https://ninja-build.org/ +.. _Python: https://www.python.org/downloads/windows/ +.. _Git for Windows: https://gitforwindows.org/ +.. _mconf-idf: https://github.com/espressif/kconfig-frontends/releases/ +.. _Github Desktop: https://desktop.github.com/ diff --git a/docs/en/get-started/add-idf_path-to-profile.rst b/docs/en/get-started/add-idf_path-to-profile.rst index 3529c86d0..8ce9a9ae6 100644 --- a/docs/en/get-started/add-idf_path-to-profile.rst +++ b/docs/en/get-started/add-idf_path-to-profile.rst @@ -1,40 +1,40 @@ -Add IDF_PATH & idf.py PATH to User Profile -========================================== - +Add IDF_PATH to User Profile +============================ :link_to_translation:`zh_CN:[中文]` +To preserve setting of ``IDF_PATH`` environment variable between system restarts, add it to the user profile, following instructions below. -.. note:: - This is documentation for the CMake-based build system which is currently in preview release. The documentation may have gaps, and you may encounter bugs (please report either of these). To view documentation for the older GNU Make based build system, switch versions to the 'latest' master branch or a stable release. -To use the CMake-based build system and the idf.py tool, two modifications need to be made to system environment variables: - -- ``IDF_PATH`` needs to be set to the path of the directory containing ESP-IDF. -- System ``PATH`` variable to include the directory containing the ``idf.py`` tool (part of ESP-IDF). - -To preserve setting of these variables between system restarts, add them to the user profile by following the instructions below. - -.. note:: If using an IDE, you can optionally set these environment variables in your IDE's project environment rather than from the command line as described below. - -.. note:: If you don't ever use the command line ``idf.py`` tool, but run cmake directly or via an IDE, then it is not necessary to set the ``PATH`` variable - only ``IDF_PATH``. However it can be useful to set both. - -.. note:: If you only ever use the command line ``idf.py`` tool, and never use cmake directly or via an IDE, then it is not necessary to set the ``IDF_PATH`` variable - ``idf.py`` will detect the directory it is contained within and set ``IDF_PATH`` appropriately if it is missing. - -.. _add-paths-to-profile-windows: +.. _add-idf_path-to-profile-windows: Windows ------- -To edit Environment Variables on Windows 10, search for "Edit Environment Variables" under the Start menu. +The user profile scripts are contained in ``C:/msys32/etc/profile.d/`` directory. They are executed every time you open an MSYS2 window. -On earlier Windows versions, open the System Control Panel then choose "Advanced" and look for the Environment Variables button. +#. Create a new script file in ``C:/msys32/etc/profile.d/`` directory. Name it ``export_idf_path.sh``. -You can set these environment variables for all users, or only for the current user, depending on whether other users of your computer will be using ESP-IDF. +#. Identify the path to ESP-IDF directory. It is specific to your system configuration and may look something like ``C:\msys32\home\user-name\esp\esp-idf`` -- Click ``New...`` to add a new environment variable named ``IDF_PATH``. Set the path to directory containing ESP-IDF, for example ``C:\Users\myuser\esp\esp-idf``. -- Locate the ``Path`` environment variable and double-click to edit it. Append the following to the end: ``;%IDF_PATH%\tools``. This will allow you to run ``idf.py`` and other tools from Windows Command Prompt. +#. Add the ``export`` command to the script file, e.g.:: -If you got here from section :ref:`get-started-setup-path`, while installing s/w for ESP32 development, then go back to section :ref:`get-started-start-project`. + export IDF_PATH="C:/msys32/home/user-name/esp/esp-idf" + + Remember to replace back-slashes with forward-slashes in the original Windows path. + +#. Save the script file. + +#. Close MSYS2 window and open it again. Check if ``IDF_PATH`` is set, by typing:: + + printenv IDF_PATH + + The path previusly entered in the script file should be printed out. + +If you do not like to have ``IDF_PATH`` set up permanently in user profile, you should enter it manually on opening of an MSYS2 window:: + + export IDF_PATH="C:/msys32/home/user-name/esp/esp-idf" + +If you got here from section :ref:`get-started-setup-path`, while installing s/w for ESP32 development, then go back to section :ref:`get-started-start-project`. .. _add-idf_path-to-profile-linux-macos: @@ -42,20 +42,15 @@ If you got here from section :ref:`get-started-setup-path`, while installing s/w Linux and MacOS --------------- -Set up ``IDF_PATH`` and add ``idf.py`` to the PATH by adding the following two lines to your ``~/.profile`` file:: +Set up ``IDF_PATH`` by adding the following line to ``~/.profile`` file:: export IDF_PATH=~/esp/esp-idf - export PATH="$PATH:$IDF_PATH/tools" + +Log off and log in back to make this change effective. .. note:: - ``~/.profile`` means a file named ``.profile`` in your user's home directory (which is abbreviated ``~`` in the shell). - -Log off and log in back to make this change effective. - -.. note:: - - Not all shells use ``.profile``. If you have ``/bin/bash`` and ``.bash_profile`` exists then update this file instead. For ``zsh``, update ``.zprofile``. Other shells may use other profile files (consult the shell's documentation). + If you have ``/bin/bash`` set as login shell, and both ``.bash_profile`` and ``.profile`` exist, then update ``.bash_profile`` instead. Run the following command to check if ``IDF_PATH`` is set:: @@ -63,15 +58,8 @@ Run the following command to check if ``IDF_PATH`` is set:: The path previously entered in ``~/.profile`` file (or set manually) should be printed out. -To verify idf.py is now on the ``PATH``, you can run the following:: - - which idf.py - -A path like ``${IDF_PATH}/tools/idf.py`` should be printed. - -If you do not like to have ``IDF_PATH`` or ``PATH`` modifications set, you can enter it manually in terminal window on each restart or logout:: +If you do not like to have ``IDF_PATH`` set up permanently, you should enter it manually in terminal window on each restart or logout:: export IDF_PATH=~/esp/esp-idf - export PATH="$PATH:$IDF_PATH/tools" If you got here from section :ref:`get-started-setup-path`, while installing s/w for ESP32 development, then go back to section :ref:`get-started-start-project`. diff --git a/docs/en/get-started/eclipse-setup-windows.rst b/docs/en/get-started/eclipse-setup-windows.rst new file mode 100644 index 000000000..62373485a --- /dev/null +++ b/docs/en/get-started/eclipse-setup-windows.rst @@ -0,0 +1,79 @@ +********************** +Eclipse IDE on Windows +********************** +:link_to_translation:`zh_CN:[中文]` + +Configuring Eclipse on Windows requires some different steps. The full configuration steps for Windows are shown below. + +(For OS X and Linux instructions, see the :doc:`Eclipse IDE page `.) + +Installing Eclipse IDE +====================== + +Follow the steps under :ref:`Installing Eclipse IDE ` for all platforms. + +.. _eclipse-windows-setup: + +Setting up Eclipse on Windows +============================= + +Once your new Eclipse installation launches, follow these steps: + +Import New Project +------------------ + +* Eclipse makes use of the Makefile support in ESP-IDF. This means you need to start by creating an ESP-IDF project. You can use the idf-template project from github, or open one of the examples in the esp-idf examples subdirectory. + +* Once Eclipse is running, choose File -> Import... + +* In the dialog that pops up, choose "C/C++" -> "Existing Code as Makefile Project" and click Next. + +* On the next page, enter "Existing Code Location" to be the directory of your IDF project. Don't specify the path to the ESP-IDF directory itself (that comes later). The directory you specify should contain a file named "Makefile" (the project Makefile). + +* On the same page, under "Toolchain for Indexer Settings" uncheck "Show only available toolchains that support this platform". + +* On the extended list that appears, choose "Cygwin GCC". Then click Finish. + +*Note: you may see warnings in the UI that Cygwin GCC Toolchain could not be found. This is OK, we're going to reconfigure Eclipse to find our toolchain.* + +Project Properties +------------------ + +* The new project will appear under Project Explorer. Right-click the project and choose Properties from the context menu. + +* Click on the "C/C++ Build" properties page (top-level): + + * Uncheck "Use default build command" and enter this for the custom build command: ``python ${IDF_PATH}/tools/windows/eclipse_make.py``. + +* Click on the "Environment" properties page under "C/C++ Build": + + * Click "Add..." and enter name ``BATCH_BUILD`` and value ``1``. + + * Click "Add..." again, and enter name ``IDF_PATH``. The value should be the full path where ESP-IDF is installed. The IDF_PATH directory should be specified using forwards slashes not backslashes, ie *C:/Users/user-name/Development/esp-idf*. + + * Edit the PATH environment variable. Delete the existing value and replace it with ``C:\msys32\usr\bin;C:\msys32\mingw32\bin;C:\msys32\opt\xtensa-esp32-elf\bin`` (If you installed msys32 to a different directory then you'll need to change these paths to match). + +* Click on "C/C++ General" -> "Preprocessor Include Paths, Macros, etc." property page: + + * Click the "Providers" tab + + * In the list of providers, click "CDT GCC Built-in Compiler Settings Cygwin". Under "Command to get compiler specs", replace the text ``${COMMAND}`` at the beginning of the line with ``xtensa-esp32-elf-gcc``. This means the full "Command to get compiler specs" should be ``xtensa-esp32-elf-gcc ${FLAGS} -E -P -v -dD "${INPUTS}"``. + + * In the list of providers, click "CDT GCC Build Output Parser" and type ``xtensa-esp32-elf-`` at the beginning of the Compiler command pattern, and wrap remaining part with brackets. This means the full Compiler command pattern should be ``xtensa-esp32-elf-((g?cc)|([gc]\+\+)|(clang))`` + + +Building in Eclipse +------------------- + +Continue from :ref:`Building in Eclipse ` for all platforms. + +Technical Details +================= + +**Of interest to Windows gurus or very curious parties, only.** + +Explanations of the technical reasons for some of these steps. You don't need to know this to use esp-idf with Eclipse on Windows, but it may be helpful background knowledge if you plan to do dig into the Eclipse support: + +* The xtensa-esp32-elf-gcc cross-compiler is *not* a Cygwin toolchain, even though we tell Eclipse that it is one. This is because msys2 uses Cygwin and supports Unix-style paths (of the type ``/c/blah`` instead of ``c:/blah`` or ``c:\\blah``). In particular, xtensa-esp32-elf-gcc reports to the Eclipse "built-in compiler settings" function that its built-in include directories are all under ``/usr/``, which is a Unix/Cygwin-style path that Eclipse otherwise can't resolve. By telling Eclipse the compiler is Cygwin, it resolves these paths internally using the ``cygpath`` utility. + +* The same problem occurs when parsing make output from esp-idf. Eclipse parses this output to find header directories, but it can't resolve include directories of the form ``/c/blah`` without using ``cygpath``. There is a heuristic that Eclipse Build Output Parser uses to determine whether it should call ``cygpath``, but for currently unknown reasons the esp-idf configuration doesn't trigger it. For this reason, the ``eclipse_make.py`` wrapper script is used to call ``make`` and then use ``cygpath`` to process the output for Eclipse. diff --git a/docs/en/get-started/eclipse-setup.rst b/docs/en/get-started/eclipse-setup.rst index 5d20efc3a..7d17d6c15 100644 --- a/docs/en/get-started/eclipse-setup.rst +++ b/docs/en/get-started/eclipse-setup.rst @@ -3,10 +3,108 @@ Build and Flash with Eclipse IDE ******************************** :link_to_translation:`zh_CN:[中文]` -.. note:: - This is documentation for the CMake-based build system which is currently in preview release. The documentation may have gaps, and you may enocunter bugs (please report either of these). To view documentation for the older GNU Make based build system, switch versions to the 'latest' master branch or a stable release. +.. _eclipse-install-steps: + +Installing Eclipse IDE +====================== + +The Eclipse IDE gives you a graphical integrated development environment for writing, compiling and debugging ESP-IDF projects. + +* Start by installing the esp-idf for your platform (see files in this directory with steps for Windows, OS X, Linux). + +* We suggest building a project from the command line first, to get a feel for how that process works. You also need to use the command line to configure your esp-idf project (via ``make menuconfig``), this is not currently supported inside Eclipse. + +* Download the Eclipse Installer for your platform from eclipse.org_. + +* When running the Eclipse Installer, choose "Eclipse for C/C++ Development" (in other places you'll see this referred to as CDT.) + +Windows Users +============= + +Using ESP-IDF with Eclipse on Windows requires different configuration steps. :ref:`See the Eclipse IDE on Windows guide `. + +Setting up Eclipse +================== + +Once your new Eclipse installation launches, follow these steps: + +Import New Project +------------------ + +* Eclipse makes use of the Makefile support in ESP-IDF. This means you need to start by creating an ESP-IDF project. You can use the idf-template project from github, or open one of the examples in the esp-idf examples subdirectory. + +* Once Eclipse is running, choose File -> Import... + +* In the dialog that pops up, choose "C/C++" -> "Existing Code as Makefile Project" and click Next. + +* On the next page, enter "Existing Code Location" to be the directory of your IDF project. Don't specify the path to the ESP-IDF directory itself (that comes later). The directory you specify should contain a file named "Makefile" (the project Makefile). + +* On the same page, under "Toolchain for Indexer Settings" choose "Cross GCC". Then click Finish. + + +Project Properties +------------------ + +* The new project will appear under Project Explorer. Right-click the project and choose Properties from the context menu. + +* Click on the "Environment" properties page under "C/C++ Build". Click "Add..." and enter name ``BATCH_BUILD`` and value ``1``. + +* Click "Add..." again, and enter name ``IDF_PATH``. The value should be the full path where ESP-IDF is installed. + +* Edit the ``PATH`` environment variable. Keep the current value, and append the path to the Xtensa toolchain installed as part of IDF setup, if this is not already listed on the PATH. A typical path to the toolchain looks like ``/home/user-name/esp/xtensa-esp32-elf/bin``. Note that you need to add a colon ``:`` before the appended path. + +* On macOS, add a ``PYTHONPATH`` environment variable and set it to ``/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages``. This is so that the system Python, which has pyserial installed as part of the setup steps, overrides any built-in Eclipse Python. + +Navigate to "C/C++ General" -> "Preprocessor Include Paths" property page: + +* Click the "Providers" tab + +* In the list of providers, click "CDT Cross GCC Built-in Compiler Settings". Under "Command to get compiler specs", replace the text ``${COMMAND}`` at the beginning of the line with ``xtensa-esp32-elf-gcc``. This means the full "Command to get compiler specs" should be ``xtensa-esp32-elf-gcc ${FLAGS} -E -P -v -dD "${INPUTS}"``. + +* In the list of providers, click "CDT GCC Build Output Parser" and type ``xtensa-esp32-elf-`` at the beginning of the Compiler command pattern. This means the full Compiler command pattern should be ``xtensa-esp32-elf-(g?cc)|([gc]\+\+)|(clang)`` + +.. _eclipse-build-project: + +Building in Eclipse +------------------- + +Before your project is first built, Eclipse may show a lot of errors and warnings about undefined values. This is because some source files are automatically generated as part of the esp-idf build process. These errors and warnings will go away after you build the project. + +* Click OK to close the Properties dialog in Eclipse. + +* Outside Eclipse, open a command line prompt. Navigate to your project directory, and run ``make menuconfig`` to configure your project's esp-idf settings. This step currently has to be run outside Eclipse. + +*If you try to build without running a configuration step first, esp-idf will prompt for configuration on the command line - but Eclipse is not able to deal with this, so the build will hang or fail.* + +* Back in Eclipse, choose Project -> Build to build your project. + +**TIP**: If your project had already been built outside Eclipse, you may need to do a Project -> Clean before choosing Project -> Build. This is so Eclipse can see the compiler arguments for all source files. It uses these to determine the header include paths. + +Flash from Eclipse +------------------ + +You can integrate the "make flash" target into your Eclipse project to flash using esptool.py from the Eclipse UI: + +* Right-click your project in Project Explorer (important to make sure you select the project, not a directory in the project, or Eclipse may find the wrong Makefile.) + +* Select Build Targets -> Create... from the context menu. + +* Type "flash" as the target name. Leave the other options as their defaults. + +* Now you can use Project -> Build Target -> Build (Shift+F9) to build the custom flash target, which will compile and flash the project. + +Note that you will need to use "make menuconfig" to set the serial port and other config options for flashing. "make menuconfig" still requires a command line terminal (see the instructions for your platform.) + +Follow the same steps to add ``bootloader`` and ``partition_table`` targets, if necessary. + +Related Documents +----------------- + +.. toctree:: + :maxdepth: 1 + + eclipse-setup-windows -Documentation for Eclipse setup with CMake-based build system and Eclipse CDT is coming soon. .. _eclipse.org: https://www.eclipse.org/ diff --git a/docs/en/get-started/establish-serial-connection.rst b/docs/en/get-started/establish-serial-connection.rst index 3566e8551..e54345d83 100644 --- a/docs/en/get-started/establish-serial-connection.rst +++ b/docs/en/get-started/establish-serial-connection.rst @@ -55,8 +55,6 @@ MacOS :: ls /dev/cu.* -.. note: MacOS users: if you don't see the serial port then check you have the USB/serial drivers installed as shown in the Getting Started guide for your particular development board. For MacOS High Sierra (10.13), you may also have to explicitly allow the drivers to load. Open System Preferences -> Security & Privacy -> General and check if there is a message shown here about "System Software from developer ..." where the developer name is Silicon Labs or FTDI. - .. _linux-dialout-group: Adding user to ``dialout`` on Linux @@ -128,4 +126,5 @@ If you see some legible log, it means serial connection is working and you are r If you got here from section :ref:`get-started-connect` when installing s/w for ESP32 development, then go back to section :ref:`get-started-configure`. + .. _esptool documentation: https://github.com/espressif/esptool/wiki/ESP32-Boot-Mode-Selection#automatic-bootloader diff --git a/docs/en/get-started/idf-monitor.rst b/docs/en/get-started/idf-monitor.rst index c54ed4314..09291a3d3 100644 --- a/docs/en/get-started/idf-monitor.rst +++ b/docs/en/get-started/idf-monitor.rst @@ -3,7 +3,7 @@ IDF Monitor *********** :link_to_translation:`zh_CN:[中文]` -The idf_monitor tool is a Python program which runs when the ``idf.py monitor`` target is invoked in IDF. +The IDF Monitor tool is a Python program which runs when the ``make monitor`` target is invoked in IDF. It is mainly a serial terminal program which relays serial data to and from the target device's serial port, but it has some other IDF-specific features. @@ -67,7 +67,7 @@ By default, if an esp-idf app crashes then the panic handler prints registers an Optionally, the panic handler can be configured to run a serial "gdb stub" which can communicate with a gdb_ debugger program and allow memory to be read, variables and stack frames examined, etc. This is not as versatile as JTAG debugging, but no special hardware is required. -To enable the gdbstub, run ``idf.py menuconfig`` and set :ref:`CONFIG_ESP32_PANIC` option to ``Invoke GDBStub``. +To enable the gdbstub, run ``make menuconfig`` and set :ref:`CONFIG_ESP32_PANIC` option to ``Invoke GDBStub``. If this option is enabled and IDF Monitor sees the gdb stub has loaded, it will automatically pause serial monitoring and run GDB with the correct arguments. After GDB exits, the board will be reset via the RTS serial line (if this is connected.) @@ -79,9 +79,9 @@ Behind the scenes, the command IDF Monitor runs is:: Quick Compile and Flash ======================= -The keyboard shortcut ``Ctrl-T Ctrl-F`` will pause idf_monitor, run the ``idf.py flash`` target, then resume idf_monitor. Any changed source files will be recompiled before re-flashing. +The keyboard shortcut ``Ctrl-T Ctrl-F`` will pause IDF Monitor, run the ``make flash`` target, then resume IDF Monitor. Any changed source files will be recompiled before re-flashing. -The keyboard shortcut ``Ctrl-T Ctrl-A`` will pause idf-monitor, run the ``idf.py app-flash`` target, then resume idf_monitor. This is similar to ``idf.py flash``, but only the main app is compiled and reflashed. +The keyboard shortcut ``Ctrl-T Ctrl-A`` will pause IDF Monitor, run the ``make app-flash`` target, then resume IDF Monitor. This is similar to ``make flash``, but only the main app is compiled and reflashed. Quick Reset @@ -115,7 +115,6 @@ This program can still be run, via ``make simple_monitor``. IDF Monitor is based on miniterm and shares the same basic keyboard shortcuts. -.. note:: This target only works in the GNU Make based build system, not the CMake-based build system preview. Known Issues with IDF Monitor ============================= diff --git a/docs/en/get-started/index.rst b/docs/en/get-started/index.rst index 431c097cf..9e33e6349 100644 --- a/docs/en/get-started/index.rst +++ b/docs/en/get-started/index.rst @@ -3,10 +3,7 @@ Get Started *********** :link_to_translation:`zh_CN:[中文]` -This document is intended to help users set up the software environment for development of applications using hardware based on the Espressif ESP32. Through a simple example we would like to illustrate how to use ESP-IDF (Espressif IoT Development Framework), including the menu based configuration, compiling the ESP-IDF and firmware download to ESP32 boards. - -.. note:: - The CMake-based build system is currently in preview release. Documentation may have missing gaps, and you may enocunter bugs (please report these). To view documentation for the older GNU Make based build system, switch versions to the 'latest' master branch or a stable release. +This document is intended to help users set up the software environment for development of applications using hardware based on the Espressif ESP32. Through a simple example we would like to illustrate how to use ESP-IDF (Espressif IoT Development Framework), including the menu based configuration, compiling the ESP-IDF and firmware download to ESP32 boards. Introduction @@ -23,8 +20,7 @@ What You Need To develop applications for ESP32 you need: * **PC** loaded with either Windows, Linux or Mac operating system -* **Toolchain** to compile code for ESP32 -* **Build tools** CMake and Ninja to build a full **Application** for ESP32 +* **Toolchain** to build the **Application** for ESP32 * **ESP-IDF** that essentially contains API for ESP32 and scripts to operate the **Toolchain** * A text editor to write programs (**Projects**) in C, e.g. `Eclipse `_ * The **ESP32** board itself and a **USB cable** to connect it to the **PC** @@ -36,23 +32,28 @@ To develop applications for ESP32 you need: Development of applications for ESP32 -Development Environment Steps: +Preparation of development environment consists of three steps: 1. Setup of **Toolchain** -2. Getting **ESP-IDF** from GitHub +2. Getting of **ESP-IDF** from GitHub +3. Installation and configuration of **Eclipse** -Once the development environment is set up, we will follow these steps to create an ESP-IDF application: +You may skip the last step, if you prefer to use different editor. + +Having environment set up, you are ready to start the most interesting part - the application development. This process may be summarized in four steps: 1. Configuration of a **Project** and writing the code 2. Compilation of the **Project** and linking it to build an **Application** -3. Flashing (uploading) the compiled **Application** to **ESP32** over a USB/serial connection -4. Monitoring / debugging of the **Application** output via USB/serial +3. Flashing (uploading) of the **Application** to **ESP32** +4. Monitoring / debugging of the **Application** + +See instructions below that will walk you through these steps. -Development Board Guides -======================== +Guides +====== -If you have one of ESP32 development boards listed below, click on the link for hardware setup: +If you have one of ESP32 development boards listed below, click on provided links to get you up and running. .. toctree:: :maxdepth: 1 @@ -99,12 +100,13 @@ The quickest way to start development with ESP32 is by installing a prebuilt too .. note:: - We are an using ``esp`` subdirectory in your user's home directory (``~/esp`` on Linux and Mac OS, ``%userprofile%\esp`` on Windows) to install everything needed for ESP-IDF. You can use any different directory, but will need to adjust the respective commands. + We are using ``~/esp`` directory to install the prebuilt toolchain, ESP-IDF and sample applications. You can use different directory, but need to adjust respective commands. Depending on your experience and preferences, instead of using a prebuilt toolchain, you may want to customize your environment. To set up the system your own way go to section :ref:`get-started-customized-setup`. Once you are done with setting up the toolchain then go to section :ref:`get-started-get-esp-idf`. + .. _get-started-get-esp-idf: Get ESP-IDF @@ -114,48 +116,26 @@ Get ESP-IDF Besides the toolchain (that contains programs to compile and build the application), you also need ESP32 specific API / libraries. They are provided by Espressif in `ESP-IDF repository `_. To get it, open terminal, navigate to the directory you want to put ESP-IDF, and clone it using ``git clone`` command:: - mkdir -p ~/esp cd ~/esp git clone --recursive https://github.com/espressif/esp-idf.git ESP-IDF will be downloaded into ``~/esp/esp-idf``. -.. highlight:: batch - -For **Windows Command Prompt** users, the equivalent commands are:: - - mkdir %userprofile%\esp - cd %userprofile%\esp - git clone --branch feature/cmake --recursive https://github.com/espressif/esp-idf.git - -.. highlight:: bash .. note:: Do not miss the ``--recursive`` option. If you have already cloned ESP-IDF without this option, run another command to get all the submodules:: - cd esp-idf + cd ~/esp/esp-idf git submodule update --init -.. note:: - - The CMake-based build system preview uses a different Git branch to the default. This branch is ``feature/cmake``. If you missed the ``--branch`` option when cloning then you can switch branches on the command line:: - - cd esp-idf - git checkout feature/cmake .. _get-started-setup-path: -Setup Environment Variables -=========================== +Setup Path to ESP-IDF +===================== -ESP-IDF requires two environment variables to be set for normal operation: +The toolchain programs access ESP-IDF using ``IDF_PATH`` environment variable. This variable should be set up on your PC, otherwise projects will not build. Setting may be done manually, each time PC is restarted. Another option is to set up it permanently by defining ``IDF_PATH`` in user profile. To do so, follow instructions specific to :ref:`Windows ` , :ref:`Linux and MacOS ` in section :doc:`add-idf_path-to-profile`. -- ``IDF_PATH`` should be set to the path to the ESP-IDF root directory. -- ``PATH`` should include the path to the ``tools`` directory inside the same ``IDF_PATH`` directory. - -These two variables should be set up on your PC, otherwise projects will not build. - -Setting may be done manually, each time PC is restarted. Another option is to set them permanently in user profile. To do this, follow instructions specific to :ref:`Windows ` , :ref:`Linux and MacOS ` in section :doc:`add-idf_path-to-profile`. .. _get-started-start-project: @@ -164,27 +144,16 @@ Start a Project Now you are ready to prepare your application for ESP32. To start off quickly, we will use :example:`get-started/hello_world` project from :idf:`examples` directory in IDF. -.. highlight:: bash - Copy :example:`get-started/hello_world` to ``~/esp`` directory:: cd ~/esp cp -r $IDF_PATH/examples/get-started/hello_world . -.. highlight:: batch - -For **Windows Command Prompt** users, the equivalent commands are:: - - cd %userprofile%\esp - xcopy /e /i %IDF_PATH%\examples\get-started\hello_world hello_world - You can also find a range of example projects under the :idf:`examples` directory in ESP-IDF. These example project directories can be copied in the same way as presented above, to begin your own projects. -It is also possible to build examples in-place, without copying them first. - .. important:: - The esp-idf build system does not support spaces in the path to either esp-idf or to projects. + The esp-idf build system does not support spaces in paths to esp-idf or to projects. .. _get-started-connect: @@ -194,32 +163,18 @@ Connect You are almost there. To be able to proceed further, connect ESP32 board to PC, check under what serial port the board is visible and verify if serial communication works. If you are not sure how to do it, check instructions in section :doc:`establish-serial-connection`. Note the port number, as it will be required in the next step. + .. _get-started-configure: Configure ========= -.. highlight:: bash - Being in terminal window, go to directory of ``hello_world`` application by typing ``cd ~/esp/hello_world``. Then start project configuration utility ``menuconfig``:: cd ~/esp/hello_world - idf.py menuconfig + make menuconfig -.. highlight:: batch - -For **Windows Command Prompt** users:: - - cd %userprofile%\esp\hello_world - idf.py menuconfig - -.. note:: If you get an error about ``idf.py`` not being found, check the ``tools`` directory is part of your Path as described above in :ref:`get-started-setup-path`. If there is no ``idf.py`` in the ``tools`` directory, check you have the correct branch for the CMake preview as shown under :ref:`get-started-get-esp-idf`. - -.. note:: Windows users, the Python 2.7 installer will try to configure Windows to associate files with a ``.py`` extension with Python 2. If a separate installed program (such as Visual Studio Python Tools) has created an association with a different version of Python, then running ``idf.py`` may not work. You can either run ``C:\Python27\python idf.py`` each time instead, or change the association that Windows uses for ``.py`` files. - -.. note:: Linux users, if your default version of Python is 3.x then you may need to run ``python2 idf.py`` instead. - -If previous steps have been done correctly, the following menu will be displayed: +If previous steps have been done correctly, the following menu will be displayed: .. figure:: ../../_static/project-configuration.png :align: center @@ -228,10 +183,17 @@ If previous steps have been done correctly, the following menu will be displayed Project configuration - Home window +In the menu, navigate to ``Serial flasher config`` > ``Default serial port`` to configure the serial port, where project will be loaded to. Confirm selection by pressing enter, save configuration by selecting ``< Save >`` and then exit application by selecting ``< Exit >``. + +.. note:: + + On Windows, serial ports have names like COM1. On MacOS, they start with ``/dev/cu.``. On Linux, they start with ``/dev/tty``. + (See :doc:`establish-serial-connection` for full details.) + Here are couple of tips on navigation and use of ``menuconfig``: * Use up & down arrow keys to navigate the menu. -* Use Enter key to go into a submenu, Escape key to go up a level or exit. +* Use Enter key to go into a submenu, Escape key to go out or to exit. * Type ``?`` to see a help screen. Enter key exits the help screen. * Use Space key, or ``Y`` and ``N`` keys to enable (Yes) and disable (No) configuration items with checkboxes "``[*]``" * Pressing ``?`` while highlighting a configuration item displays help about that item. @@ -241,91 +203,51 @@ Here are couple of tips on navigation and use of ``menuconfig``: If you are **Arch Linux** user, navigate to ``SDK tool configuration`` and change the name of ``Python 2 interpreter`` from ``python`` to ``python2``. + .. _get-started-build-flash: -Build The Project and Flash -=========================== +Build and Flash +=============== -.. highlight:: bash +Now you can build and flash the application. Run:: -Now you can build the project. Run:: + make flash - idf.py build - -This command will compile the application and all the ESP-IDF components, generate bootloader, partition table, and application binaries. - -.. highlight: none - -:: - $ idf.py build - Running cmake in directory /path/to/hello_world/build - Executing "cmake -G Ninja --warn-uninitialized /path/to/hello_world"... - Warn about uninitialized values. - -- Found Git: /usr/bin/git (found version "2.17.0") - -- Building empty aws_iot component due to configuration - -- Component names: ... - -- Component paths: ... - - ... (more lines of build system output) - - [527/527] Generating hello-world.bin - esptool.py v2.3.1 - - Project build complete. To flash, run this command: - ../../../components/esptool_py/esptool/esptool.py -p (PORT) -b 921600 write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x10000 build/hello-world.bin build 0x1000 build/bootloader/bootloader.bin 0x8000 build/partition_table/partition-table.bin - or run 'idf.py flash' - -If there are no errors, the build will finish by generating the firmware binary .bin file. - -Flash To A Device -================= - -Now you can flash the application to the ESP32 board. Run:: - - idf.py -p PORT flash - -Replace PORT with the name of your ESP32 board's serial port. On Windows, serial ports have names like ``COM1``. On MacOS, they start with ``/dev/cu.``. On Linux, they start with ``/dev/tty``. (See :doc:`establish-serial-connection` for full details.) - -This step will flash the binaries that you just built to your ESP32 board. - -.. note:: Running ``idf.py build`` before ``idf.py flash`` is not actually necessary, the flash step will automatically build the project if required before flashing. +This will compile the application and all the ESP-IDF components, generate bootloader, partition table, and application binaries, and flash these binaries to your ESP32 board. .. highlight:: none :: - Running esptool.py in directory [...]/esp/hello_world - Executing "python [...]/esp-idf/components/esptool_py/esptool/esptool.py -b 460800 write_flash @flash_project_args"... - esptool.py -b 460800 write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x1000 bootloader/bootloader.bin 0x8000 partition_table/partition-table.bin 0x10000 hello-world.bin - esptool.py v2.3.1 - Connecting.... - Detecting chip type... ESP32 - Chip is ESP32D0WDQ6 (revision 1) - Features: WiFi, BT, Dual Core - Uploading stub... - Running stub... - Stub running... - Changing baud rate to 460800 - Changed. - Configuring flash size... - Auto-detected Flash size: 4MB - Flash params set to 0x0220 - Compressed 22992 bytes to 13019... - Wrote 22992 bytes (13019 compressed) at 0x00001000 in 0.3 seconds (effective 558.9 kbit/s)... - Hash of data verified. - Compressed 3072 bytes to 82... - Wrote 3072 bytes (82 compressed) at 0x00008000 in 0.0 seconds (effective 5789.3 kbit/s)... - Hash of data verified. - Compressed 136672 bytes to 67544... - Wrote 136672 bytes (67544 compressed) at 0x00010000 in 1.9 seconds (effective 567.5 kbit/s)... - Hash of data verified. + esptool.py v2.0-beta2 + Flashing binaries to serial port /dev/ttyUSB0 (app at offset 0x10000)... + esptool.py v2.0-beta2 + Connecting........___ + Uploading stub... + Running stub... + Stub running... + Changing baud rate to 921600 + Changed. + Attaching SPI flash... + Configuring flash size... + Auto-detected Flash size: 4MB + Flash params set to 0x0220 + Compressed 11616 bytes to 6695... + Wrote 11616 bytes (6695 compressed) at 0x00001000 in 0.1 seconds (effective 920.5 kbit/s)... + Hash of data verified. + Compressed 408096 bytes to 171625... + Wrote 408096 bytes (171625 compressed) at 0x00010000 in 3.9 seconds (effective 847.3 kbit/s)... + Hash of data verified. + Compressed 3072 bytes to 82... + Wrote 3072 bytes (82 compressed) at 0x00008000 in 0.0 seconds (effective 8297.4 kbit/s)... + Hash of data verified. - Leaving... - Hard resetting via RTS pin... + Leaving... + Hard resetting... -If there are no issues, at the end of build process, you should see messages describing progress of flashing the project binary image onto the ESP32. Finally, the module will be reset and "hello_world" application will be running there. +If there are no issues, at the end of build process, you should see messages describing progress of loading process. Finally, the end module will be reset and "hello_world" application will start. -.. (Not currently supported) If you'd like to use the Eclipse IDE instead of running ``idf.py``, check out the :doc:`Eclipse guide `. +If you'd like to use the Eclipse IDE instead of running ``make``, check out the :doc:`Eclipse guide `. .. _get-started-build-monitor: @@ -333,11 +255,10 @@ If there are no issues, at the end of build process, you should see messages des Monitor ======= -To see if "hello_world" application is indeed running, type ``idf.py -p PORT monitor``. This command is launching :doc:`IDF Monitor ` application:: +To see if "hello_world" application is indeed running, type ``make monitor``. This command is launching :doc:`IDF Monitor ` application:: - $ idf.py -p /dev/ttyUSB0 monitor - Running idf_monitor in directory [...]/esp/hello_world/build - Executing "python [...]/esp-idf/tools/idf_monitor.py -b 115200 [...]/esp/hello_world/build/hello-world.elf"... + $ make monitor + MONITOR --- idf_monitor on /dev/ttyUSB0 115200 --- --- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- ets Jun 8 2016 00:22:57 @@ -356,7 +277,7 @@ Several lines below, after start up and diagnostic log, you should see "Hello wo Restarting in 8 seconds... Restarting in 7 seconds... -To exit the monitor use shortcut ``Ctrl+]``. +To exit the monitor use shortcut ``Ctrl+]``. .. note:: @@ -365,19 +286,11 @@ To exit the monitor use shortcut ``Ctrl+]``. e���)(Xn@�y.!��(�PW+)��Hn9a؅/9�!�t5��P�~�k��e�ea�5�jA ~zY��Y(1�,1�� e���)(Xn@�y.!Dr�zY(�jpi�|�+z5Ymvp - or monitor fails shortly after upload, your board is likely using 26MHz crystal. Most development board designs use 40MHz and the ESP-IDF uses this default value. Exit the monitor, go back to the :ref:`menuconfig `, change :ref:`CONFIG_ESP32_XTAL_FREQ_SEL` to 26MHz, then :ref:`build and flash ` the application again. This is found under ``idf.py menuconfig`` under Component config --> ESP32-specific --> Main XTAL frequency. + or monitor fails shortly after upload, your board is likely using 26MHz crystal, while the ESP-IDF assumes default of 40MHz. Exit the monitor, go back to the :ref:`menuconfig `, change :ref:`CONFIG_ESP32_XTAL_FREQ_SEL` to 26MHz, then :ref:`build and flash ` the application again. This is found under ``make menuconfig`` under Component config --> ESP32-specific --> Main XTAL frequency. -.. note:: +To execute ``make flash`` and ``make monitor`` in one go, type ``make flash monitor``. Check section :doc:`IDF Monitor ` for handy shortcuts and more details on using this application. - You can combine building, flashing and monitoring into one step as follows:: - - idf.py -p PORT flash monitor - -Check the section :doc:`IDF Monitor ` for handy shortcuts and more details on using the monitor. - -Check the section :ref:`idf.py` for a full reference of ``idf.py`` commands and options. - -That's all what you need to get started with ESP32! +That's all what you need to get started with ESP32! Now you are ready to try some other :idf:`examples`, or go right to developing your own applications. @@ -387,27 +300,15 @@ Updating ESP-IDF After some time of using ESP-IDF, you may want to update it to take advantage of new features or bug fixes. The simplest way to do so is by deleting existing ``esp-idf`` folder and cloning it again, exactly as when doing initial installation described in sections :ref:`get-started-get-esp-idf`. -.. highlight:: bash - Another solution is to update only what has changed. This method is useful if you have a slow connection to GitHub. To do the update run the following commands:: cd ~/esp/esp-idf git pull git submodule update --init --recursive -.. highlight:: batch - -For **Windows Command Prompt** users:: - - cd %userprofile%\esp\esp-idf - git pull - git submodule update --init --recursive - The ``git pull`` command is fetching and merging changes from ESP-IDF repository on GitHub. Then ``git submodule update --init --recursive`` is updating existing submodules or getting a fresh copy of new ones. On GitHub the submodules are represented as links to other repositories and require this additional command to get them onto your PC. -.. highlight:: bash - -To use a specific release of ESP-IDF, e.g. `v2.1`, run:: +If you would like to use specific release of ESP-IDF, e.g. `v2.1`, run:: cd ~/esp git clone https://github.com/espressif/esp-idf.git esp-idf-v2.1 @@ -415,22 +316,8 @@ To use a specific release of ESP-IDF, e.g. `v2.1`, run:: git checkout v2.1 git submodule update --init --recursive -.. highlight:: batch - -For **Windows Command Prompt** users:: - - cd %userprofile%\esp - git clone https://github.com/espressif/esp-idf.git esp-idf-v2.1 - cd esp-idf-v2.1/ - git checkout v2.1 - git submodule update --init --recursive - After that remember to :doc:`add-idf_path-to-profile`, so the toolchain scripts know where to find the ESP-IDF in it's release specific location. -.. note:: - - Different versions of ESP-IDF may have different setup or prerequisite requirements, or require different toolchain versions. If you experience any problems, carefully check the Getting Started documentation for the version you are switching to. - Related Documents ================= diff --git a/docs/en/get-started/linux-setup-scratch.rst b/docs/en/get-started/linux-setup-scratch.rst index 1c1d287e8..b2cb96ec3 100644 --- a/docs/en/get-started/linux-setup-scratch.rst +++ b/docs/en/get-started/linux-setup-scratch.rst @@ -2,9 +2,6 @@ Setup Linux Toolchain from Scratch ********************************** -.. note:: - This is documentation for the CMake-based build system which is currently in preview release. The documentation may have gaps, and you may encounter bugs (please report either of these). To view documentation for the older GNU Make based build system, switch versions to the 'latest' master branch or a stable release. - The following instructions are alternative to downloading binary toolchain from Espressif website. To quickly setup the binary toolchain, instead of compiling it yourself, backup and proceed to section :doc:`linux-setup`. @@ -13,20 +10,14 @@ Install Prerequisites To compile with ESP-IDF you need to get the following packages: -- CentOS 7:: - - sudo yum install git wget ncurses-devel flex bison gperf python pyserial cmake ninja-build ccache - - Ubuntu and Debian:: - sudo apt-get install git wget libncurses-dev flex bison gperf python python-serial cmake ninja-build ccache + sudo apt-get install git wget make libncurses-dev flex bison gperf python python-serial - Arch:: - sudo pacman -S --needed gcc git make ncurses flex bison gperf python2-pyserial cmake ninja ccache + sudo pacman -S --needed gcc git make ncurses flex bison gperf python2-pyserial -.. note:: - CMake version 3.5 or newer is required for use with ESP-IDF. Older Linux distributions may require updating, or enabling of a "backports" repository, or installing of a "cmake3" package not "cmake") Compile the Toolchain from Source ================================= @@ -35,19 +26,19 @@ Compile the Toolchain from Source - CentOS 7:: - sudo yum install gawk gperf grep gettext ncurses-devel python python-devel automake bison flex texinfo help2man libtool make + sudo yum install gawk gperf grep gettext ncurses-devel python python-devel automake bison flex texinfo help2man libtool - Ubuntu pre-16.04:: - sudo apt-get install gawk gperf grep gettext libncurses-dev python python-dev automake bison flex texinfo help2man libtool make + sudo apt-get install gawk gperf grep gettext libncurses-dev python python-dev automake bison flex texinfo help2man libtool - Ubuntu 16.04:: - sudo apt-get install gawk gperf grep gettext python python-dev automake bison flex texinfo help2man libtool libtool-bin make + sudo apt-get install gawk gperf grep gettext python python-dev automake bison flex texinfo help2man libtool libtool-bin - Debian 9:: - sudo apt-get install gawk gperf grep gettext libncurses-dev python python-dev automake bison flex texinfo help2man libtool libtool-bin make + sudo apt-get install gawk gperf grep gettext libncurses-dev python python-dev automake bison flex texinfo help2man libtool libtool-bin - Arch:: diff --git a/docs/en/get-started/linux-setup.rst b/docs/en/get-started/linux-setup.rst index 1b884be7f..bdc4467ce 100644 --- a/docs/en/get-started/linux-setup.rst +++ b/docs/en/get-started/linux-setup.rst @@ -3,9 +3,6 @@ Standard Setup of Toolchain for Linux ************************************* :link_to_translation:`zh_CN:[中文]` -.. note:: - This is documentation for the CMake-based build system which is currently in preview release. The documentation may have gaps, and you may encounter bugs (please report either of these). To view documentation for the older GNU Make based build system, switch versions to the 'latest' master branch or a stable release. - Install Prerequisites ===================== @@ -13,18 +10,16 @@ To compile with ESP-IDF you need to get the following packages: - CentOS 7:: - sudo yum install git wget ncurses-devel flex bison gperf python pyserial cmake ninja-build ccache + sudo yum install gcc git wget make ncurses-devel flex bison gperf python pyserial - Ubuntu and Debian:: - sudo apt-get install git wget libncurses-dev flex bison gperf python python-serial cmake ninja-build ccache + sudo apt-get install gcc git wget make libncurses-dev flex bison gperf python python-serial - Arch:: - sudo pacman -S --needed gcc git make ncurses flex bison gperf python2-pyserial cmake ninja ccache + sudo pacman -S --needed gcc git make ncurses flex bison gperf python2-pyserial -.. note:: - CMake version 3.5 or newer is required for use with ESP-IDF. Older Linux distributions may require updating, or enabling of a "backports" repository, or installing of a "cmake3" package not "cmake") Toolchain Setup =============== @@ -84,7 +79,7 @@ With some Linux distributions you may get the ``Failed to open port /dev/ttyUSB0 Arch Linux Users ---------------- -To run the precompiled gdb (xtensa-esp32-elf-gdb) in Arch Linux requires ncurses 5, but Arch uses ncurses 6. +To run the precompiled gdb (xtensa-esp32-elf-gdb) in Arch Linux requires ncurses 5, but Arch uses ncurses 6. Backwards compatibility libraries are available in AUR_ for native and lib32 configurations: diff --git a/docs/en/get-started/macos-setup-scratch.rst b/docs/en/get-started/macos-setup-scratch.rst index 53b8a9947..7516158a1 100644 --- a/docs/en/get-started/macos-setup-scratch.rst +++ b/docs/en/get-started/macos-setup-scratch.rst @@ -2,16 +2,6 @@ Setup Toolchain for Mac OS from Scratch *************************************** -Package Manager -=============== - -To set up the toolchain from scratch, rather than `downloading a precocmpiled toolchain`, you will need to install either the MacPorts_ or homebrew_ package manager. - -MacPorts needs a full XCode installation, while homebrew only needs XCode command line tools. - - .. _homebrew: https://brew.sh/ - .. _MacPorts: https://www.macports.org/install.php - Install Prerequisites ===================== @@ -23,28 +13,24 @@ Install Prerequisites sudo pip install pyserial -- install CMake & Ninja build: - - - If you have HomeBrew, you can run:: - - brew install cmake ninja - - - If you have MacPorts, you can run:: - - sudo port install cmake ninja Compile the Toolchain from Source ================================= - Install dependencies: + - Install either MacPorts_ or homebrew_ package manager. MacPorts needs a full XCode installation, while homebrew only needs XCode command line tools. + + .. _homebrew: https://brew.sh/ + .. _MacPorts: https://www.macports.org/install.php + - with MacPorts:: - sudo port install gsed gawk binutils gperf grep gettext wget libtool autoconf automake make + sudo port install gsed gawk binutils gperf grep gettext wget libtool autoconf automake - with homebrew:: - brew install gnu-sed gawk binutils gperftools gettext wget help2man libtool autoconf automake make + brew install gnu-sed gawk binutils gperftools gettext wget help2man libtool autoconf automake Create a case-sensitive filesystem image:: diff --git a/docs/en/get-started/macos-setup.rst b/docs/en/get-started/macos-setup.rst index 9c42d4759..16123cb03 100644 --- a/docs/en/get-started/macos-setup.rst +++ b/docs/en/get-started/macos-setup.rst @@ -3,14 +3,9 @@ Standard Setup of Toolchain for Mac OS ************************************** :link_to_translation:`zh_CN:[中文]` -.. note:: - This is documentation for the CMake-based build system which is currently in preview release. The documentation may have gaps, and you may encounter bugs (please report either of these). To view documentation for the older GNU Make based build system, switch versions to the 'latest' master branch or a stable release. - Install Prerequisites ===================== -ESP-IDF will use the version of Python installed by default on Mac OS. - - install pip:: sudo easy_install pip @@ -19,26 +14,6 @@ ESP-IDF will use the version of Python installed by default on Mac OS. sudo pip install pyserial -- install CMake & Ninja build: - - - If you have HomeBrew_, you can run:: - - brew install cmake ninja - - - If you have MacPorts_, you can run:: - - sudo port install cmake ninja - - - Otherwise, consult the CMake_ and Ninja_ home pages for Mac OS installation downloads. - -- It is strongly recommended to also install ccache_ for faster builds. If you have HomeBrew_, this can be done via ``brew install ccache`` or ``sudo port install ccache`` on MacPorts_. - -.. note:: - If an error like this is shown during any step:: - - xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun - - Then you will need to install the XCode command line tools to continue. You can install these by running ``xcode-select --install``. Toolchain Setup =============== @@ -73,6 +48,7 @@ Next Steps To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf`. + Related Documents ================= @@ -80,9 +56,3 @@ Related Documents :maxdepth: 1 macos-setup-scratch - -.. _cmake: https://cmake.org/ -.. _ninja: https://ninja-build.org/ -.. _ccache: https://ccache.samba.org/ -.. _homebrew: https://brew.sh/ -.. _MacPorts: https://www.macports.org/install.php diff --git a/docs/en/get-started/windows-setup-scratch.rst b/docs/en/get-started/windows-setup-scratch.rst index f7ee77081..4c772eeb3 100644 --- a/docs/en/get-started/windows-setup-scratch.rst +++ b/docs/en/get-started/windows-setup-scratch.rst @@ -2,81 +2,91 @@ Setup Windows Toolchain from Scratch ************************************ -This is a step-by-step alternative to running the :doc:`ESP-IDF Tools Installer ` for the CMake-based build system. Installing all of the tools by hand allows more control over the process, and also provides the information for advanced users to customize the install. +Setting up the environment gives you some more control over the process, and also provides the information for advanced users to customize the install. The :doc:`pre-built environment `, addressed to less experienced users, has been prepared by following these steps. -To quickly setup the toolchain and other tools in standard way, using the ESP-IDF Tools installer, proceed to section :doc:`windows-setup`. - -.. note:: - This is documentation for the CMake-based build system which is currently in preview release. The documentation may have gaps, and you may encounter bugs (please report either of these). To view documentation for the older GNU Make based build system, switch versions to the 'latest' master branch or a stable release. - -.. note:: - - Unlike the previous "GNU Make" based ESP-IDF build environment, the cmake environment does not include or require MSYS2 or any other Unix compatibility layer. - -Tools -===== - -cmake -^^^^^ - -Download the latest stable release of CMake_ for Windows and run the installer. - -When the installer asks for Install Options, choose either "Add CMake to the system PATH for all users" or "Add CMake to the system PATH for the current user". - -Ninja build -^^^^^^^^^^^ - -.. note:: - Ninja currently only provides binaries for 64-bit Windows. It is possible to use CMake and ``idf.py`` with other build tools, such as mingw-make, on 32-bit windows. However this is currently undocumented. - -Download the ninja_ latest stable Windows release from the (`download page `_). - -The Ninja for Windows download is a .zip file containing a single ``ninja.exe`` file which needs to be unzipped to a directory which is then `added to your Path `_ (or you can choose a directory which is already on your Path). +To quickly setup the toolchain in standard way, using a prebuilt environment, proceed to section :doc:`windows-setup`. -Python 2.x -^^^^^^^^^^ +.. _configure-windows-toolchain-from-scratch: -Download the latest Python_ 2.7 for Windows installer, and run it. +Configure Toolchain & Environment from Scratch +============================================== -The "Customise" step of the Python installer gives a list of options. The last option is "Add python.exe to Path". Change this option to select "Will be installed". +This process involves installing MSYS2_, then installing the MSYS2_ and Python packages which ESP-IDF uses, and finally downloading and installing the Xtensa toolchain. -Once Python is installed, open a Windows Command Prompt from the Start menu and run the following command:: +* Navigate to the MSYS2_ installer page and download the ``msys2-i686-xxxxxxx.exe`` installer executable (we only support a 32-bit MSYS environment, it works on both 32-bit and 64-bit Windows.) At time of writing, the latest installer is ``msys2-i686-20161025.exe``. - pip install pyserial +* Run through the installer steps. **Uncheck the "Run MSYS2 32-bit now" checkbox at the end.** -MConf for IDF -^^^^^^^^^^^^^ +* Once the installer exits, open Start Menu and find "MSYS2 MinGW 32-bit" to run the terminal. -Download the configuration tool mconf-idf from the `kconfig-frontends releases page `_. This is the ``mconf`` configuration tool with some minor customizations for ESP-IDF. + *(Why launch this different terminal? MSYS2 has the concept of different kinds of environments. The default "MSYS" environment is Cygwin-like and uses a translation layer for all Windows API calls. We need the "MinGW" environment in order to have a native Python which supports COM ports.)* -This tool will also need to be unzipped to a directory which is then `added to your Path `_. +* The ESP-IDF repository on github contains a script in the tools directory titled ``windows_install_prerequisites.sh``. If you haven't got a local copy of the ESP-IDF yet, that's OK - you can just download that one file in Raw format from here: :idf_raw:`tools/windows/windows_install_prerequisites.sh`. Save it somewhere on your computer. -Toolchain Setup -=============== +* Type the path to the shell script into the MSYS2 terminal window. You can type it as a normal Windows path, but use forward-slashes instead of back-slashes. ie: ``C:/Users/myuser/Downloads/windows_install_prerequisites.sh``. You can read the script beforehand to check what it does. -Download the precompiled Windows toolchain from dl.espressif.com: +* The ``windows_install_prerequisites.sh`` script will download and install packages for ESP-IDF support, and the ESP32 toolchain. + + +Troubleshooting +~~~~~~~~~~~~~~~ + +* While the install script runs, MSYS may update itself into a state where it can no longer operate. You may see errors like the following:: + + *** fatal error - cygheap base mismatch detected - 0x612E5408/0x612E4408. This problem is probably due to using incompatible versions of the cygwin DLL. + + If you see errors like this, close the terminal window entirely (terminating the processes running there) and then re-open a new terminal. Re-run ``windows_install_prerequisites.sh`` (tip: use the up arrow key to see the last run command). The update process will resume after this step. + +* MSYS2 is a "rolling" distribution so running the installer script may install newer packages than what is used in the prebuilt environments. If you see any errors that appear to be related to installing MSYS2 packages, please check the `MSYS2-packages issues list`_ for known issues. If you don't see any relevant issues, please `raise an IDF issue`_. + + +MSYS2 Mirrors in China +~~~~~~~~~~~~~~~~~~~~~~ + +There are some (unofficial) MSYS2 mirrors inside China, which substantially improves download speeds inside China. + +To add these mirrors, edit the following two MSYS2 mirrorlist files before running the setup script. The mirrorlist files can be found in the ``/etc/pacman.d`` directory (i.e. ``c:\msys2\etc\pacman.d``). + +Add these lines at the top of ``mirrorlist.mingw32``:: + + Server = https://mirrors.ustc.edu.cn/msys2/mingw/i686/ + Server = http://mirror.bit.edu.cn/msys2/REPOS/MINGW/i686 + +Add these lines at the top of ``mirrorlist.msys``:: + + Server = http://mirrors.ustc.edu.cn/msys2/msys/$arch + Server = http://mirror.bit.edu.cn/msys2/REPOS/MSYS2/$arch + + +HTTP Proxy +~~~~~~~~~~ + +You can enable an HTTP proxy for MSYS and PIP downloads by setting the ``http_proxy`` variable in the terminal before running the setup script:: + + export http_proxy='http://http.proxy.server:PORT' + +Or with credentials:: + + export http_proxy='http://user:password@http.proxy.server:PORT' + +Add this line to ``/etc/profile`` in the MSYS directory in order to permanently enable the proxy when using MSYS. + + +Alternative Setup: Just download a toolchain +============================================ + +If you already have an MSYS2 install or want to do things differently, you can download just the toolchain here: https://dl.espressif.com/dl/xtensa-esp32-elf-win32-1.22.0-80-g6c4433a-5.2.0.zip -Unzip the zip file to ``C:\Program Files`` (or some other location). The zip file contains a single directory ``xtensa-esp32-elf``. - -Next, the ``bin`` subdirectory of this directory must be `added to your Path `_. For example, the directory to add may be ``C:\Program Files\xtensa-esp32-elf\bin``. - .. note:: - If you already have the MSYS2 environment (for use with the "GNU Make" build system) installed, you can skip the separate download and add the directory ``C:\msys32\opt\xtensa-esp32-elf\bin`` to the Path instead, as the toolchain is included in the MSYS2 environment. + If you followed instructions :ref:`configure-windows-toolchain-from-scratch`, you already have the toolchain and you won't need this download. -.. _add-directory-windows-path: +.. important:: -Adding Directory to Path -======================== - -To add any new directory to your Windows Path environment variable: - -Open the System control panel and navigate to the Environment Variables dialog. (On Windows 10, this is found under Advanced System Settings). - -Double-click the ``Path`` variable (either User or System Path, depending if you want other users to have this directory on their path.) Go to the end of the value, and append ``;``. + Just having this toolchain is *not enough* to use ESP-IDF on Windows. You will need GNU make, bash, and sed at minimum. The above environments provide all this, plus a host compiler (required for menuconfig support). Next Steps @@ -84,5 +94,22 @@ Next Steps To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf`. -.. _ninja: https://ninja-build.org/ -.. _Python: https://www.python.org/downloads/windows/ +.. _updating-existing-windows-environment: + +Updating The Environment +======================== + +When IDF is updated, sometimes new toolchains are required or new system requirements are added to the Windows MSYS2 environment. + +Rather than setting up a new environment, you can update an existing Windows environment & toolchain: + +- Update IDF to the new version you want to use. +- Run the ``tools/windows/windows_install_prerequisites.sh`` script inside IDF. This will install any new software packages that weren't previously installed, and download and replace the toolchain with the latest version. + +The script to update MSYS2 may also fail with the same errors mentioned under Troubleshooting_. + +If you need to support multiple IDF versions concurrently, you can have different independent MSYS2 environments in different directories. Alternatively you can download multiple toolchains and unzip these to different directories, then use the PATH environment variable to set which one is the default. + +.. _MSYS2: https://msys2.github.io/ +.. _MSYS2-packages issues list: https://github.com/Alexpux/MSYS2-packages/issues/ +.. _raise an IDF issue: https://github.com/espressif/esp-idf/issues/new diff --git a/docs/en/get-started/windows-setup.rst b/docs/en/get-started/windows-setup.rst index c84959a96..9b143920b 100644 --- a/docs/en/get-started/windows-setup.rst +++ b/docs/en/get-started/windows-setup.rst @@ -3,61 +3,64 @@ Standard Setup of Toolchain for Windows *************************************** :link_to_translation:`zh_CN:[中文]` -.. note:: - This is documentation for the CMake-based build system which is currently in preview release. The documentation may have gaps, and you may encounter bugs (please report either of these). To view documentation for the older GNU Make based build system, switch versions to the 'latest' master branch or a stable release. - -.. note:: - The CMake-based build system is only supported on 64-bit versions of Windows. - Introduction ============ -ESP-IDF requires some prerequisite tools to be installed so you can build firmware for the ESP32. The prerequisite tools include Git, a cross-compiler and the CMake build tool. We'll go over each one in this document. +Windows doesn't have a built-in "make" environment, so as well as installing the toolchain you will need a GNU-compatible environment. We use the MSYS2_ environment to provide this. You don't need to use this environment all the time (you can use :doc:`Eclipse ` or some other front-end), but it runs behind the scenes. -For this Getting Started we're going to use a command prompt, but after ESP-IDF is installed you can use :doc:`Eclipse ` or another graphical IDE with CMake support instead. -.. note:: - Previous versions of ESP-IDF used a GNU Make based build system, which required the MSYS2_ Unix compatibility environment on Windows. This is no longer required. +Toolchain Setup +=============== -ESP-IDF Tools Installer -======================= +The quick setup is to download the Windows all-in-one toolchain & MSYS2 zip file from dl.espressif.com: -The easiest way to install ESP-IDF's prerequisites is to download the ESP-IDF Tools installer from this URL: +https://dl.espressif.com/dl/esp32_win32_msys2_environment_and_toolchain-20180110.zip -https://dl.espressif.com/dl/esp-idf-tools-setup-1.1.exe +Unzip the zip file to ``C:\`` (or some other location, but this guide assumes ``C:\``) and it will create an ``msys32`` directory with a pre-prepared environment. -The installer will automatically install the ESP32 Xtensa gcc toolchain, Ninja_ build tool, and a configuration tool called mconf-idf_. The installer can also download and run installers for CMake_ and Python_ 2.7 if these are not already installed on the computer. -By default, the installer updates the Windows ``Path`` environment variable so all of these tools can be run from anywhere. If you disable this option, you will need to configure the environment where you are using ESP-IDF (terminal or chosen IDE) with the correct paths. +Check it Out +============ -Note that this installer is for the ESP-IDF Tools package, it doesn't include ESP-IDF itself. +Open a MSYS2 MINGW32 terminal window by running ``C:\msys32\mingw32.exe``. The environment in this window is a bash shell. Create a directory named ``esp`` that is a default location to develop ESP32 applications. To do so, run the following shell command:: -Installing Git -============== + mkdir -p ~/esp -The ESP-IDF tools installer does not install Git. By default, the getting started guide assumes you will be using Git on the command line. You can download and install a command line Git for Windows (along with the "Git Bash" terminal) from `Git For Windows`_. +By typing ``cd ~/esp`` you can then move to the newly created directory. If there are no error messages you are done with this step. -If you prefer to use a different graphical Git client, then you can install one such as `Github Desktop`. You will need to translate the Git commands in the Getting Started guide for use with your chosen Git client. +.. figure:: ../../_static/msys2-terminal-window.png + :align: center + :alt: MSYS2 MINGW32 shell window + :figclass: align-center -Using a Terminal -================ + MSYS2 MINGW32 shell window -For the remaining Getting Started steps, we're going to use a terminal command prompt. It doesn't matter which command prompt you use: +Use this window in the following steps setting up development environment for ESP32. -- You can use the built-in Windows Command Prompt, under the Start menu. Note that command line instructions in this documentation give "bash" commands for Mac OS or Linux first. The Windows Command Prompt equivalent is given afterwards. -- You can use the "Git Bash" terminal which is part of `Git for Windows`_. This uses the same "bash" command prompt syntax as Mac OS or Linux. You can find it in the Start menu once installed. -- If you have MSYS2_ installed (maybe from a previous ESP-IDF version), then you can also use the MSYS terminal. Next Steps ========== To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf`. +Updating The Environment +======================== + +When IDF is updated, sometimes new toolchains are required or new requirements are added to the Windows MSYS2 environment. To move any data from an old version of the precompiled environment to a new one: + +- Take the old MSYS2 environment (ie ``C:\msys32``) and move/rename it to a different directory (ie ``C:\msys32_old``). +- Download the new precompiled environment using the steps above. +- Unzip the new MSYS2 environment to ``C:\msys32`` (or another location). +- Find the old ``C:\msys32_old\home`` directory and move this into ``C:\msys32``. +- You can now delete the ``C:\msys32_old`` directory if you no longer need it. + +You can have independent different MSYS2 environments on your system, as long as they are in different directories. + +There are :ref:`also steps to update the existing environment without downloading a new one `, although this is more complex. + Related Documents ================= -For advanced users who want to customize the install process: - .. toctree:: :maxdepth: 1 @@ -65,9 +68,3 @@ For advanced users who want to customize the install process: .. _MSYS2: https://msys2.github.io/ -.. _cmake: https://cmake.org/download/ -.. _ninja: https://ninja-build.org/ -.. _Python: https://www.python.org/downloads/windows/ -.. _Git for Windows: https://gitforwindows.org/ -.. _mconf-idf: https://github.com/espressif/kconfig-frontends/releases/ -.. _Github Desktop: https://desktop.github.com/ diff --git a/docs/en/index.rst b/docs/en/index.rst index 907d8f734..80cdfd482 100644 --- a/docs/en/index.rst +++ b/docs/en/index.rst @@ -4,9 +4,6 @@ ESP-IDF Programming Guide This is the documentation for Espressif IoT Development Framework (`esp-idf `_). ESP-IDF is the official development framework for the `ESP32 `_ chip. -.. note:: - This is documentation for the the CMake-based build system which is currently in preview release. The documentation may have gaps, and you may encounter bugs (please report either of these). To view documentation for the older GNU Make based build system, switch versions to the 'latest' master branch or a stable release. - The documentation has different language versions (:link_to_translation:`en:English`, :link_to_translation:`zh_CN:中文版`, :doc:`How to switch between languages? `). However, please refer to the English version if there is any discrepancy. ================== ================== ================== @@ -43,6 +40,7 @@ The documentation has different language versions (:link_to_translation:`en:Engl :hidden: Get Started + Get Started (CMake Preview) API Reference H/W Reference API Guides diff --git a/docs/zh_CN/api-guides/build-system-cmake.rst b/docs/zh_CN/api-guides/build-system-cmake.rst new file mode 100644 index 000000000..d70290e6e --- /dev/null +++ b/docs/zh_CN/api-guides/build-system-cmake.rst @@ -0,0 +1 @@ +.. include:: ../../en/api-guides/build-system-cmake.rst diff --git a/docs/zh_CN/api-guides/gnu-make-build-system.rst b/docs/zh_CN/api-guides/gnu-make-build-system.rst deleted file mode 100644 index 19bc45fc3..000000000 --- a/docs/zh_CN/api-guides/gnu-make-build-system.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../en/api-guides/gnu-make-build-system.rst diff --git a/docs/zh_CN/cmake-pending-features.rst b/docs/zh_CN/cmake-pending-features.rst new file mode 100644 index 000000000..6a45fbef9 --- /dev/null +++ b/docs/zh_CN/cmake-pending-features.rst @@ -0,0 +1 @@ +.. include:: /../en/cmake-pending-features.rst diff --git a/docs/zh_CN/cmake-warning.rst b/docs/zh_CN/cmake-warning.rst new file mode 100644 index 000000000..09479207f --- /dev/null +++ b/docs/zh_CN/cmake-warning.rst @@ -0,0 +1 @@ +.. include:: /../en/cmake-warning.rst diff --git a/docs/zh_CN/get-started-cmake/add-idf_path-to-profile.rst b/docs/zh_CN/get-started-cmake/add-idf_path-to-profile.rst new file mode 100644 index 000000000..2aacd4a4e --- /dev/null +++ b/docs/zh_CN/get-started-cmake/add-idf_path-to-profile.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/add-idf_path-to-profile.rst diff --git a/docs/zh_CN/get-started-cmake/eclipse-setup.rst b/docs/zh_CN/get-started-cmake/eclipse-setup.rst new file mode 100644 index 000000000..b7fd85471 --- /dev/null +++ b/docs/zh_CN/get-started-cmake/eclipse-setup.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/eclipse-setup.rst diff --git a/docs/zh_CN/get-started-cmake/establish-serial-connection.rst b/docs/zh_CN/get-started-cmake/establish-serial-connection.rst new file mode 100644 index 000000000..29f14b710 --- /dev/null +++ b/docs/zh_CN/get-started-cmake/establish-serial-connection.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/establish-serial-connection.rst diff --git a/docs/zh_CN/get-started-cmake/get-started-devkitc-v2.rst b/docs/zh_CN/get-started-cmake/get-started-devkitc-v2.rst new file mode 100644 index 000000000..155d0a53c --- /dev/null +++ b/docs/zh_CN/get-started-cmake/get-started-devkitc-v2.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/get-started-devkitc-v2.rst diff --git a/docs/zh_CN/get-started-cmake/get-started-devkitc.rst b/docs/zh_CN/get-started-cmake/get-started-devkitc.rst new file mode 100644 index 000000000..922a1445b --- /dev/null +++ b/docs/zh_CN/get-started-cmake/get-started-devkitc.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/get-started-devkitc.rst diff --git a/docs/zh_CN/get-started-cmake/get-started-pico-kit-v3.rst b/docs/zh_CN/get-started-cmake/get-started-pico-kit-v3.rst new file mode 100644 index 000000000..5cb327a30 --- /dev/null +++ b/docs/zh_CN/get-started-cmake/get-started-pico-kit-v3.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/get-started-pico-kit-v3.rst diff --git a/docs/zh_CN/get-started-cmake/get-started-pico-kit.rst b/docs/zh_CN/get-started-cmake/get-started-pico-kit.rst new file mode 100644 index 000000000..d409f1d16 --- /dev/null +++ b/docs/zh_CN/get-started-cmake/get-started-pico-kit.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/get-started-pico-kit.rst diff --git a/docs/zh_CN/get-started-cmake/get-started-wrover-kit-v2.rst b/docs/zh_CN/get-started-cmake/get-started-wrover-kit-v2.rst new file mode 100644 index 000000000..a742059bd --- /dev/null +++ b/docs/zh_CN/get-started-cmake/get-started-wrover-kit-v2.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/get-started-wrover-kit-v2.rst diff --git a/docs/zh_CN/get-started-cmake/get-started-wrover-kit.rst b/docs/zh_CN/get-started-cmake/get-started-wrover-kit.rst new file mode 100644 index 000000000..23227d7d5 --- /dev/null +++ b/docs/zh_CN/get-started-cmake/get-started-wrover-kit.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/get-started-wrover-kit.rst diff --git a/docs/zh_CN/get-started-cmake/idf-monitor.rst b/docs/zh_CN/get-started-cmake/idf-monitor.rst new file mode 100644 index 000000000..05b457188 --- /dev/null +++ b/docs/zh_CN/get-started-cmake/idf-monitor.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/idf-monitor.rst diff --git a/docs/zh_CN/get-started-cmake/index.rst b/docs/zh_CN/get-started-cmake/index.rst new file mode 100644 index 000000000..5c49b60a4 --- /dev/null +++ b/docs/zh_CN/get-started-cmake/index.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/index.rst diff --git a/docs/zh_CN/get-started-cmake/linux-setup-scratch.rst b/docs/zh_CN/get-started-cmake/linux-setup-scratch.rst new file mode 100644 index 000000000..1bc3dfab7 --- /dev/null +++ b/docs/zh_CN/get-started-cmake/linux-setup-scratch.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/linux-setup-scratch.rst diff --git a/docs/zh_CN/get-started-cmake/linux-setup.rst b/docs/zh_CN/get-started-cmake/linux-setup.rst new file mode 100644 index 000000000..048417a90 --- /dev/null +++ b/docs/zh_CN/get-started-cmake/linux-setup.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/linux-setup.rst diff --git a/docs/zh_CN/get-started-cmake/macos-setup-scratch.rst b/docs/zh_CN/get-started-cmake/macos-setup-scratch.rst new file mode 100644 index 000000000..82b866534 --- /dev/null +++ b/docs/zh_CN/get-started-cmake/macos-setup-scratch.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/macos-setup-scratch.rst diff --git a/docs/zh_CN/get-started-cmake/macos-setup.rst b/docs/zh_CN/get-started-cmake/macos-setup.rst new file mode 100644 index 000000000..e1bf5a2f6 --- /dev/null +++ b/docs/zh_CN/get-started-cmake/macos-setup.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/macos-setup.rst diff --git a/docs/zh_CN/get-started-cmake/toolchain-setup-scratch.rst b/docs/zh_CN/get-started-cmake/toolchain-setup-scratch.rst new file mode 100644 index 000000000..2bad626c9 --- /dev/null +++ b/docs/zh_CN/get-started-cmake/toolchain-setup-scratch.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/toolchain-setup-scratch.rst diff --git a/docs/zh_CN/get-started-cmake/windows-setup-scratch.rst b/docs/zh_CN/get-started-cmake/windows-setup-scratch.rst new file mode 100644 index 000000000..6ec60d320 --- /dev/null +++ b/docs/zh_CN/get-started-cmake/windows-setup-scratch.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/windows-setup-scratch.rst diff --git a/docs/zh_CN/get-started-cmake/windows-setup.rst b/docs/zh_CN/get-started-cmake/windows-setup.rst new file mode 100644 index 000000000..b03ce8af0 --- /dev/null +++ b/docs/zh_CN/get-started-cmake/windows-setup.rst @@ -0,0 +1 @@ +.. include:: ../../en/get-started-cmake/windows-setup.rst diff --git a/docs/zh_CN/get-started/eclipse-setup-windows.rst b/docs/zh_CN/get-started/eclipse-setup-windows.rst new file mode 100644 index 000000000..dbd07b565 --- /dev/null +++ b/docs/zh_CN/get-started/eclipse-setup-windows.rst @@ -0,0 +1,82 @@ +***************************************************** +Eclipse IDE 的创建和烧录指南(Windows 平台) +***************************************************** +:link_to_translation:`en:[English]` + +Windows 平台上的 Eclipse 配置略有不同,具体步骤请见下文。 + +注意:OS X 和 Linux 平台上的 Eclipse IDE 配置,请见 :doc:`Eclipse IDE page `。 + +安装 Eclipse IDE +================== + +Windows 平台的 Eclipse 安装步骤与其他平台相同,请见 :ref:`Installing Eclipse IDE `。 + +.. _eclipse-windows-setup: + + +Windows 平台上的 Eclipse 配置 +================================ + +完成 Eclipse IDE 的安装后,请按照下列步骤继续操作: + +导入新项目 +------------- + +* Eclipse IDE 需使用 ESP-IDF 的 Makefile 功能。因此,在使用 Eclipse 前,您需要先创建一个 ESP-IDF 项目。在创建 ESP-IDF 项目时,您可以使用 GitHub 中的 idf-template 项目模版,或从 esp-idf 子目录中选择一个 example。 + +* 运行 Eclipse,选择 “File” -> “Import...”。 + +* 在弹出的对话框中选择 “C/C++” -> “Existing Code as Makefile Project”,然后点击 “Next”。 + +* 下个界面,在 “Existing Code Location” 位置输入您的 IDF 项目的路径。注意,这里应填入 ESP-IDF 项目的路径,而非 ESP-IDF 的路径(稍后再填写)。此外,您指定的目录中应包含名为 “Makefile”(项目 Makefile)的文件。 + +* 在同一页面上,在 “Toolchain for Indexer Settings” 下取消选中 “Show only available toolchains that support this platform”。 + +* 在出现的扩展列表中,选择 “Cygwin GCC”。然后点击 “Finish”。 + +*注意:您可能看到有关“无法找到 Cygwin GCC 工具链”的警告。这种情况并不影响安装,我们只需重新配置 Eclipse,并找到我们的工具链即可。* + +项目属性 +---------- + +* 新项目将出现在 “Project Explorer” 下。请右键选择该项目,并在菜单中选择顶层 “Properties”。 + +* 点击 “C/C++ Build” 属性页。 + + * 取消选中 “Use default build command”,然后输入命令:``python${IDF_PATH}/tools/windows/eclipse_make.py``,开始自定义创建。 + +* 点击 “C/C++ Build” 下的 “Environment” 属性页面。 + + * 选择 “Add...”,并在对应位置输入 ``BATCH_BUILD`` 和 ``1``。 + + * 再次点击 “Add...”,输入名称 ``IDF_PATH``,并填写 ESP-IDF 的完整安装路径。``IDF_PATH`` 目录路径应使用正斜杠,而非反斜线,即 ``C:/Users/user-name/Development/esp-idf``。 + + * 选择 PATH 环境变量,删除默认值,并将其替换为 ``C:\msys32\usr\bin;C:\msys32\mingw32\bin;C:\msys32\opt\xtensa-esp32-elf\bin`` (如果您已经将 msys32 安装到其他目​​录,这里请自行调整)。 + + +* 点击 “C/C++ General” -> “Preprocessor Include Paths, Macros, etc.” 属性页。 + + * 点击 “Providers” 选项卡。 + + * 从 “Providers” 列表中选择 “CDT GCC Built-in Compiler Settings Cygwin”。在 “Command to get compiler specs” 输入框中,用 ``xtensa-esp32-elf-gcc`` 替换行首的 ``${COMMAND}``,最终完整的 ``Command to get compiler specs`` 应为 ``xtensa-esp32-elf-gcc ${FLAGS} -E -P -v -dD "${INPUTS}"``。 + + * 从 “Providers” 列表中选择 “CDT GCC Build Output Parser”,然后在 Compiler 命令模式的起始位置输入 ``xtensa-esp32-elf-``,并用括号把剩余部分扩起来。最终的完整 Compiler 命令模式应为 ``xtensa-esp32-elf-((g?cc)|([gc]\+\+)|(clang))``。 + + +在 Eclipse IDE 中创建项目 +--------------------------- + +Windows 平台的 Eclipse 项目创建步骤与其他平台相同,请见 :ref:`Building in Eclipse `。 + +技术细节 +========= + +**以下内容仅供 Windows 平台专家或非常感兴趣的开发者阅读。** + +Windows 平台的 Eclipse 介绍到此结束,下方将主要将介绍一些关键步骤的原理,助您了解更多 Eclipse 的背景信息。 + +* 首先,xtensa-esp32-elf-gcc 交叉编译器 *并非* Cygwin 工具链,但我们会在 Eclipse 中指定其为 Cygwin 工具链。主要原因在于:msys2 需要使用 Cygwin,并支持 Unix 风格的路径,即 ``/c/blah``,而非 ``c:/blah`` 或 ``c:\\blah``。特别需要说明的是,``xtensa-esp32-elf-gcc`` 会“告知” Eclipse 的 ``built-in compiler settings`` 功能,其内置 “include” 目录全部位于 ``/usr/`` 路径下,这也是 Eclipse 唯一可以解析的 ``Unix/Cygwin`` 风格路径。通过在 Eclipse 中指定 ``xtensa-esp32-elf-gcc`` 交叉编译器为 Cygwin 编译器,可以让 Eclipse 使用 cygpath 实用程序直接内部解析路径。 + + +* 在解析 ESP-IDF 的 make 结果时也经常会出现同样的问题。Eclipse 可以解析 make 的结果,查找头文件目录,但是无法脱离 ``cygpath``,直接解析类似 ``/c/blah`` 的目录。``Eclipse Build Output Parser`` 将利用该机制确认是否调用 ``cygpath``,但由于未知原因,目前 ESP-IDF 配置并不会触发该功能。出于这个原因,我们会使用 ``eclipse_make.py`` 包装脚本调用 ``make``,然后使用 ``cygpath`` 处理 Eclipse 的结果。 diff --git a/docs/zh_CN/get-started/eclipse-setup.rst b/docs/zh_CN/get-started/eclipse-setup.rst index e1bebd50e..e2f7be8a3 100644 --- a/docs/zh_CN/get-started/eclipse-setup.rst +++ b/docs/zh_CN/get-started/eclipse-setup.rst @@ -3,6 +3,107 @@ Eclipse IDE 的创建和烧录指南 **************************** :link_to_translation:`en:[English]` -.. important:: 对不起,CMake-based Build System Preview 还没有中文翻译。 +.. _eclipse-install-steps: + +安装 Eclipse IDE +================ + +Eclipse IDE 是一个可视化的集成开发环境,可用于编写、编译和调试 ESP-IDF 项目。 + +* 首先,请在您的平台上安装相应的 ESP-IDF,具体步骤请参考适用于 Windows、OS X 和 Linux 的相应安装步骤。 + +* 我们建议,您应首先使用命令行创建一个项目,大致熟悉项目的创建流程。此外,您还需要使用命令行 (``make menuconfig``) 对您的 ESP-IDF 项目进行配置。目前,Eclipse 尚不支持对 ESP-IDF 项目进行配置。 + +* 下载相应版本的 Eclipse Installer 至您的平台,点击 eclipse.org_。 + +* 运行 Eclipse Installer,选择 “Eclipse for C/C++ Development”(有的版本也可能显示为 CDT)。 + +Windows 用户 +============ + +在 Windows 平台上使用 Eclipse IDE 的用户,请参考 :ref:`Windows 用户的 Eclipse IDE 使用指南 `。 + +配置 Eclipse IDE +================= + +请打开安装好的 Eclipse IDE,并按照以下步骤进行操作: + +导入新项目 +---------- + +* Eclipse IDE 需使用 ESP-IDF 的 Makefile 功能。因此,在使用 Eclipse 前,您需要先创建一个 ESP-IDF 项目。在创建 ESP-IDF 项目时,您可以使用 GitHub 中的 idf-template 项目模版,或从 esp-idf 子目录中选择一个 example。 + +* 运行 Eclipse,选择 “File” -> “Import...”。 + +* 在弹出的对话框中选择 “C/C++” -> “Existing Code as Makefile Project”,然后点击 “Next”。 + +* 在下个界面中 “Existing Code Location” 位置输入您的 IDF 项目的路径。注意,这里应输入 ESP-IDF 项目的路径,而非 ESP-IDF 本身的路径(这个稍后再填)。此外,您指定的目标路径中应包含名为 ``Makefile`` (项目 Makefile)的文件。 + +* 在本界面,找到 “Toolchain for Indexer Settings”,选择 “Cross GCC”,最后点击 “Finish”。 + + +项目属性 +-------- + +* 新项目将出现在 “Project Explorer” 下。请右键选择该项目,并在菜单中选择 “Properties”。 + +* 点击 “C/C++ Build” 下的 “Environment” 属性页,选择 “Add...”,并在对应位置输入 ``BATCH_BUILD`` 和 ``1``。 + +* 再次点击 “Add...”,并在 “IDF_PATH” 中输入 ESP-IDF 所在的完整安装路径。 + +* 选择 “PATH” 环境变量,不要改变默认值。如果 Xtensa 工具链的路径尚不在 “PATH” 列表中,则应将该路径 (``something/xtensa-esp32-elf/bin``) 增加至列表。 + +* 在 macOS 平台上,增加一个 “PYTHONPATH” 环境变量,并将其设置为 ``/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages``, 保证系统中预先安装的 Python (需安装 pyserial 模块)可以覆盖 Eclipse 内置的任何 Python。 + +* 前往 “C/C++ General” -> “Preprocessor Include Paths” 属性页面。 + + * 点击 “Providers” 选项卡。从 “Providers” 列表中选择 “CDT Cross GCC Built-in Compiler Settings”。在 “Command to get compiler specs” 输入框中,用 ``xtensa-esp32-elf-gcc`` 替换行首的 ``${COMMAND}``,最终的完整 “Command to get compiler specs” 应为 ``xtensa-esp32-elf-gcc ${FLAGS} -E -P -v -dD "${INPUTS}"``。 + + * 从 “Providers” 列表中选择 “CDT GCC Build Output Parser”,然后在 “Compiler command pattern“ 输入框的起始位置输入 ``xtensa-esp32-elf-``,最终的完整编译器命令应为 ``xtensa-esp32-elf-(g?cc)|([gc]\+\+)|(clang)``。 + +.. _eclipse-build-project: + +在 Eclipse IDE 中创建项目 +-------------------------- + +在首次创建项目前,Eclipse IDE 可能会显示大量有关未定义值的错误和警告,主要原因在于项目编译过程中所需的一些源文件是在 ESP-IDF 项目创建过程中自动生成的。因此,这些错误和警告将在 ESP-IDF 项目生成完成后消失。 + +* 点击 “OK”,关闭 Eclipse IDE 中的 “Properties” 对话框。 + +* 在 Eclipse IDE 界面外,打开命令管理器。进入项目目录,并通过 ``make menuconfig`` 命令对您的 ESP-IDF 项目进行配置。现阶段,您还无法在 Eclipse 中完成本操作。 + +*如果您未进行最开始的配置步骤,ESP-IDF 将提示在命令行中进行配置 - 但由于 Eclipse 暂时不支持相关功能,因此该项目将挂起或创建失败。* + +* 返回 Eclipse IDE 界面中,选择 “Project” -> “Build” 创建您的项目。 + +**提示**:如果您已经在 Eclipse IDE 环境外创建了项目,则可能需要选择 “Project” -> “Clean before choosing Project” -> “Build”,允许 Eclipse 查看所有源文件的编译器参数,并借此确定头文件包含路径。 + +在 Eclipse IDE 中烧录项目 +-------------------------- + +您可以将 ``make flash`` 目标放在 Eclipse 项目中,通过 Eclipse UI 调用 ``esptool.py`` 进行烧录: + +* 打开 “Project Explorer”,并右击您的项目(请注意右击项目本身,而非项目下的子文件,否则 Eclipse 可能会找到错误的 ``Makefile``)。 + +* 从菜单中选择 “Make Targets” -> “Create”。 + +* 输入 “flash” 为目标名称,其他选项使用默认值。 + +* 选择 “Project” -> “Make Target” -> “Build (快捷键:Shift + F9)”,创建自定义烧录目标,用于编译、烧录项目。 + +注意,您将需要通过 ``make menuconfig``,设置串行端口和其他烧录选项。``make menuconfig`` 仍需通过命令行操作(请见平台的对应指南)。 + +如有需要,请按照相同步骤添加 ``bootloader`` 和 ``partition_table``。 + +相关文档 +-------- + +.. toctree:: + :maxdepth: 1 + + eclipse-setup-windows + + +.. _eclipse.org: https://www.eclipse.org/ diff --git a/docs/zh_CN/index.rst b/docs/zh_CN/index.rst index 9945da9bc..2a961055b 100644 --- a/docs/zh_CN/index.rst +++ b/docs/zh_CN/index.rst @@ -40,6 +40,7 @@ ESP-IDF 编程指南 :hidden: 快速入门 + 快速入门 (CMake 预览版本) API 参考 H/W 参考 API 指南 diff --git a/tools/idf.py b/tools/idf.py index 5837060fb..abf098445 100755 --- a/tools/idf.py +++ b/tools/idf.py @@ -346,7 +346,7 @@ def print_closing_message(args): args.port or "(PORT)", args.baud, cmd.strip())) - print("or run 'idf.py %s'" % (key + "-flash" if key != "project" else "flash",)) + print("or run 'idf.py -p PORT %s'" % (key + "-flash" if key != "project" else "flash",)) if "all" in args.actions or "build" in args.actions: print_flashing_message("Project", "project") diff --git a/tools/kconfig_new/confgen.py b/tools/kconfig_new/confgen.py index b78967d48..416c28d88 100755 --- a/tools/kconfig_new/confgen.py +++ b/tools/kconfig_new/confgen.py @@ -33,6 +33,9 @@ import pprint __version__ = "0.1" +if not "IDF_CMAKE" in os.environ: + os.environ["IDF_CMAKE"] = "" + def main(): parser = argparse.ArgumentParser(description='confgen.py v%s - Config Generation Tool' % __version__, prog=os.path.basename(sys.argv[0]))