Build & config: Remove the "make" build system

The "make" build system was deprecated in v4.0 in favor of idf.py
(cmake). The remaining support is removed in v5.0.
This commit is contained in:
Roland Dobai 2021-11-04 15:28:07 +01:00
parent 2df1743883
commit 9c1d4f5b54
120 changed files with 65 additions and 7396 deletions

26
Kconfig
View File

@ -6,7 +6,7 @@ mainmenu "Espressif IoT Development Framework Configuration"
config IDF_CMAKE
bool
option env="IDF_CMAKE"
default "y"
config IDF_ENV_FPGA
# This option is for internal use only
@ -93,29 +93,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
The prefix/path that is used to call the toolchain. The default setting assumes
a crosstool-ng gcc setup that is in your PATH.
config SDK_PYTHON
string "Python interpreter"
depends on !IDF_CMAKE
default "python"
help
The executable name/path that is used to run python.
(Note: This option is used with the legacy GNU Make build system only.)
config SDK_MAKE_WARN_UNDEFINED_VARIABLES
bool "'make' warns on undefined variables"
depends on !IDF_CMAKE
default "y"
help
Adds --warn-undefined-variables to MAKEFLAGS. This causes make to
print a warning any time an undefined variable is referenced.
This option helps find places where a variable reference is misspelled
or otherwise missing, but it can be unwanted if you have Makefiles which
depend on undefined variables expanding to an empty string.
(Note: this option is used with the legacy GNU Make build system only.)
config SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS
bool "Toolchain supports time_t wide 64-bits"
default n
@ -315,7 +292,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
menuconfig COMPILER_HIDE_PATHS_MACROS
bool "Replace ESP-IDF and project paths in binaries"
default y
depends on IDF_CMAKE
help
When expanding the __FILE__ and __BASE_FILE__ macros, replace paths inside ESP-IDF
with paths relative to the placeholder string "IDF", and convert paths inside the

View File

@ -1,59 +1,5 @@
menu "Serial flasher config"
config ESPTOOLPY_PORT
string "Default serial port"
depends on !IDF_CMAKE
default "/dev/ttyUSB0"
help
The serial port that's connected to the ESP chip. This can be overridden by setting the ESPPORT
environment variable.
This value is ignored when using the CMake-based build system or idf.py.
choice ESPTOOLPY_BAUD
prompt "Default baud rate"
depends on !IDF_CMAKE
default ESPTOOLPY_BAUD_115200B
help
Default baud rate to use while communicating with the ESP chip. Can be overridden by
setting the ESPBAUD variable.
This value is ignored when using the CMake-based build system or idf.py.
config ESPTOOLPY_BAUD_115200B
bool "115200 baud"
config ESPTOOLPY_BAUD_230400B
bool "230400 baud"
config ESPTOOLPY_BAUD_921600B
bool "921600 baud"
config ESPTOOLPY_BAUD_2MB
bool "2Mbaud"
config ESPTOOLPY_BAUD_OTHER
bool "Other baud rate"
endchoice
config ESPTOOLPY_BAUD_OTHER_VAL
int "Other baud rate value" if ESPTOOLPY_BAUD_OTHER
default 115200
config ESPTOOLPY_BAUD
int
depends on !IDF_CMAKE
default 115200 if ESPTOOLPY_BAUD_115200B
default 230400 if ESPTOOLPY_BAUD_230400B
default 921600 if ESPTOOLPY_BAUD_921600B
default 2000000 if ESPTOOLPY_BAUD_2MB
default ESPTOOLPY_BAUD_OTHER_VAL if ESPTOOLPY_BAUD_OTHER
config ESPTOOLPY_COMPRESSED
bool "Use compressed upload"
depends on !IDF_CMAKE
default "y"
help
The flasher tool can send data compressed using zlib, letting the ROM on the ESP chip
decompress it on the fly before flashing it. For most payloads, this should result in a
speed increase.
config ESPTOOLPY_NO_STUB
bool "Disable download stub"
default "n"

View File

@ -3,7 +3,6 @@
* Espressif IoT Development Framework (ESP-IDF) Configuration Header
*/
#pragma once
#define CONFIG_IDF_CMAKE 1
#define CONFIG_IDF_TARGET "esp32"
#define CONFIG_IDF_TARGET_ESP32 1
#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x0000
@ -21,7 +20,6 @@
#define CONFIG_BOOTLOADER_WDT_ENABLE 1
#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000
#define CONFIG_BOOTLOADER_RESERVE_RTC_SIZE 0x0
#define CONFIG_ESPTOOLPY_BAUD_OTHER_VAL 115200
#define CONFIG_ESPTOOLPY_WITH_STUB 1
#define CONFIG_ESPTOOLPY_FLASHMODE_DIO 1
#define CONFIG_ESPTOOLPY_FLASHMODE "dio"

View File

@ -64,12 +64,6 @@ TOUCH_SENSOR_DOCS = ['api-reference/peripherals/touch_pad.rst']
SPIRAM_DOCS = ['api-guides/external-ram.rst']
LEGACY_DOCS = ['api-guides/build-system-legacy.rst',
'gnu-make-legacy.rst',
'api-guides/ulp-legacy.rst',
'api-guides/unit-tests-legacy.rst',
'get-started-legacy/**']
USB_DOCS = ['api-reference/peripherals/usb_device.rst',
'api-reference/peripherals/usb_host.rst',
'api-guides/usb-otg-console.rst',
@ -96,7 +90,7 @@ ESP32_DOCS = ['api-guides/ulp_instruction_set.rst',
'security/secure-boot-v1.rst',
'api-reference/peripherals/secure_element.rst',
'api-reference/peripherals/dac.rst',
'hw-reference/esp32/**'] + LEGACY_DOCS + FTDI_JTAG_DOCS
'hw-reference/esp32/**'] + FTDI_JTAG_DOCS
ESP32S2_DOCS = ['hw-reference/esp32s2/**',
'api-guides/ulps2_instruction_set.rst',

View File

@ -481,20 +481,15 @@ Compiler Option
In order to obtain code coverage data in a project, one or more source files within the project must be compiled with the ``--coverage`` option. In ESP-IDF, this can be achieved at the component level or the individual source file level:
To cause all source files in a component to be compiled with the ``--coverage`` option.
- Add ``target_compile_options(${COMPONENT_LIB} PRIVATE --coverage)`` to the ``CMakeLists.txt`` file of the component if using CMake.
- Add ``CFLAGS += --coverage`` to the ``component.mk`` file of the component if using Make.
To cause a select number of source files (e.g. ``sourec1.c`` and ``source2.c``) in the same component to be compiled with the ``--coverage`` option.
- Add ``set_source_files_properties(source1.c source2.c PROPERTIES COMPILE_FLAGS --coverage)`` to the ``CMakeLists.txt`` file of the component if using CMake.
- Add ``source1.o: CFLAGS += --coverage`` and ``source2.o: CFLAGS += --coverage`` to the ``component.mk`` file of the component if using Make.
- To cause all source files in a component to be compiled with the ``--coverage`` option, you can add ``target_compile_options(${COMPONENT_LIB} PRIVATE --coverage)`` to the ``CMakeLists.txt`` file of the component.
- To cause a select number of source files (e.g. ``sourec1.c`` and ``source2.c``) in the same component to be compiled with the ``--coverage`` option, you can add ``set_source_files_properties(source1.c source2.c PROPERTIES COMPILE_FLAGS --coverage)`` to the ``CMakeLists.txt`` file of the component.
When a source file is compiled with the ``--coverage`` option (e.g. ``gcov_example.c``), the compiler will generate the ``gcov_example.gcno`` file in the project's build directory.
Project Configuration
~~~~~~~~~~~~~~~~~~~~~
Before building a project with source code coverage, ensure that the following project configuration options are enabled by running ``idf.py menuconfig`` (or ``make menuconfig`` if using the legacy Make build system).
Before building a project with source code coverage, ensure that the following project configuration options are enabled by running ``idf.py menuconfig``.
- Enable the application tracing module by choosing *Trace Memory* for the :ref:`CONFIG_APPTRACE_DESTINATION` option.
- Enable Gcov to host via the :ref:`CONFIG_APPTRACE_GCOV_ENABLE`
@ -508,7 +503,7 @@ Once a project has been complied with the ``--coverage`` option and flashed onto
The dumping of coverage data is done via OpenOCD (see :doc:`JTAG Debugging <../api-guides/jtag-debugging/index>` on how to setup and run OpenOCD). A dump is triggered by issuing commands to OpenOCD, therefore a telnet session to OpenOCD must be opened to issue such commands (run ``telnet localhost 4444``). Note that GDB could be used instead of telnet to issue commands to OpenOCD, however all commands issued from GDB will need to be prefixed as ``mon <oocd_command>``.
When the target dumps code coverage data, the ``.gcda`` files are stored in the project's build directory. For example, if ``gcov_example_main.c`` of the ``main`` component was compiled with the ``--coverage`` option, then dumping the code coverage data would generate a ``gcov_example_main.gcda`` in ``build/esp-idf/main/CMakeFiles/__idf_main.dir/gcov_example_main.c.gcda`` (or ``build/main/gcov_example_main.gcda`` if using the legacy Make build system). Note that the ``.gcno`` files produced during compilation are also placed in the same directory.
When the target dumps code coverage data, the ``.gcda`` files are stored in the project's build directory. For example, if ``gcov_example_main.c`` of the ``main`` component was compiled with the ``--coverage`` option, then dumping the code coverage data would generate a ``gcov_example_main.gcda`` in ``build/esp-idf/main/CMakeFiles/__idf_main.dir/gcov_example_main.c.gcda``. Note that the ``.gcno`` files produced during compilation are also placed in the same directory.
The dumping of code coverage data can be done multiple times throughout an application's life time. Each dump will simply update the ``.gcda`` file with the newest code coverage information. Code coverage data is accumulative, thus the newest data will contain the total execution count of each code path over the application's entire lifetime.
@ -558,10 +553,7 @@ Adding Gcovr Build Target to Project
To make report generation more convenient, users can define additional build targets in their projects such report generation can be done with a single build command.
CMake Build System
******************
For the CMake build systems, add the following lines to the ``CMakeLists.txt`` file of your project.
Add the following lines to the ``CMakeLists.txt`` file of your project.
.. code-block:: none
@ -573,32 +565,3 @@ The following commands can now be used:
* ``cmake --build build/ --target gcovr-report`` will generate an HTML coverage report in ``$(BUILD_DIR_BASE)/coverage_report/html`` directory.
* ``cmake --build build/ --target cov-data-clean`` will remove all coverage data files.
Make Build System
*****************
For the Make build systems, add the following lines to the ``Makefile`` of your project.
.. code-block:: none
GCOV := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))gcov
REPORT_DIR := $(BUILD_DIR_BASE)/coverage_report
gcovr-report:
echo "Generating coverage report in: $(REPORT_DIR)"
echo "Using gcov: $(GCOV)"
mkdir -p $(REPORT_DIR)/html
cd $(BUILD_DIR_BASE)
gcovr -r $(PROJECT_PATH) --gcov-executable $(GCOV) -s --html-details $(REPORT_DIR)/html/index.html
cov-data-clean:
echo "Remove coverage data files..."
find $(BUILD_DIR_BASE) -name "*.gcda" -exec rm {} +
rm -rf $(REPORT_DIR)
.PHONY: gcovr-report cov-data-clean
The following commands can now be used:
* ``make gcovr-report`` will generate an HTML coverage report in ``$(BUILD_DIR_BASE)/coverage_report/html`` directory.
* ``make cov-data-clean`` will remove all coverage data files.

View File

@ -135,10 +135,6 @@ When using the default :ref:`CONFIG_PARTITION_TABLE_OFFSET` value 0x8000, the si
If the bootloader binary is too large, then the bootloader build will fail with an error "Bootloader binary size [..] is too large for partition table offset". If the bootloader binary is flashed anyhow then the {IDF_TARGET_NAME} will fail to boot - errors will be logged about either invalid partition table or invalid bootloader checksum.
.. note::
The bootloader size check only happens in the CMake Build System, when using the legacy GNU Make Build System the size is not checked but the {IDF_TARGET_NAME} will fail to boot if bootloader is too large.
Options to work around this are:
- Set :ref:`bootloader compiler optimization <CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION>` back to "Size" if it has been changed from this default value.
@ -163,5 +159,3 @@ The current bootloader implementation allows a project to extend it or modify it
In the bootloader space, you cannot use the drivers and functions from other components. If necessary, then the required functionality should be placed in the project's `bootloader_components` directory (note that this will increase its size).
If the bootloader grows too large then it can collide with the partition table, which is flashed at offset 0x8000 by default. Increase the :ref:`partition table offset <CONFIG_PARTITION_TABLE_OFFSET>` value to place the partition table later in the flash. This increases the space available for the bootloader.
.. note:: Customize the bootloader by using either method is only supported with CMake build system (i.e. not supported with legacy Make build system).

View File

@ -1,535 +0,0 @@
Build System (Legacy GNU Make)
******************************
:link_to_translation:`zh_CN:[中文]`
.. include:: ../gnu-make-legacy.rst
This document explains the legacy GNU Make Espressif IoT Development Framework build system and the concept of "components"
Read this document if you want to know how to organise an ESP-IDF project using GNU Make build system.
We recommend using the esp-idf-template_ project as a starting point for your project.
Using the Build System
======================
The esp-idf README file contains a description of how to use the build system to build your project.
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 {IDF_TARGET_NAME} base libraries (libc, rom bindings etc)
- The Wi-Fi 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 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 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 ``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.
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, or the path to the toolchain can be set as part of the compiler prefix in the project configuration.
Example Project
---------------
An example project directory tree might look like this::
- myProject/
- Makefile
- sdkconfig
- components/ - component1/ - component.mk
- Kconfig
- src1.c
- 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 Makefile. This Makefile sets 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 "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. 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 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 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 Makefiles
-----------------
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 Makefile
^^^^^^^^^^^^^^^^^^^^^^^^
::
PROJECT_NAME := myProject
include $(IDF_PATH)/make/project.mk
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 ``make/project.mk`` for all of the implementation details.
- ``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.
- ``TEST_EXCLUDE_COMPONENTS``: Optional list of component names to exclude during the build process of unit tests.
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)``.
These variables should all be set before the line ``include $(IDF_PATH)/make/project.mk`` in the Makefile.
Component Makefiles
-------------------
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 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 `component.mk` file), or they can be top-level directories whose subdirectories are 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 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 Makefile
^^^^^^^^^^^^^^^^^^^^^^^^^^
The minimal ``component.mk`` file is an empty file(!). If the file is empty, the default component behaviour is set:
- 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.
See `example component makefiles`_ for more complete component makefile examples.
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.
.. component variables:
Preset Component Variables
^^^^^^^^^^^^^^^^^^^^^^^^^^
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.
- ``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 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.
- ``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`.
- ``IDF_VERSION_MAJOR``, ``IDF_VERSION_MINOR``, ``IDF_VERSION_PATCH``: Components of ESP-IDF version, to be used in conditional expressions. Note that this information is less precise than that provided by ``IDF_VER`` variable. ``v4.0-dev-*``, ``v4.0-beta1``, ``v4.0-rc1`` and ``v4.0`` will all have the same values of ``ESP_IDF_VERSION_*`` variables, but different ``IDF_VER`` values.
- ``PROJECT_VER``: Project version.
* If :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` option is set, the value of :ref:`CONFIG_APP_PROJECT_VER` will be used.
* Else, if ``PROJECT_VER`` variable is set in project Makefile file, its value will be used.
* Else, if the ``$PROJECT_PATH/version.txt`` exists, its contents will be used as ``PROJECT_VER``.
* Else, if the project is located inside a Git repository, the output of git describe will be used.
* Otherwise, ``PROJECT_VER`` will be "1".
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.
Optional Project-Wide Component Variables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The following variables can be set inside ``component.mk`` to control build settings across the entire project:
- ``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.
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_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.
- ``COMPONENT_ADD_LDFRAGMENTS``: Paths to linker fragment files for the linker script generation functionality. See :doc:`Linker Script Generation <linker-script-generation>`.
To apply compilation flags to a single source file, you can add a variable override as a target, ie::
apps/dhcpserver.o: CFLAGS += -Wno-unused-variable
This can be useful if there is upstream code that emits warnings.
Component Configuration
-----------------------
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.
For an example, see `Adding conditional configuration`_.
Preprocessor Definitions
------------------------
ESP-IDF build systems 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`` — ESP-IDF version, see `Preset Component Variables`_ for more details.
Build Process Internals
-----------------------
Top Level: Project Makefile
^^^^^^^^^^^^^^^^^^^^^^^^^^^
- "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.
To better understand the project make process, have a read through the ``project.mk`` file itself.
Second Level: Component Makefiles
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 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.
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.
Running Make Non-Interactively
------------------------------
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).
Setting ``BATCH_BUILD`` implies the following:
- 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.
.. _make-size:
Advanced Make Targets
---------------------
- ``make app``, ``make bootloader``, ``make partition table`` can be used to build only the app, bootloader, or partition table from the project as applicable.
- ``make erase_flash`` and ``make erase_otadata`` will use esptool.py to erase the entire flash chip and the OTA selection setting from the flash chip, respectively.
- ``make size`` prints some size information about the app. ``make size-components`` and ``make size-files`` are similar targets which print more detailed per-component or per-source-file information, respectively.
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-legacy:
Warning On Undefined Variables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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 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
-------------------------------
Makefile.projbuild
^^^^^^^^^^^^^^^^^^
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.
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.
``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".
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 ``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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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.
Example Component Makefiles
---------------------------
Because the build environment tries to set reasonable defaults that will work most 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.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 ``make menuconfig``. For this, ESP-IDF has the compile_only_if and compile_only_if_not macros:
``Kconfig``::
config FOO_ENABLE_BAR
bool "Enable the BAR feature."
help
This enables the BAR feature of the FOO component.
``component.mk``::
$(call compile_only_if,$(CONFIG_FOO_ENABLE_BAR),bar.o)
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:
``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
``component.mk``::
# 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
$(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 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::
COMPONENT_EXTRA_CLEAN := logo.h
graphics_lib.o: logo.h
logo.h: $(COMPONENT_PATH)/logo.bmp
bmp2h -i $^ -o $@
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 needs to be cleaned when make clean is called which why it is added to the COMPONENT_EXTRA_CLEAN variable.
Cosmetic Improvements
^^^^^^^^^^^^^^^^^^^^^
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 component.mk, giving the names of the files to embed in this way::
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::
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.
For an example of using this technique, see the "main" component of the file_serving example :example_file:`protocols/http_server/file_serving/main/component.mk` - two files are loaded at build time and linked into the firmware.
Code and Data Placements
------------------------
ESP-IDF has a feature called linker script generation that enables components to define where its code and data will be placed in memory through linker fragment files. These files are processed by the build system, and is used to augment the linker script used for linking app binary. See :doc:`Linker Script Generation <linker-script-generation>` for a quick start guide as well as a detailed discussion of the mechanism.
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 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.
It is possible for the component build target to build additional libraries and add these to the linker arguments as well. It's even possible for the default $(COMPONENT_LIBRARY) to be a dummy library, however it's used to track the overall build status so the build target should always create it.
.. note:: When using an external build process with PSRAM, remember to add ``-mfix-esp32-psram-cache-issue`` to the C compiler arguments. See :ref:`CONFIG_SPIRAM_CACHE_WORKAROUND` for details of this flag.
.. _esp-idf-template: https://github.com/espressif/esp-idf-template
.. _GNU Make Manual: https://www.gnu.org/software/make/manual/make.html
.. _custom-sdkconfig-defaults-legacy:
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 running ``make defconfig``, or creating a new config from scratch.
To override the name of this file, set the ``SDKCONFIG_DEFAULTS`` environment variable.
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. We can use command ``make print_flash_cmd``, it will print the flash arguments::
--flash_mode dio --flash_freq 40m --flash_size detect 0x1000 bootloader/bootloader.bin 0x10000 example_app.bin 0x8000 partition_table_unit_test_app.bin
Then use flash arguments as the arguemnts for esptool write_flash arguments::
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 "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 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.

View File

@ -5,11 +5,6 @@ Build System
This document explains the implementation of the ESP-IDF build system and the concept of "components". Read this document if you want to know how to organize and build a new ESP-IDF project or component.
.. only:: esp32
.. note:: This document describes the CMake-based build system, which is the default since ESP-IDF V4.0. ESP-IDF also supports a :doc:`legacy build system based on GNU Make <build-system-legacy>`, which was the default before ESP-IDF V4.0.
Overview
========
@ -1546,6 +1541,9 @@ Finalization
Browse :idf_file:`/tools/cmake/project.cmake` for more details.
.. _migrating_from_make:
Migrating from ESP-IDF GNU Make System
======================================
@ -1554,21 +1552,7 @@ Some aspects of the CMake-based ESP-IDF build system are very similar to the old
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.
.. important:: When the conversion tool converts a ``component.mk`` file, it doesn't determine what other components that component depends on. This information needs to be added manually by editing the new component ``CMakeLists.txt`` file and adding ``REQUIRES`` and/or ``PRIV_REQUIRES`` clauses. Otherwise, source files in the component will fail to compile as headers from other components are not found. See :ref:`component requirements`.
The conversion tool is not capable of dealing with complex Makefile logic or unusual targets. These will need to be converted by hand.
An automatic project conversion tool is available in `tools/cmake/convert_to_cmake.py` in ESP-IDF v4.x releases. The script was removed in v5.0 because of its `make` build system dependency.
No Longer Available in CMake
----------------------------

View File

@ -200,7 +200,7 @@ Generic command syntax: ``espcoredump.py [options] command [args]``
--core-format {b64,elf,raw}, -t {b64,elf,raw}
File specified with "-c" is an ELF ("elf"), raw (raw) or base64-encoded (b64) binary
--off OFF, -o OFF Offset of coredump partition in flash (type "make partition_table" to see).
--off OFF, -o OFF Offset of coredump partition in flash (type "idf.py partition-table" to see).
--save-core SAVE_CORE, -s SAVE_CORE
Save core to file. Otherwise temporary core file will be deleted. Does not work with "-c"

View File

@ -82,11 +82,6 @@ Then, in the component CMakeLists.txt, add this file as an unresolved symbol to
target_link_libraries(${COMPONENT_TARGET} "-u ld_include_my_isr_file")
If using the legacy Make build system, add the following to component.mk, instead::
COMPONENT_ADD_LDFLAGS := -u ld_include_my_isr_file
This should cause the linker to always include a file defining ``ld_include_my_isr_file``, causing the ISR to always be linked in.
- High-level interrupts can be routed and handled using esp_intr_alloc and associated functions. The handler and handler arguments

View File

@ -10,7 +10,6 @@ API Guides
:SOC_BT_SUPPORTED: BluFi <blufi>
Bootloader <bootloader>
Build System <build-system>
:esp32: Build System (Legacy GNU Make) <build-system-legacy>
Deep Sleep Wake Stubs <deep-sleep-stub>
:SOC_USB_OTG_SUPPORTED: Device Firmware Upgrade through USB <dfu>
Error Handling <error-handling>
@ -38,11 +37,9 @@ API Guides
Thread Local Storage <thread-local-storage>
Tools <tools/index>
:SOC_ULP_SUPPORTED: ULP Coprocessor <ulp>
:esp32: ULP Coprocessor (Legacy GNU Make) <ulp-legacy>
:SOC_RISCV_COPROC_SUPPORTED: ULP-RISC-V Coprocessor <ulp-risc-v>
Unit Testing (Target) <unit-tests>
Unit Testing (Linux Host) <linux-host-testing>
:esp32: Unit Testing (Legacy GNU Make) <unit-tests-legacy>
:SOC_USB_OTG_SUPPORTED: USB OTG Console <usb-otg-console>
:SOC_USB_SERIAL_JTAG_SUPPORTED: USB Serial/JTAG Controller Console <usb-serial-jtag-console>
Wi-Fi Driver <wifi>

View File

@ -45,18 +45,6 @@ Creating and Specifying a Linker Fragment File
Before anything else, a linker fragment file needs to be created. A linker fragment file is simply a text file with a ``.lf`` extension upon which the desired placements will be written. After creating the file, it is then necessary to present it to the build system. The instructions for the build systems supported by ESP-IDF are as follows:
Make
""""
In the component's ``component.mk`` file, set the variable ``COMPONENT_ADD_LDFRAGMENTS`` to the path of the created linker fragment file. The path can either be an absolute path or a relative path from the component directory.
.. code-block:: make
COMPONENT_ADD_LDFRAGMENTS += my_linker_fragment_file.lf
CMake
"""""
In the component's ``CMakeLists.txt`` file, specify argument ``LDFRAGMENTS`` in the ``idf_component_register`` call. The value of ``LDFRAGMENTS`` can either be an absolute path or a relative path from the component directory to the created linker fragment file.
.. code-block:: cmake

View File

@ -183,10 +183,6 @@ Currently these checks are performed for the following binaries:
Although the build process will fail if the size check returns an error, the binary files are still generated and can be flashed (although they may not work if they are too large for the available space.)
.. note::
Build system binary size checks are only performed when using the CMake build system. When using the legacy GNU Make build system, file sizes can be checked manually or an error will be logged during boot.
MD5 checksum
~~~~~~~~~~~~

View File

@ -11,7 +11,7 @@ The image contains:
- Common utilities such as git, wget, curl, zip.
- Python 3.6 or newer.
- A copy of a specific version of ESP-IDF (see below for information about versions). ``IDF_PATH`` environment variable is set, and points to ESP-IDF location in the container.
- All the build tools required for the specific version of ESP-IDF: CMake, make, ninja, cross-compiler toolchains, etc.
- All the build tools required for the specific version of ESP-IDF: CMake, ninja, cross-compiler toolchains, etc.
- All Python packages required by ESP-IDF are installed in a virtual environment.
The image entrypoint sets up ``PATH`` environment variable to point to the correct version of tools, and activates the Python virtual environment. As a result, the environment is ready to use the ESP-IDF build system.
@ -63,27 +63,6 @@ To build with a specific docker image tag, specify it as ``espressif/idf:TAG``,
You can check the up-to-date list of available tags at https://hub.docker.com/r/espressif/idf/tags.
Building a project with GNU Make
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Same as for CMake, except that the build command is different::
docker run --rm -v $PWD:/project -w /project espressif/idf make defconfig all -j4
.. note::
If the ``sdkconfig`` file does not exist, the default behavior of GNU Make build system is to open the menuconfig UI. This may be not desired in automated build environments. To ensure that the ``sdkconfig`` file exists, ``defconfig`` target is added before ``all``.
If you intend to build the same project repeatedly, you may bind the ``tools/kconfig`` directory of ESP-IDF to a named volume. This will prevent Kconfig tools, located in ESP-IDF directory, from being rebuilt, causing a rebuild of the rest of the project::
docker run --rm -v $PWD:/project -v kconfig:/opt/esp/idf/tools/kconfig -w /project espressif/idf make defconfig all -j4
If you need clean up the ``kconfig`` volume, run ``docker volume rm kconfig``.
Binding the ``tools/kconfig`` directory to a volume is not necessary when using the CMake build system.
Using the image interactively
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -8,9 +8,6 @@ The IDF monitor tool is mainly a serial terminal program which relays serial dat
This tool can be launched from an IDF project by running ``idf.py monitor``.
For the legacy GNU Make system, run ``make monitor``.
Keyboard Shortcuts
==================
@ -271,7 +268,7 @@ Issues Observed on Windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Arrow keys, as well as some other keys, do not work in GDB due to Windows Console limitations.
- Occasionally, when "idf.py" or "make" exits, it might stall for up to 30 seconds before IDF Monitor resumes.
- Occasionally, when "idf.py" exits, it might stall for up to 30 seconds before IDF Monitor resumes.
- When "gdb" is run, it might stall for a short time before it begins communicating with the GDBStub.
.. _addr2line: https://sourceware.org/binutils/docs/binutils/addr2line.html

View File

@ -1,166 +0,0 @@
The ULP Coprocessor (Legacy GNU Make)
======================================
:link_to_translation:`zh_CN:[中文]`
.. toctree::
:maxdepth: 1
Instruction set reference <ulp_instruction_set>
Programming using macros (legacy) <ulp_macros>
.. include:: ../gnu-make-legacy.rst
The ULP (Ultra Low Power) coprocessor is a simple FSM (Finite State Machine) which is designed to perform measurements using the ADC, temperature sensor, and external I2C sensors, while the main processors are in deep sleep mode. The ULP coprocessor can access the RTC_SLOW_MEM memory region, and registers in RTC_CNTL, RTC_IO, and SARADC peripherals. The ULP coprocessor uses fixed-width 32-bit instructions, 32-bit memory addressing, and has 4 general-purpose 16-bit registers.
Installing the Toolchain
------------------------
The ULP coprocessor code is written in assembly and compiled using the `binutils-esp32ulp toolchain`.
1. Download pre-built binaries of the latest toolchain release from:
https://github.com/espressif/binutils-esp32ulp/releases.
2. Extract the toolchain into a directory, and add the path to the ``bin/`` directory of the toolchain to the ``PATH`` environment variable.
Compiling the ULP Code
------------------------
To compile the ULP code as part of the component, the following steps must be taken:
1. The ULP code, written in assembly, must be added to one or more files with `.S` extension. These files must be placed into a separate directory inside the component directory, for instance `ulp/`.
.. note: This directory should not be added to the ``COMPONENT_SRCDIRS`` environment variable. The logic behind this is that the ESP-IDF build system will compile files found in ``COMPONENT_SRCDIRS`` based on their extensions. For ``.S`` files, ``xtensa-esp32-elf-as`` assembler is used. This is not desirable for ULP assembly files, thus the easiest way to achieve this distinction is by placing ULP assembly files into a separate directory.
2. Modify the component makefile, adding the following::
ULP_APP_NAME ?= ulp_$(COMPONENT_NAME)
ULP_S_SOURCES = $(COMPONENT_PATH)/ulp/ulp_source_file.S
ULP_EXP_DEP_OBJECTS := main.o
include $(IDF_PATH)/components/ulp/component_ulp_common.mk
Here is each line explained:
ULP_APP_NAME
Name of the generated ULP application, without an extension. This name is used for build products of the ULP application: ELF file, map file, binary file, generated header file, and generated linker export file.
ULP_S_SOURCES
List of assembly files to be passed to the ULP assembler. These must be absolute paths, i.e. start with ``$(COMPONENT_PATH)``. Consider using ``$(addprefix)`` function if more than one file needs to be listed. Paths are relative to component build directory, so prefixing them is not necessary.
ULP_EXP_DEP_OBJECTS
List of object files names within the component which include the generated header file. This list is needed to build the dependencies correctly and ensure that the generated header file is created before any of these files are compiled. See section below explaining the concept of generated header files for ULP applications.
include $(IDF_PATH)/components/ulp/component_ulp_common.mk
Includes common definitions of ULP build steps. Defines build targets for ULP object files, ELF file, binary file, etc.
3. Build the application as usual (e.g. ``idf.py build`` or ``idf.py app``)
Inside, the build system will take the following steps to build ULP program:
1. **Run each assembly file** (``foo.S``) **through the C preprocessor.** This step generates the preprocessed assembly files (``foo.ulp.pS``) in the component build directory. This step also generates dependency files (``foo.ulp.d``).
2. **Run the preprocessed assembly sources through the assembler.** This produces object (``foo.ulp.o``) and listing (``foo.ulp.lst``) files. Listing files are generated for debugging purposes and are not used at later stages of the build process.
3. **Run the linker script template through the C preprocessor.** The template is located in ``components/ulp/ld`` directory.
4. **Link the object files into an output ELF file** (``ulp_app_name.elf``). The Map file (``ulp_app_name.map``) generated at this stage may be useful for debugging purposes.
5. **Dump the contents of the ELF file into a binary** (``ulp_app_name.bin``) which can then be embedded into the application.
6. **Generate a list of global symbols** (``ulp_app_name.sym``) in the ELF file using ``esp32ulp-elf-nm``.
7. **Create an LD export script and header file** (``ulp_app_name.ld`` and ``ulp_app_name.h``) containing the symbols from ``ulp_app_name.sym``. This is done using the ``esp32ulp_mapgen.py`` utility.
8. **Add the generated binary to the list of binary files** to be embedded into the application.
Accessing the ULP Program Variables
------------------------------------
Global symbols defined in the ULP program may be used inside the main program.
For example, the ULP program may define a variable ``measurement_count`` which will define the number of the ADC measurements the program needs to make before waking up the chip from deep sleep::
.global measurement_count
measurement_count: .long 0
/* later, use measurement_count */
move r3, measurement_count
ld r3, r3, 0
The main program needs to initialize this variable before the ULP program is started. The build system makes this possible by generating ``$(ULP_APP_NAME).h`` and ``$(ULP_APP_NAME).ld`` files which define global symbols present in the ULP program. Each global symbol defined in the ULP program is included in these files and are prefixed with ``ulp_``.
The header file contains the declaration of the symbol::
extern uint32_t ulp_measurement_count;
Note that all symbols (variables, arrays, functions) are declared as ``uint32_t``. For functions and arrays, take the address of the symbol and cast it to the appropriate type.
The generated linker script file defines locations of symbols in RTC_SLOW_MEM::
PROVIDE ( ulp_measurement_count = 0x50000060 );
To access the ULP program variables from the main program, the generated header file should be included using an ``include`` statement. This will allow the ULP program variables to be accessed as regular variables::
#include "ulp_app_name.h"
// later
void init_ulp_vars() {
ulp_measurement_count = 64;
}
Note that the ULP program can only use lower 16 bits of each 32-bit word in RTC memory, because the registers are 16-bit, and there is no instruction to load from the high part of the word.
Likewise, the ULP store instruction writes register value into the lower 16 bits part of the 32-bit word. The upper 16 bits are written with a value which depends on the address of the store instruction, thus when reading variables written by the ULP, the main application needs to mask the upper 16 bits, e.g.::
printf("Last measurement value: %d\n", ulp_last_measurement & UINT16_MAX);
Starting the ULP Program
------------------------
To run a ULP program, the main application needs to load the ULP program into RTC memory using the ``ulp_load_binary`` function, and then start it using the ``ulp_run`` function.
Note that "Enable Ultra Low Power (ULP) Coprocessor" option must be enabled in menuconfig to reserve memory for the ULP. "RTC slow memory reserved for coprocessor" option must be set to a value sufficient to store ULP code and data. If the application components contain multiple ULP programs, then the size of the RTC memory must be sufficient to hold the largest one.
Each ULP program is embedded into the ESP-IDF application as a binary blob. The application can reference this blob and load it in the following way (suppose ULP_APP_NAME was defined to ``ulp_app_name``)::
extern const uint8_t bin_start[] asm("_binary_ulp_app_name_bin_start");
extern const uint8_t bin_end[] asm("_binary_ulp_app_name_bin_end");
void start_ulp_program() {
ESP_ERROR_CHECK( ulp_load_binary(
0 /* load address, set to 0 when using default linker scripts */,
bin_start,
(bin_end - bin_start) / sizeof(uint32_t)) );
}
.. doxygenfunction:: ulp_load_binary
Once the program is loaded into RTC memory, the application can start it, passing the address of the entry point to the ``ulp_run`` function::
ESP_ERROR_CHECK( ulp_run(&ulp_entry - RTC_SLOW_MEM) );
.. doxygenfunction:: ulp_run
Declaration of the entry point symbol comes from the generated header file mentioned above, ``$(ULP_APP_NAME).h``. In the assembly source of the ULP application, this symbol must be marked as ``.global``::
.global entry
entry:
/* code starts here */
ULP Program Flow
----------------
The ULP coprocessor is started by a timer. The timer is started once ``ulp_run`` is called. The timer counts the number of RTC_SLOW_CLK ticks (by default, produced by an internal 150 kHz RC oscillator). The number of ticks is set using ``SENS_ULP_CP_SLEEP_CYCx_REG`` registers (x = 0..4). When starting the ULP for the first time, ``SENS_ULP_CP_SLEEP_CYC0_REG`` will be used to set the number of timer ticks. Later the ULP program can select another ``SENS_ULP_CP_SLEEP_CYCx_REG`` register using the ``sleep`` instruction.
The application can set ULP timer period values (SENS_ULP_CP_SLEEP_CYCx_REG, x = 0..4) using the ``ulp_set_wakeup_period`` function.
.. doxygenfunction:: ulp_set_wakeup_period
Once the timer counts the number of ticks set in the selected ``SENS_ULP_CP_SLEEP_CYCx_REG`` register, the ULP coprocessor will power up and start running the program from the entry point set in the call to ``ulp_run``.
The program runs until it encounters a ``halt`` instruction or an illegal instruction. Once the program halts, ULP coprocessor will power down, and the timer will be started again.
To disable the timer (effectively preventing the ULP program from running again), please clear the ``RTC_CNTL_ULP_CP_SLP_TIMER_EN`` bit in the ``RTC_CNTL_STATE0_REG`` register. This can be done both from the ULP code and from the main program.
.. _binutils-esp32ulp toolchain: https://github.com/espressif/binutils-esp32ulp

View File

@ -20,10 +20,6 @@ The ULP coprocessor code is written in assembly and compiled using the `binutils
If you have already set up ESP-IDF with CMake build system according to the :doc:`Getting Started Guide <../../get-started/index>`, then the ULP toolchain will already be installed.
.. only:: esp32
If you are using ESP-IDF with the legacy GNU Make based build system, refer to the instructions on this page: :doc:`ulp-legacy`.
Compiling the ULP Code
-----------------------

View File

@ -1,218 +0,0 @@
Unit Testing (Legacy GNU Make)
==============================
:link_to_translation:`zh_CN:[中文]`
.. include:: ../gnu-make-legacy.rst
ESP-IDF comes with a unit test application that is based on the Unity - unit test framework. Unit tests are integrated in the ESP-IDF repository and are placed in the ``test`` subdirectories of each component respectively.
Normal Test Cases
------------------
Unit tests are located in the ``test`` subdirectory of a component.
Tests are added in C files, a single C file can include multiple test cases.
Test files start with the word "test".
Each test file should include the ``unity.h`` header and the header for the C module to be tested.
Tests are added in a function in the C file as follows:
.. code-block:: c
TEST_CASE("test name", "[module name]"
{
// Add test here
}
The first argument is a descriptive name for the test, the second argument is an identifier in square brackets.
Identifiers are used to group related test, or tests with specific properties.
.. note::
There is no need to add a main function with ``UNITY_BEGIN()`` and ``UNITY_END()`` in each test case. ``unity_platform.c`` will run ``UNITY_BEGIN()`` autonomously, and run the test cases, then call ``UNITY_END()``.
Each ``test`` subdirectory needs to include a ``component.mk`` file with the following line of code::
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
See http://www.throwtheswitch.org/unity for more information about writing tests in Unity.
Multi-device Test Cases
------------------------
The normal test cases will be executed on one DUT (Device Under Test). However, components that require some form of communication (e.g., GPIO, SPI) require another device to communicate with, thus cannot be tested normal test cases.
Multi-device test cases involve writing multiple test functions, and running them on multiple DUTs.
The following is an example of a Multi-device test case:
.. code-block:: c
void gpio_master_test()
{
gpio_config_t slave_config = {
.pin_bit_mask = 1 << MASTER_GPIO_PIN,
.mode = GPIO_MODE_INPUT,
};
gpio_config(&slave_config);
unity_wait_for_signal("output high level");
TEST_ASSERT(gpio_get_level(MASTER_GPIO_PIN) == 1);
}
void gpio_slave_test()
{
gpio_config_t master_config = {
.pin_bit_mask = 1 << SLAVE_GPIO_PIN,
.mode = GPIO_MODE_OUTPUT,
};
gpio_config(&master_config);
gpio_set_level(SLAVE_GPIO_PIN, 1);
unity_send_signal("output high level");
}
TEST_CASE_MULTIPLE_DEVICES("gpio multiple devices test example", "[driver]", gpio_master_test, gpio_slave_test);
The macro ``TEST_CASE_MULTIPLE_DEVICES`` is used to declare a multi-device test case.
The first argument is test case name, the second argument is test case description.
From the third argument, up to 5 test functions can be defined, each function will be the entry point of tests running on each DUT.
Running test cases from different DUTs could require synchronizing between DUTs. We provide ``unity_wait_for_signal`` and ``unity_send_signal`` to support synchronizing with UART.
As the scenario in the above example, the slave should get GPIO level after master set level. DUT UART console will prompt and requires user interaction:
DUT1 (master) console::
Waiting for signal: [output high level]!
Please press "Enter" key once any board send this signal.
DUT2 (slave) console::
Send signal: [output high level]!
Once the signal is sent from DUT2, you need to press "Enter" on DUT1, then DUT1 unblocks from ``unity_wait_for_signal`` and starts to change GPIO level.
Signals can also be used to pass parameters between multiple devices. For example, DUT1 want to know the MAC address of DUT2, so it can connect to DUT2.
In this case, ``unity_wait_for_signal_param`` and ``unity_send_signal_param`` can be used:
DUT1 console::
Waiting for signal: [dut2 mac address]!
Please input parameter value from any board send this signal and press "Enter" key.
DUT2 console::
Send signal: [dut2 mac address][10:20:30:40:50:60]!
Once the signal is sent from DUT2, you need to input ``10:20:30:40:50:60`` on DUT1 and press "Enter". Then DUT1 will get the MAC address string of DUT2 and unblock from ``unity_wait_for_signal_param``, then start to connect to DUT2.
Multi-stage Test Cases
-----------------------
The normal test cases are expected to finish without reset (or only need to check if reset happens). Sometimes we expect to run some specific tests after certain kinds of reset.
For example, we expect to test if reset reason is correct after a wakeup from deep sleep. We need to create a deep-sleep reset first and then check the reset reason.
To support this, we can define multi-stage test cases, to group a set of test functions::
static void trigger_deepsleep(void)
{
esp_sleep_enable_timer_wakeup(2000);
esp_deep_sleep_start();
}
void check_deepsleep_reset_reason()
{
soc_reset_reason_t reason = esp_rom_get_reset_reason(0);
TEST_ASSERT(reason == RESET_REASON_CORE_DEEP_SLEEP);
}
TEST_CASE_MULTIPLE_STAGES("reset reason check for deepsleep", "[esp32]", trigger_deepsleep, check_deepsleep_reset_reason);
Multi-stage test cases present a group of test functions to users. It need user interactions (select cases and select different stages) to run the case.
Building Unit Test App
----------------------
Follow the setup instructions in the top-level esp-idf README.
Make sure that ``IDF_PATH`` environment variable is set to point to the path of esp-idf top-level directory.
Change into ``tools/unit-test-app`` directory to configure and build it:
* ``make menuconfig`` - configure unit test app.
* ``make TESTS_ALL=1`` - build unit test app with tests for each component having tests in the ``test`` subdirectory.
* ``make TEST_COMPONENTS='xxx'`` - build unit test app with tests for specific components.
* ``make TESTS_ALL=1 TEST_EXCLUDE_COMPONENTS='xxx'`` - build unit test app with all unit tests, except for unit tests of some components. (For instance: ``make TESTS_ALL=1 TEST_EXCLUDE_COMPONENTS='ulp mbedtls'`` - build all unit tests exludes ``ulp`` and ``mbedtls`` components).
When the build finishes, it will print instructions for flashing the chip. You can simply run ``make flash`` to flash all build output.
You can also run ``make flash TESTS_ALL=1`` or ``make TEST_COMPONENTS='xxx'`` to build and flash. Everything needed will be rebuilt automatically before flashing.
Use menuconfig to set the serial port for flashing.
Running Unit Tests
------------------
After flashing reset the ESP32 and it will boot the unit test app.
When unit test app is idle, press "Enter" will make it print test menu with all available tests::
Here's the test menu, pick your combo:
(1) "esp_ota_begin() verifies arguments" [ota]
(2) "esp_ota_get_next_update_partition logic" [ota]
(3) "Verify bootloader image in flash" [bootloader_support]
(4) "Verify unit test app image" [bootloader_support]
(5) "can use new and delete" [cxx]
(6) "can call virtual functions" [cxx]
(7) "can use static initializers for non-POD types" [cxx]
(8) "can use std::vector" [cxx]
(9) "static initialization guards work as expected" [cxx]
(10) "global initializers run in the correct order" [cxx]
(11) "before scheduler has started, static initializers work correctly" [cxx]
(12) "adc2 work with wifi" [adc]
(13) "gpio master/slave test example" [ignore][misc][test_env=UT_T2_1][multi_device]
(1) "gpio_master_test"
(2) "gpio_slave_test"
(14) "SPI Master clockdiv calculation routines" [spi]
(15) "SPI Master test" [spi][ignore]
(16) "SPI Master test, interaction of multiple devs" [spi][ignore]
(17) "SPI Master no response when switch from host1 (SPI2) to host2 (SPI3)" [spi]
(18) "SPI Master DMA test, TX and RX in different regions" [spi]
(19) "SPI Master DMA test: length, start, not aligned" [spi]
(20) "reset reason check for deepsleep" [esp32][test_env=UT_T2_1][multi_stage]
(1) "trigger_deepsleep"
(2) "check_deepsleep_reset_reason"
The normal case will print the case name and description. Master-slave cases will also print the sub-menu (the registered test function names).
Test cases can be run by inputting one of the following:
- Test case name in quotation marks (for example, ``"esp_ota_begin() verifies arguments"``) to run a single test case.
- Test case index (for example, ``1``) to run a single test case.
- Module name in square brackets (for example, ``[cxx]``) to run all test cases for a specific module.
- An asterisk (``*``) to run all test cases
``[multi_device]`` and ``[multi_stage]`` tags tell the test runner whether a test case is a multi-device or multi-stage test case.
These tags are automatically added by ```TEST_CASE_MULTIPLE_STAGES`` and ``TEST_CASE_MULTIPLE_DEVICES`` macros.
After you select a multi-device test case, it will print sub menu::
Running gpio master/slave test example...
gpio master/slave test example
(1) "gpio_master_test"
(2) "gpio_slave_test"
You need to input a number to select the test running on the DUT.
Similar to multi-device test cases, multi-stage test cases will also print sub-menu::
Running reset reason check for deepsleep...
reset reason check for deepsleep
(1) "trigger_deepsleep"
(2) "check_deepsleep_reset_reason"
For the first time you execute this case, please input ``1`` to run the first stage (trigger deep-sleep).
After DUT is rebooted and test cases are available to run, select this case again and input ``2`` to run the second stage.
The case will only pass if the last stage passes and all previous stages trigger reset.

View File

@ -20,8 +20,6 @@ Application developers can open a terminal-based project configuration menu with
After being updated, this configuration is saved inside ``sdkconfig`` file in the project root directory. Based on ``sdkconfig``, application build targets will generate ``sdkconfig.h`` file in the build directory, and will make sdkconfig options available to the project build system and source files.
(For the legacy GNU Make build system, the project configuration menu is opened with ``make menuconfig``.)
Using sdkconfig.defaults
========================
@ -89,15 +87,6 @@ By convention, all option names are upper case with underscores. When Kconfig ge
.. include-build-file:: inc/kconfig.inc
Customisations
==============
Because IDF builds by default with :ref:`warn-undefined-variables`, when the Kconfig tool generates Makefiles (the ``auto.conf`` file) its behaviour has been customised. In normal Kconfig, a variable which is set to "no" is undefined. In IDF's version of Kconfig, this variable is defined in the Makefile but has an empty value.
(Note that ``ifdef`` and ``ifndef`` can still be used in Makefiles, because they test if a variable is defined *and has a non-empty value*.)
When generating header files for C & C++, the behaviour is not customised - so ``#ifdef`` can be used to test if a boolean config item is set or not.
.. _Kconfig: https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt
.. _kconfiglib: https://github.com/ulfalizer/Kconfiglib
.. _kconfiglib extentions: https://pypi.org/project/kconfiglib/#kconfig-extensions

View File

@ -22,7 +22,7 @@ In addition it is possible to specify a path to a certificate file or a director
Configuration
-------------
Most configuration is done through menuconfig. Make and CMake will generate the bundle according to the configuration and embed it.
Most configuration is done through menuconfig. CMake will generate the bundle according to the configuration and embed it.
* :ref:`CONFIG_MBEDTLS_CERTIFICATE_BUNDLE`: automatically build and attach the bundle.
* :ref:`CONFIG_MBEDTLS_DEFAULT_CERTIFICATE_BUNDLE`: decide which certificates to include from the complete root list.

View File

@ -79,11 +79,11 @@ There are two ways to use wolfssl in your project
git clone https://github.com/espressif/esp-wolfssl.git
* Include esp-wolfssl in ESP-IDF with setting EXTRA_COMPONENT_DIRS in CMakeLists.txt/Makefile of your project as done in `wolfssl/examples <https://github.com/espressif/esp-wolfssl/tree/master/examples>`_. For reference see Optional Project variables in :doc:`build-system.</api-guides/build-system>`
* Include esp-wolfssl in ESP-IDF with setting EXTRA_COMPONENT_DIRS in CMakeLists.txt of your project as done in `wolfssl/examples <https://github.com/espressif/esp-wolfssl/tree/master/examples>`_. For reference see Optional Project variables in :doc:`build-system.</api-guides/build-system>`
After above steps, you will have option to choose wolfssl as underlying SSL/TLS library in configuration menu of your project as follows::
idf.py/make menuconfig -> ESP-TLS -> choose SSL/TLS Library -> mbedtls/wolfssl
idf.py menuconfig -> ESP-TLS -> choose SSL/TLS Library -> mbedtls/wolfssl
Comparison between mbedtls and wolfssl
--------------------------------------

View File

@ -42,49 +42,21 @@ These optional arguments correspond to a possible SPIFFS build configuration. To
When the image is created, it can be flashed using ``esptool.py`` or ``parttool.py``.
Aside from invoking the ``spiffsgen.py`` standalone by manually running it from the command line or a script, it is also possible to invoke ``spiffsgen.py`` directly from the build system by calling ``spiffs_create_partition_image``.
Make::
SPIFFS_IMAGE_FLASH_IN_PROJECT := ...
SPIFFS_IMAGE_DEPENDS := ...
$(eval $(call spiffs_create_partition_image,<partition>,<base_dir>))
CMake::
Aside from invoking the ``spiffsgen.py`` standalone by manually running it from the command line or a script, it is also possible to invoke ``spiffsgen.py`` directly from the build system by calling ``spiffs_create_partition_image``::
spiffs_create_partition_image(<partition> <base_dir> [FLASH_IN_PROJECT] [DEPENDS dep dep dep...])
This is more convenient as the build configuration is automatically passed to the tool, ensuring that the generated image is valid for that build. An example of this is while the *image_size* is required for the standalone invocation, only the *partition* name is required when using ``spiffs_create_partition_image`` -- the image size is automatically obtained from the project's partition table.
Due to the differences in structure between Make and CMake, it is important to note that:
``spiffs_create_partition_image`` must be called from one of the component CMakeLists.txt files.
- for Make ``spiffs_create_partition_image`` must be called from the project Makefile
- for CMake ``spiffs_create_partition_image`` must be called from one of the component CMakeLists.txt files
Optionally, user can opt to have the image automatically flashed together with the app binaries, partition tables, etc. on ``idf.py flash`` or ``make flash`` by specifying ``FLASH_IN_PROJECT``. For example,
in Make::
SPIFFS_IMAGE_FLASH_IN_PROJECT := 1
$(eval $(call spiffs_create_partition_image,<partition>,<base_dir>))
in CMake::
Optionally, users can opt to have the image automatically flashed together with the app binaries, partition tables, etc. on ``idf.py flash`` by specifying ``FLASH_IN_PROJECT``. For example::
spiffs_create_partition_image(my_spiffs_partition my_folder FLASH_IN_PROJECT)
If FLASH_IN_PROJECT/SPIFFS_IMAGE_FLASH_IN_PROJECT is not specified, the image will still be generated, but you will have to flash it manually using ``esptool.py``, ``parttool.py``, or a custom build system target.
There are cases where the contents of the base directory itself is generated at build time. Users can use DEPENDS/SPIFFS_IMAGE_DEPENDS to specify targets that should be executed before generating the image.
in Make::
dep:
...
SPIFFS_IMAGE_DEPENDS := dep
$(eval $(call spiffs_create_partition_image,<partition>,<base_dir>))
in CMake::
There are cases where the contents of the base directory itself is generated at build time. Users can use DEPENDS/SPIFFS_IMAGE_DEPENDS to specify targets that should be executed before generating the image::
add_custom_target(dep COMMAND ...)

View File

@ -101,14 +101,9 @@ The following pattern can be used to add a custom structure to your image:
Offset for custom structure is sizeof(:cpp:type:`esp_image_header_t`) + sizeof(:cpp:type:`esp_image_segment_header_t`) + sizeof(:cpp:type:`esp_app_desc_t`).
To guarantee that the custom structure is located in the image even if it is not used, you need to add:
* For Make: add ``COMPONENT_ADD_LDFLAGS += -u custom_app_desc`` into ``component.mk``
* For Cmake: add ``target_link_libraries(${COMPONENT_TARGET} "-u custom_app_desc")`` into ``CMakeLists.txt``
To guarantee that the custom structure is located in the image even if it is not used, you need to add ``target_link_libraries(${COMPONENT_TARGET} "-u custom_app_desc")`` into ``CMakeLists.txt``.
API Reference
-------------
.. include-build-file:: inc/esp_app_format.inc

View File

@ -196,8 +196,6 @@ To set version in your project manually you need to set ``PROJECT_VER`` variable
* In application CMakeLists.txt put ``set(PROJECT_VER "0.1.0.1")`` before including ``project.cmake``.
(For legacy GNU Make build system: in application Makefile put ``PROJECT_VER = "0.1.0.1"`` before including ``project.mk``.)
If :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` option is set, the value of :ref:`CONFIG_APP_PROJECT_VER` will be used. Otherwise if ``PROJECT_VER`` variable is not set in the project then it will be retrieved from either ``$(PROJECT_PATH)/version.txt`` file (if present) else using git command ``git describe``. If neither is available then ``PROJECT_VER`` will be set to "1". Application can make use of this by calling :cpp:func:`esp_ota_get_app_description` or :cpp:func:`esp_ota_get_partition_description` functions.
API Reference

View File

@ -23,7 +23,7 @@ Checklist
Checklist before submitting a new example:
* Example project name (in ``Makefile`` and ``README.md``) uses the word "example". Use "example" instead of "demo", "test" or similar words.
* Example project name (in ``README.md``) uses the word "example". Use "example" instead of "demo", "test" or similar words.
* Example does one distinct thing. If the example does more than one thing at a time, split it into two or more examples.
* Example has a ``README.md`` file which is similar to the :idf_file:`template example README <docs/TEMPLATE_EXAMPLE_README.md>`.
* Functions and variables in the example are named according to :ref:`naming section of the style guide <style-guide-naming>`. (For non-static names which are only specific to the example's source files, you can use ``example`` or something similar as a prefix.)

View File

@ -1,67 +0,0 @@
Add IDF_PATH to User Profile (Legacy GNU Make)
==============================================
:link_to_translation:`zh_CN:[中文]`
.. include:: ../gnu-make-legacy.rst
To preserve setting of ``IDF_PATH`` environment variable between system restarts, add it to the user profile, following instructions below.
.. _add-idf_path-to-profile-windows-legacy:
Windows
-------
The user profile scripts are contained in ``C:/msys32/etc/profile.d/`` directory. They are executed every time you open an MSYS2 window.
#. Create a new script file in ``C:/msys32/etc/profile.d/`` directory. Name it ``export_idf_path.sh``.
#. 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``
#. Add the ``export`` command to the script file, e.g.::
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-legacy`, while installing s/w for ESP32 development, then go back to section :ref:`get-started-start-project-legacy`.
.. _add-idf_path-to-profile-linux-macos-legacy:
Linux and MacOS
---------------
Set up ``IDF_PATH`` by adding the following line to ``~/.profile`` file::
export IDF_PATH=~/esp/esp-idf
Log off and log in back to make this change effective.
.. note::
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::
printenv IDF_PATH
The path previously entered in ``~/.profile`` file (or set manually) should be printed out.
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
If you got here from section :ref:`get-started-setup-path-legacy`, while installing s/w for ESP32 development, then go back to section :ref:`get-started-start-project-legacy`.

View File

@ -1,111 +0,0 @@
**************************************************
Build and Flash with Eclipse IDE (Legacy GNU Make)
**************************************************
:link_to_translation:`zh_CN:[中文]`
.. include:: ../gnu-make-legacy.rst
.. _eclipse-install-steps-legacy:
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.)
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. Windows users can copy the ``IDF_PATH`` from windows explorer.
* 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. Windows users will need to prepend ``C:\msys32\mingw32\bin;C:\msys32\opt\xtensa-esp32-elf\bin;C:\msys32\usr\bin`` to ``PATH`` environment variable (If you installed msys32 to a different directory then youll need to change these paths to match).
* 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.
**ADDITIONAL NOTE**: If either the IDF_PATH directory or the project directory is located outside ``C:\msys32\home`` directory, you will have to give custom build command in C/C++ Build properties as: ``python ${IDF_PATH}/tools/windows/eclipse_make.py`` (Please note that the build time may get significantly increased by this method.)
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". Change "Command to get compiler specs" to ``xtensa-esp32-elf-gcc ${FLAGS} -std=c++11 -E -P -v -dD "${INPUTS}"``.
* In the list of providers, click "CDT GCC Build Output Parser" and change the "Compiler command pattern" to ``xtensa-esp32-elf-(gcc|g\+\+|c\+\+|cc|cpp|clang)``
Navigate to "C/C++ General" -> "Indexer" property page:
* Check "Enable project specific settings" to enable the rest of the settings on this page.
* Uncheck "Allow heuristic resolution of includes". When this option is enabled Eclipse sometimes fails to find correct header directories.
Navigate to "C/C++ Build" -> "Behavior" property page:
* Check "Enable parallel build" to enable multiple build jobs in parallel.
.. _eclipse-build-project-legacy:
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.
.. _eclipse.org: https://www.eclipse.org/

View File

@ -1,154 +0,0 @@
Establish Serial Connection with ESP32 (Legacy GNU Make)
========================================================
:link_to_translation:`zh_CN:[中文]`
.. include:: ../gnu-make-legacy.rst
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 and other boards produced by Espressif:
.. csv-table::
:header: Development Board, USB Driver, Remarks
:widths: 40, 20, 40
ESP32-DevKitC, `CP210x`_
`ESP32-LyraT <https://www.espressif.com/en/products/hardware/esp32-lyrat>`_, `CP210x`_
`ESP32-LyraTD-MSC <https://www.espressif.com/en/products/hardware/esp32-lyratd-msc>`_, `CP210x`_
ESP32-PICO-KIT, `CP210x`_
ESP-WROVER-KIT, `FTDI`_
ESP32 Demo Board, `FTDI`_
`ESP-Prog`_, `FTDI`_, Programmer board (w/o ESP32)
`ESP32-MeshKit-Sense <https://github.com/espressif/esp-dev-kits/blob/master/esp32-meshkit-sensor/docs/ESP32-MeshKit-Sense_guide_en.md>`_, n/a, Use with `ESP-Prog`_
`ESP32-Sense-Kit <https://github.com/espressif/esp-dev-kits/blob/master/esp32-sense-kit/docs/esp32_sense_kit_guide_en.md>`_, n/a, Use with `ESP-Prog`_
.. _CP210x: https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers
.. _FTDI: https://www.ftdichip.com/Drivers/VCP.htm
.. _ESP-Prog: https://github.com/espressif/esp-dev-kits/blob/master/esp-prog/docs/ESP-Prog_guide_en.md
* CP210x: `CP210x USB to UART Bridge VCP Drivers <https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers>`_
* FTDI: `FTDI Virtual COM Port Drivers <https://www.ftdichip.com/Drivers/VCP.htm>`_
The drivers above are primarily for reference. Under normal circumstances, the drivers should be bundled with and operating system and automatically installed upon connecting one of the listed boards 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.*
.. _linux-dialout-group-legacy:
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
on Arch Linux this is done by adding the user to ``uucp`` group with the following command::
sudo usermod -a -G uucp $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 <http://www.putty.org/>`_ 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-legacy` when installing s/w for ESP32 development, then go back to section :ref:`get-started-configure-legacy`.
.. _esptool documentation: https://github.com/espressif/esptool/wiki/ESP32-Boot-Mode-Selection#automatic-bootloader

View File

@ -1,464 +0,0 @@
*****************************
Get Started (Legacy GNU Make)
*****************************
:link_to_translation:`zh_CN:[中文]`
.. include:: ../gnu-make-legacy.rst
This document is intended to help you set up the software development environment for the hardware based on Espressif ESP32.
After that, a simple example will show you how to use ESP-IDF (Espressif IoT Development Framework) for menu configuration, then for building and flashing firmware onto an ESP32 board.
.. include-build-file:: inc/version-note.inc
Introduction
============
ESP32 is a system on a chip that integrates the following features:
* Wi-Fi (2.4 GHz band)
* Bluetooth
* Dual high performance cores
* Ultra Low Power co-processor
* Several peripherals
Powered by 40 nm technology, ESP32 provides a robust, highly integrated platform, which helps meet the continuous demands for efficient power usage, compact design, security, high performance, and reliability.
Espressif provides basic hardware and software resources to help application developers realize their ideas using the ESP32 series hardware. The software development framework by Espressif is intended for development of Internet-of-Things (IoT) applications with Wi-Fi, Bluetooth, power management and several other system features.
What You Need
=============
Hardware:
* An **ESP32** board
* **USB cable** - USB A / micro USB B
* **Computer** running Windows, Linux, or macOS
Software:
* **Toolchain** to build the **Application** for ESP32
* **ESP-IDF** that essentially contains API (software libraries and source code) for ESP32 and scripts to operate the **Toolchain**
* **Text editor** to write programs (**Projects**) in C, e.g., `Eclipse <https://www.eclipse.org/>`_
Development Board Overviews
===========================
If you have one of ESP32 development boards listed below, you can click on the link to learn more about its hardware.
.. toctree::
:maxdepth: 1
ESP32-DevKitC <../hw-reference/esp32/get-started-devkitc>
ESP-WROVER-KIT <../hw-reference/esp32/get-started-wrover-kit>
ESP32-PICO-KIT <../hw-reference/esp32/get-started-pico-kit>
ESP32-Ethernet-Kit <../hw-reference/esp32/get-started-ethernet-kit>
ESP32-DevKit-S(-R) <../hw-reference/esp32/user-guide-devkits-r-v1.1>
.. _get-started-step-by-step-legacy:
Installation Step by Step
=========================
This is a detailed roadmap to walk you through the installation process.
Setting up Development Environment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* :ref:`get-started-setup-toolchain-legacy` for :doc:`Windows <windows-setup>`, :doc:`Linux <linux-setup>` or :doc:`macOS <macos-setup>`
* :ref:`get-started-get-esp-idf-legacy`
* :ref:`get-started-setup-path-legacy`
* :ref:`get-started-get-packages-legacy`
Creating Your First Project
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* :ref:`get-started-start-project-legacy`
* :ref:`get-started-connect-legacy`
* :ref:`get-started-configure-legacy`
* :ref:`get-started-build-and-flash-legacy`
* :ref:`get-started-monitor-legacy`
.. _get-started-setup-toolchain-legacy:
Step 1. Set up the Toolchain
============================
The toolchain is a set of programs for compiling code and building applications.
The quickest way to start development with ESP32 is by installing a prebuilt toolchain. Pick up your OS below and follow the provided instructions.
.. toctree::
:hidden:
Windows <windows-setup>
Linux <linux-setup>
macOS <macos-setup>
+-----------------+---------------+---------------+
| |windows-logo| | |linux-logo| | |macos-logo| |
+-----------------+---------------+---------------+
| Windows_ | Linux_ | `macOS`_ |
+-----------------+---------------+---------------+
.. |windows-logo| image:: ../../_static/windows-logo.png
:target: ../get-started-legacy/windows-setup.html
.. |linux-logo| image:: ../../_static/linux-logo.png
:target: ../get-started-legacy/linux-setup.html
.. |macos-logo| image:: ../../_static/macos-logo.png
:target: ../get-started-legacy/macos-setup.html
.. _Windows: ../get-started-legacy/windows-setup.html
.. _Linux: ../get-started-legacy/linux-setup.html
.. _macOS: ../get-started-legacy/macos-setup.html
.. note::
This guide uses the directory ``~/esp`` on Linux and macOS or ``%userprofile%\esp`` on Windows as an installation folder for ESP-IDF. You can use any directory, but you will need to adjust paths for the commands respectively. Keep in mind that ESP-IDF does not support spaces in paths.
Depending on your experience and preferences, you may want to customize your environment instead of using a prebuilt toolchain. To set up the system your own way go to Section :ref:`get-started-customized-setup-legacy`.
.. _get-started-get-esp-idf-legacy:
Step 2. Get ESP-IDF
===================
Besides the toolchain, you also need ESP32-specific API (software libraries and source code). They are provided by Espressif in `ESP-IDF repository <https://github.com/espressif/esp-idf>`_.
To get a local copy of ESP-IDF, navigate to your installation directory and clone the repository with ``git clone``.
Open Terminal, and run the following commands:
.. include-build-file:: inc/git-clone-bash.inc
ESP-IDF will be downloaded into ``~/esp/esp-idf``.
Consult :doc:`/versions` for information about which ESP-IDF version to use in a given situation.
.. include-build-file:: inc/git-clone-notes.inc
.. 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
.. _get-started-setup-path-legacy:
Step 3. Set Environment Variables
=================================
The toolchain uses the environment variable ``IDF_PATH`` to access the ESP-IDF directory. This variable should be set up on your computer, otherwise projects will not build.
These variables can be set temporarily (per session) or permanently. Please follow the instructions specific to :ref:`Windows <add-idf_path-to-profile-windows-legacy>` , :ref:`Linux and macOS <add-idf_path-to-profile-linux-macos-legacy>` in Section :doc:`add-idf_path-to-profile`.
.. _get-started-get-packages-legacy:
Step 4. Install the Required Python Packages
============================================
The python packages required by ESP-IDF are located in ``IDF_PATH/requirements.txt``. You can install them by running::
python -m pip install --user -r $IDF_PATH/requirements.txt
.. note::
Please check the version of the Python interpreter that you will be using with ESP-IDF. For this, run
the command ``python --version`` and depending on the result, you might want to use ``python3``, ``python3.7``
or similar instead of just ``python``, e.g.::
python3 -m pip install --user -r $IDF_PATH/requirements.txt
.. _get-started-start-project-legacy:
Step 5. Start a Project
=======================
Now you are ready to prepare your application for ESP32. You can start with :example:`get-started/hello_world` project from :idf:`examples` directory in IDF.
Copy :example:`get-started/hello_world` to the ``~/esp`` directory:
Linux and macOS
~~~~~~~~~~~~~~~
.. code-block:: bash
cd ~/esp
cp -r $IDF_PATH/examples/get-started/hello_world .
Windows
~~~~~~~
.. code-block:: batch
cd %userprofile%\esp
xcopy /e /i %IDF_PATH%\examples\get-started\hello_world hello_world
There is a range of example projects in the :idf:`examples` directory in ESP-IDF. You can copy any project in the same way as presented above and run it.
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 paths to either esp-idf or to projects.
.. _get-started-connect-legacy:
Step 6. Connect Your Device
===========================
Now connect your ESP32 board to the computer and check under what serial port the board is visible.
Serial ports have the following patterns in their names:
- **Windows**: names like ``COM1``
- **Linux**: starting with ``/dev/tty``
- **macOS**: starting with ``/dev/cu.``
If you are not sure how to check the serial port name, please refer to :doc:`establish-serial-connection` for full details.
.. note::
Keep the port name handy as you will need it in the next steps.
.. _get-started-configure-legacy:
Step 7. Configure
=================
Navigate to your ``hello_world`` directory from :ref:`get-started-start-project-legacy` and run the project configuration utility ``menuconfig``.
Linux and macOS
~~~~~~~~~~~~~~~
.. code-block:: bash
cd ~/esp/hello_world
make menuconfig
Windows
~~~~~~~
.. code-block:: batch
cd %userprofile%\esp\hello_world
make menuconfig
If the previous steps have been done correctly, the following menu appears:
.. figure:: ../../_static/project-configuration.png
:align: center
:alt: Project configuration - Home window
:figclass: align-center
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 ``menuconfig`` by selecting ``< Exit >``.
To navigate and use ``menuconfig``, press the following keys:
* Arrow keys for navigation
* ``Enter`` to go into a submenu
* ``Esc`` to go up one level or exit
* ``?`` to see a help screen. Enter key exits the help screen
* ``Space``, or ``Y`` and ``N`` keys to enable (Yes) and disable (No) configuration items with checkboxes "``[*]``"
* ``?`` while highlighting a configuration item to display help about that item
* ``/`` to find configuration items
.. attention::
If you use ESP32-DevKitC board with the **ESP32-SOLO-1** module, enable single core mode (:ref:`CONFIG_FREERTOS_UNICORE`) in menuconfig before flashing examples.
.. _get-started-build-and-flash-legacy:
Step 8. Build and Flash
=======================
Build and flash the project by running::
make flash
This command will compile the application and all ESP-IDF components, then it will generate the bootloader, partition table, and application binaries. After that, these binaries will be flashed onto your ESP32 board.
Encountered Issues While Flashing?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you run the given command and see errors such as "Failed to connect", there might be several reasons for this. One of the reasons might be issues encountered by ``esptool.py``, the utility that is called by the build system to reset the chip, interact with the ROM bootloader, and flash firmware. One simple solution to try is manual reset described below, and if it does not help you can find more details about possible issues in `Troubleshooting <https://github.com/espressif/esptool#bootloader-wont-respond>`_.
``esptool.py`` resets {IDF_TARGET_NAME} automatically by asserting DTR and RTS control lines of the USB to serial converter chip, i.e., FTDI or CP210x (for more information, see :doc:`establish-serial-connection`). The DTR and RTS control lines are in turn connected to ``GPIO0`` and ``CHIP_PU`` (EN) pins of {IDF_TARGET_NAME}, thus changes in the voltage levels of DTR and RTS will boot {IDF_TARGET_NAME} into Firmware Download mode. As an example, check the `schematic <https://dl.espressif.com/dl/schematics/esp32_devkitc_v4-sch-20180607a.pdf>`_ for ESP32-DevKitC development board.
In general, you should have no problems with the official esp-idf development boards. However, ``esptool.py`` is not able to reset your hardware automatically in the following cases:
- Your hardware does not have the DTR and RTS lines connected to ``GPIO0`` and ``CHIP_PU``
- The DTR and RTS lines are configured differently
- There are no such serial control lines at all
Depending on the kind of hardware you have, it may also be possible to manually put your {IDF_TARGET_NAME} board into Firmware Download mode (reset).
- For development boards produced by Espressif, this information can be found in the respective getting started guides or user guides. For example, to manually reset an esp-idf development board, hold down the **Boot** button (``GPIO0``) and press the **EN** button (``CHIP_PU``).
- For other types of hardware, try pulling ``GPIO0`` down.
Normal Operation
~~~~~~~~~~~~~~~~
If there are no issues by the end of the flash process, you will see the output log similar to the one given below. Then the board will reboot and start up the "hello_world" application.
.. code-block:: bash
esptool.py v3.0-dev
Flashing binaries to serial port /dev/ttyUSB0 (app at offset 0x10000)...
esptool.py v3.0-dev
Serial port /dev/cu.SLAB_USBtoUART
Connecting........____
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, Coding Scheme None
Crystal is 40MHz
MAC: 30:ae:a4:15:21:b4
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0220
Compressed 26704 bytes to 15930...
Wrote 26704 bytes (15930 compressed) at 0x00001000 in 1.4 seconds (effective 151.9 kbit/s)...
Hash of data verified.
Compressed 147984 bytes to 77738...
Wrote 147984 bytes (77738 compressed) at 0x00010000 in 6.9 seconds (effective 172.7 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 103...
Wrote 3072 bytes (103 compressed) at 0x00008000 in 0.0 seconds (effective 1607.9 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
If you'd like to use the Eclipse IDE instead of running ``make``, check out the :doc:`Eclipse guide <eclipse-setup>`.
.. _get-started-monitor-legacy:
Step 9. Monitor
===============
To check if "hello_world" is indeed running, type ``make monitor``.
This command launches the :doc:`IDF Monitor <../api-guides/tools/idf-monitor>` application::
$ 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
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
ets Jun 8 2016 00:22:57
...
After startup and diagnostic logs scroll up, you should see "Hello world!" printed out by the application.
.. code-block:: bash
...
Hello world!
This is esp32 chip with 2 CPU cores, WiFi/BT/BLE, silicon revision 1, 4MB external flash
Restarting in 10 seconds...
Restarting in 9 seconds...
Restarting in 8 seconds...
Restarting in 7 seconds...
To exit IDF monitor use the shortcut ``Ctrl+]``.
If IDF monitor fails shortly after the upload, or if instead of the messages above you see a random garbage similar to what is given below, your board is likely using a 26MHz crystal. Most development board designs use 40MHz, so ESP-IDF uses this frequency as a default value.
.. figure:: ../../_static/get-started-garbled-output.png
:align: center
:alt: Garbled output
:figclass: align-center
If you have such a problem, do the following:
1. Exit the monitor.
2. Go back to :ref:`menuconfig <get-started-configure-legacy>`.
3. Go to Component config --> ESP32-specific --> Main XTAL frequency, then change :ref:`CONFIG_ESP32_XTAL_FREQ_SEL` to 26MHz.
4. After that, :ref:`build and flash <get-started-build-and-flash-legacy>` the application again.
.. note::
You can combine building, flashing and monitoring into one step by running::
make flash monitor
See also :doc:`IDF Monitor <../api-guides/tools/idf-monitor>` for handy shortcuts and more details on using IDF monitor.
**That's all that you need to get started with ESP32!**
Now you are ready to try some other :idf:`examples`, or go straight to developing your own applications.
Environment Variables
=====================
Some environment variables can be specified whilst calling ``make`` allowing users to **override arguments without the need to reconfigure them using** ``make menuconfig``.
+-----------------+--------------------------------------------------------------+
| Variables | Description & Usage |
+=================+==============================================================+
| ``ESPPORT`` | Overrides the serial port used in ``flash`` and ``monitor``. |
| | |
| | Examples: ``make flash ESPPORT=/dev/ttyUSB1``, |
| | ``make monitor ESPPORT=COM1`` |
+-----------------+--------------------------------------------------------------+
| ``ESPBAUD`` | Overrides the serial baud rate when flashing the ESP32. |
| | |
| | Example: ``make flash ESPBAUD=9600`` |
+-----------------+--------------------------------------------------------------+
| ``MONITORBAUD`` | Overrides the serial baud rate used when monitoring. |
| | |
| | Example: ``make monitor MONITORBAUD=9600`` |
+-----------------+--------------------------------------------------------------+
.. note::
You can export environment variables (e.g. ``export ESPPORT=/dev/ttyUSB1``).
All subsequent calls of ``make`` within the same terminal session will use
the exported value given that the variable is not simultaneously overridden.
Updating ESP-IDF
================
You should update ESP-IDF from time to time, as newer versions fix bugs and provide new features. The simplest way to do the update is to delete the existing ``esp-idf`` folder and clone it again, as if performing the initial installation described in :ref:`get-started-get-esp-idf-legacy`.
If downloading to a new path, remember to :doc:`add-idf_path-to-profile` so that the toolchain scripts can find ESP-IDF in its release specific location.
Another solution is to update only what has changed. :ref:`The update procedure depends on the version of ESP-IDF you are using <updating>`.
Related Documents
=================
.. toctree::
:maxdepth: 1
add-idf_path-to-profile
establish-serial-connection
make-project
eclipse-setup
../api-guides/tools/idf-monitor
toolchain-setup-scratch
.. Note: These two targets may be used from git-clone-notes.inc depending on version, don't remove
.. _Stable version: https://docs.espressif.com/projects/esp-idf/en/stable/
.. _Releases page: https://github.com/espressif/esp-idf/releases

View File

@ -1,77 +0,0 @@
****************************************************
Setup Linux Toolchain from Scratch (Legacy GNU Make)
****************************************************
:link_to_translation:`zh_CN:[中文]`
.. include:: ../gnu-make-legacy.rst
.. note::
Standard process for installing the toolchain is described :doc:`here <linux-setup>`. See :ref:`Customized Setup of Toolchain <get-started-customized-setup-legacy>` section for some of the reasons why installing the toolchain from scratch may be necessary.
Install Prerequisites
=====================
To compile with ESP-IDF you need to get the following packages:
- Ubuntu and Debian::
sudo apt-get install gcc git wget make libncurses-dev flex bison gperf python python-pip python-setuptools python-serial python-cryptography python-future python-pyparsing python-pyelftools libffi-dev libssl-dev
- Arch::
sudo pacman -S --needed gcc git make ncurses flex bison gperf python-pyserial python-cryptography python-future python-pyparsing python-pyelftools
.. note::
Some older (pre-2014) Linux distributions may use ``pyserial`` version 2.x which is not supported by ESP-IDF.
In this case please install a supported version via ``pip`` as it is described in section
:ref:`get-started-get-packages-legacy`.
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
- Ubuntu pre-16.04::
sudo apt-get install gawk gperf grep gettext libncurses-dev python python-dev automake bison flex texinfo help2man libtool
- Ubuntu 16.04 or newer::
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
- Arch::
TODO
Create the working directory and go into it::
mkdir -p ~/esp
cd ~/esp
Download ``crosstool-NG`` and build it:
.. include-build-file:: inc/scratch-build-code.inc
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 <setup-linux-toolchain-add-it-to-path-legacy>` 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-legacy`.

View File

@ -1,104 +0,0 @@
*******************************************************
Standard Setup of Toolchain for Linux (Legacy GNU Make)
*******************************************************
:link_to_translation:`zh_CN:[中文]`
.. include:: ../gnu-make-legacy.rst
Install Prerequisites
=====================
To compile with ESP-IDF you need to get the following packages:
- CentOS 7::
sudo yum install gcc git wget make flex bison gperf python python2-cryptography
- Ubuntu and Debian::
sudo apt-get install gcc git wget make flex bison gperf python python-pip python-setuptools python-serial python-cryptography python-future python-pyparsing python-pyelftools libffi-dev libssl-dev
- Arch::
sudo pacman -S --needed gcc git make flex bison gperf python-pyserial python-cryptography python-future python-pyparsing python-pyelftools
.. note::
Some older Linux distributions may be missing some of the Python packages listed above (or may use ``pyserial`` version 2.x which is not supported by ESP-IDF). It is possible to install these packages via ``pip`` instead - as described in section :ref:`get-started-get-packages-legacy`.
Toolchain Setup
===============
.. include-build-file:: inc/download-links.inc
ESP32 toolchain for Linux is available for download from Espressif website:
- for 64-bit Linux:
|download_link_linux64|
- for 32-bit Linux:
|download_link_linux32|
1. Download this file, then extract it in ``~/esp`` directory:
- for 64-bit Linux:
.. include-build-file:: inc/unpack-code-linux64.inc
- for 32-bit Linux:
.. include-build-file:: inc/unpack-code-linux32.inc
.. _setup-linux-toolchain-add-it-to-path-legacy:
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="$HOME/esp/xtensa-esp32-elf/bin:$PATH"
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="$HOME/esp/xtensa-esp32-elf/bin:$PATH"'
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. In CentOS, ``alias`` should set in ``.bashrc``.
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 beginning of displayed string::
$ printenv PATH
/home/user-name/esp/xtensa-esp32-elf/bin:/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
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<linux-dialout-group-legacy>`.
Next Steps
==========
To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf-legacy`.
Related Documents
=================
.. toctree::
:maxdepth: 1
linux-setup-scratch
.. _AUR: https://wiki.archlinux.org/index.php/Arch_User_Repository

View File

@ -1,74 +0,0 @@
*********************************************************
Setup Toolchain for Mac OS from Scratch (Legacy GNU Make)
*********************************************************
:link_to_translation:`zh_CN:[中文]`
.. include:: ../gnu-make-legacy.rst
.. note::
Standard process for installing the toolchain is described :doc:`here <macos-setup>`. See :ref:`Customized Setup of Toolchain <get-started-customized-setup-legacy>` section for some of the reasons why installing the toolchain from scratch may be necessary.
Install Prerequisites
=====================
- install pip::
sudo easy_install pip
.. note::
``pip`` will be used later for installing :ref:`the required Python packages <get-started-get-packages-legacy>`.
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
- with homebrew::
brew install gnu-sed gawk binutils gperftools gettext wget help2man libtool autoconf automake
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::
mkdir -p ~/esp
ln -s /Volumes/ctng ~/esp/ctng-volume
Go into the newly created directory::
cd ~/esp/ctng-volume
Download ``crosstool-NG`` and build it:
.. include-build-file:: inc/scratch-build-code.inc
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/ctng-volume/crosstool-NG/builds/xtensa-esp32-elf``. Follow :ref:`instructions for standard setup <setup-macos-toolchain-add-it-to-path-legacy>` 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-legacy`.

View File

@ -1,59 +0,0 @@
********************************************************
Standard Setup of Toolchain for Mac OS (Legacy GNU Make)
********************************************************
:link_to_translation:`zh_CN:[中文]`
.. include:: ../gnu-make-legacy.rst
Install Prerequisites
=====================
- install pip::
sudo easy_install pip
.. note::
``pip`` will be used later for installing :ref:`the required Python packages <get-started-get-packages-legacy>`.
Toolchain Setup
===============
.. include-build-file:: inc/download-links.inc
ESP32 toolchain for macOS is available for download from Espressif website:
|download_link_osx|
Download this file, then extract it in ``~/esp`` directory:
.. include-build-file:: inc/unpack-code-osx.inc
.. _setup-macos-toolchain-add-it-to-path-legacy:
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=$HOME/esp/xtensa-esp32-elf/bin:$PATH
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=$HOME/esp/xtensa-esp32-elf/bin:$PATH"
Then when you need the toolchain you can type ``get_esp32`` on the command line and the toolchain will be added to your ``PATH``.
Next Steps
==========
To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf-legacy`.
Related Documents
=================
.. toctree::
:maxdepth: 1
macos-setup-scratch

View File

@ -1,77 +0,0 @@
Build and Flash with Make (Legacy GNU Make)
===========================================
:link_to_translation:`zh_CN:[中文]`
.. include:: ../gnu-make-legacy.rst
Finding a project
-----------------
As well as the `esp-idf-template <https://github.com/espressif/esp-idf-template>`_ project, ESP-IDF comes with some example projects on github in the :idf:`examples` directory.
Once you've found the project you want to work with, change to its directory and you can configure and build it.
Configuring your project
------------------------
::
make menuconfig
Compiling your project
----------------------
::
make all
... will compile app, bootloader and generate a partition table based on the config.
Flashing your project
---------------------
When ``make all`` finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this from make by running::
make flash
This will flash the entire project (app, bootloader and partition table) to a new chip. Also if partition table has ota_data then this command will flash a initial ota_data.
It allows to run the newly loaded app from a factory partition (or the first OTA partition, if factory partition is not present).
The settings for serial port flashing can be configured with `make menuconfig`.
You don't need to run ``make all`` before running ``make flash``, ``make flash`` will automatically rebuild anything which needs it.
Compiling & Flashing Just the App
---------------------------------
After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table:
* ``make app`` - build just the app.
* ``make app-flash`` - flash just the app.
``make app-flash`` will automatically rebuild the app if it needs it.
There's no downside to reflashing the bootloader and partition table each time, if they haven't changed.
The Partition Table
-------------------
Once you've compiled your project, the "build" directory will contain a binary file with a name like "my_app.bin". This is an ESP32 image binary that can be loaded by the bootloader.
A single ESP32's flash can contain multiple apps, as well as many kinds of data (calibration data, filesystems, parameter storage, etc). For this reason, a partition table is flashed to offset 0x8000 in the flash.
Each entry in the partition table has a name (label), type (app, data, or something else), subtype and the offset in flash where the partition is loaded.
The simplest way to use the partition table is to `make menuconfig` and choose one of the simple predefined partition tables:
* "Single factory app, no OTA"
* "Factory app, two OTA definitions"
In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table.
For more details about :doc:`partition tables <../api-guides/partition-tables>` and how to create custom variations, view the :doc:`documentation <../api-guides/partition-tables>`.

View File

@ -1,27 +0,0 @@
.. _get-started-customized-setup-legacy:
***********************************************
Customized Setup of Toolchain (Legacy GNU Make)
***********************************************
Instead of downloading binary toolchain from Espressif website (see :ref:`get-started-setup-toolchain-legacy`) you may build the toolchain yourself.
.. include:: ../gnu-make-legacy.rst
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

View File

@ -1,119 +0,0 @@
******************************************************
Setup Windows Toolchain from Scratch (Legacy GNU Make)
******************************************************
.. include:: ../gnu-make-legacy.rst
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 <windows-setup>`, addressed to less experienced users, has been prepared by following these steps.
To quickly setup the toolchain in standard way, using a prebuilt environment, proceed to section :doc:`windows-setup`.
.. _configure-windows-toolchain-from-scratch-legacy:
Configure Toolchain & Environment from Scratch
==============================================
This process involves installing MSYS2_, then installing the MSYS2_ and Python packages which ESP-IDF uses, and finally downloading and installing the Xtensa toolchain.
* 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``.
* Run through the installer steps. **Uncheck the "Run MSYS2 32-bit now" checkbox at the end.**
* Once the installer exits, open Start Menu and find "MSYS2 MinGW 32-bit" to run the terminal.
*(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.)*
* 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.
* 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.
* 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
============================================
.. include-build-file:: inc/download-links.inc
If you already have an MSYS2 install or want to do things differently, you can download just the toolchain here:
|download_link_win32|
.. note::
If you followed instructions :ref:`configure-windows-toolchain-from-scratch-legacy`, you already have the toolchain and you won't need this download.
.. important::
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
==========
To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf-legacy`.
.. _updating-existing-windows-environment-legacy:
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://www.msys2.org/
.. _MSYS2-packages issues list: https://github.com/Alexpux/MSYS2-packages/issues/
.. _raise an IDF issue: https://github.com/espressif/esp-idf/issues/new

View File

@ -1,76 +0,0 @@
*********************************************************
Standard Setup of Toolchain for Windows (Legacy GNU Make)
*********************************************************
:link_to_translation:`zh_CN:[中文]`
.. include:: ../gnu-make-legacy.rst
Introduction
============
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 <eclipse-setup>` or some other front-end), but it runs behind the scenes.
Toolchain Setup
===============
The quick setup is to download the Windows all-in-one toolchain & MSYS2 zip file from dl.espressif.com:
https://dl.espressif.com/dl/esp32_win32_msys2_environment_and_esp2020r2_toolchain-20200601.zip
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.
.. important::
If another toolchain location is used (different than the default ``C:\msys32``), please ensure that the path where the all-in-one toolchain gets unzipped is a plain ASCII, contains no spaces, symlinks or accents.
Check it Out
============
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::
mkdir -p ~/esp
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.
.. figure:: ../../_static/msys2-terminal-window.png
:align: center
:alt: MSYS2 MINGW32 shell window
:figclass: align-center
MSYS2 MINGW32 shell window
Use this window in the following steps setting up development environment for ESP32.
Next Steps
==========
To carry on with development environment setup, proceed to section :ref:`get-started-get-esp-idf-legacy`.
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 <updating-existing-windows-environment-legacy>`, although this is more complex.
Related Documents
=================
.. toctree::
:maxdepth: 1
windows-setup-scratch
.. _MSYS2: https://www.msys2.org/

View File

@ -11,7 +11,3 @@ There is a new ESP-IDF Eclipse Plugin that works with the CMake-based build syst
.. note::
In `Espressif IDF Eclipse Plugins <https://github.com/espressif/idf-eclipse-plugin/blob/master/README.md>`_, though screenshots are captured from macOS, installation instructions are applicable for Windows, Linux and macOS.
.. only:: esp32
If you require Eclipse IDE support for legacy ESP_IDF Make build system, you can follow the :doc:`legacy GNU Make build system Getting Started guide </get-started-legacy/index>` which has steps for :doc:`Building and Flashing with Eclipse IDE </get-started-legacy/eclipse-setup>`.

View File

@ -818,7 +818,6 @@ Related Documents
vscode-setup
../api-guides/tools/idf-monitor
toolchain-setup-scratch
:esp32: ../get-started-legacy/index
.. _Stable version: https://docs.espressif.com/projects/esp-idf/en/stable/
.. _Releases page: https://github.com/espressif/esp-idf/releases

View File

@ -8,9 +8,6 @@ This is a step-by-step alternative to running the :doc:`ESP-IDF Tools Installer
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.
.. _get-esp-idf-windows-command-line:
Get ESP-IDF
@ -54,7 +51,7 @@ 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.
Ninja currently only provides binaries for 64-bit Windows.
Download the Ninja_ latest stable Windows release from the (`download page <ninja-dl_>`_).
@ -85,10 +82,6 @@ Unzip the zip file to ``C:\Program Files`` (or some other location). The zip fil
Next, the ``bin`` subdirectory of this directory must be :ref:`added to your Path <add-directory-windows-path>`. For example, the directory to add may be ``C:\Program Files\{IDF_TARGET_TOOLCHAIN_PREFIX}\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\{IDF_TARGET_TOOLCHAIN_PREFIX}\bin`` to the Path instead, as the toolchain is included in the MSYS2 environment.
.. _add-directory-windows-path:
Adding Directory to Path
@ -110,7 +103,6 @@ To carry on with development environment setup, proceed to :ref:`get-started-set
.. _Ninja: https://ninja-build.org/
.. _ninja-dl: https://github.com/ninja-build/ninja/releases
.. _Python: https://www.python.org/downloads/windows/
.. _MSYS2: https://www.msys2.org/
.. _kconfig-frontends releases page: https://github.com/espressif/kconfig-frontends/releases
.. Note: These two targets may be used from git-clone-notes.inc depending on version, don't remove
.. _Stable version: https://docs.espressif.com/projects/esp-idf/en/stable/

View File

@ -4,11 +4,6 @@ Standard Setup of Toolchain for Windows
:link_to_translation:`zh_CN:[中文]`
.. only:: esp32
.. note::
Currently only 64-bit versions of Windows are supported. 32-bit Windows can use the :doc:`Legacy GNU Make Build System<../get-started-legacy/windows-setup>`.
Introduction
============
@ -16,11 +11,6 @@ ESP-IDF requires some prerequisite tools to be installed so you can build firmwa
For this Getting Started we're going to use the Command Prompt, but after ESP-IDF is installed you can use :doc:`Eclipse <eclipse-setup>` or another graphical IDE with CMake support instead.
.. only:: esp32
.. note::
Previous versions of ESP-IDF used the :doc:`Legacy GNU Make Build System<../get-started-legacy/windows-setup>` and MSYS2_ Unix compatibility environment. This is no longer required, ESP-IDF can be used from the Windows Command Prompt.
.. note::
Limitations:
- The installation path of ESP-IDF and ESP-IDF Tools must not be longer than 90 characters. Too long installation paths might result in a failed build.

View File

@ -1 +0,0 @@
.. note:: Since ESP-IDF V4.0, the default build system is based on CMake. This documentation is for the legacy build system based on GNU Make. Support for this build system may be removed in future major releases.

View File

@ -0,0 +1,4 @@
Migrate Build System to ESP-IDF 5.0
===================================
Please follow the :ref:`build system <migrating_from_make>` guide for migrating make-based projects no longer supported in ESP-IDF v5.0.

View File

@ -6,3 +6,4 @@ ESP-IDF 5.0 Migration Guides
:maxdepth: 1
Peripherals <peripherals>
Build System <build-system>

View File

@ -225,7 +225,7 @@ How To Enable Secure Boot V2
5. Set other menuconfig options (as desired). Pay particular attention to the "Bootloader Config" options, as you can only flash the bootloader once. Then exit menuconfig and save your configuration.
6. The first time you run ``make`` or ``idf.py build``, if the signing key is not found then an error message will be printed with a command to generate a signing key via ``espsecure.py generate_signing_key``.
6. The first time you run ``idf.py build``, if the signing key is not found then an error message will be printed with a command to generate a signing key via ``espsecure.py generate_signing_key``.
.. important::
A signing key generated this way will use the best random number source available to the OS and its Python installation (`/dev/urandom` on OSX/Linux and `CryptGenRandom()` on Windows). If this random number source is weak, then the private key will be weak.
@ -366,7 +366,7 @@ The following sections contain low-level reference descriptions of various Secur
Manual Commands
~~~~~~~~~~~~~~~
Secure boot is integrated into the esp-idf build system, so ``make`` or ``idf.py build`` will sign an app image and ``idf.py bootloader`` will produce a signed bootloader if secure signed binaries on build is enabled.
Secure boot is integrated into the esp-idf build system, so ``idf.py build`` will sign an app image and ``idf.py bootloader`` will produce a signed bootloader if secure signed binaries on build is enabled.
However, it is possible to use the ``espsecure.py`` tool to make standalone signatures and digests.

View File

@ -481,20 +481,16 @@ ESP-IDF 中 Gcov 和 Gcovr 应用
为了获得项目中的代码覆盖率数据,项目中的一个或多个源文件必须用 ``--coverage`` 选项进行编译。在 ESP-IDF 中,这可以在组件级或单个源文件级实现:
使组件中的所有源文件用 ``--coverage`` 选项进行编译:
- 如果使用 CMake则在组件的 ``CMakeLists.txt`` 文件中添加 ``target_compile_options(${COMPONENT_LIB} PRIVATE --coverage)``
- 如果使用 Make则在组件的 ``component.mk`` 文件中添加 ``CFLAGS += --coverage``
在组件的 CMakeLists.txt 文件中添加 target_compile_options(${COMPONENT_LIB} PRIVATE --coverage) 可将组件中的所有源文件用 --coverage 选项进行编译。
使同一组件中选定的一些源文件(如 ``sourec1.c````source2.c``)通过 ``--coverage`` 选项编译:
- 如果使用 CMake则在组件的 ``CMakeLists.txt`` 文件中添加 ``set_source_files_properties(source1.c source2.c PROPERTIES COMPILE_FLAGS --coverage)``
- 如果使用 Make则在组件的 ``component.mk`` 文件中添加 ``source1.o: CFLAGS += --coverage````source2.o: CFLAGS += --coverage``
在组件的 CMakeLists.txt 文件中添加 set_source_files_properties(source1.c source2.c PROPERTIES COMPILE_FLAGS --coverage) 可将同一组件中选定的一些源文件(如 sourec1.c 和 source2.c通过 --coverage 选项编译。
当一个源文件用 ``--coverage`` 选项编译时(例如 ``gcov_example.c``),编译器会在项目的构建目录下生成 ``gcov_example.gcno`` 文件。
项目配置
~~~~~~~~~~~~~~~~~
在构建一个有源代码覆盖的项目之前,请通过运行 ``idf.py menuconfig``(如使用传统的 Make 构建系统,则启用 ``make menuconfig``启用以下项目配置选项。
在构建一个有源代码覆盖的项目之前,请通过运行 ``idf.py menuconfig`` 启用以下项目配置选项。
- 通过 :ref:`CONFIG_APPTRACE_DESTINATION` 选项选择 *Trace Memory* 来启用应用程序跟踪模块。
- 通过 :ref:`CONFIG_APPTRACE_GCOV_ENABLE` 选项启用 Gcov 主机。
@ -508,7 +504,7 @@ ESP-IDF 中 Gcov 和 Gcovr 应用
覆盖率数据的转储通过 OpenOCD 进行(关于如何设置和运行 OpenOCD请参考 :doc:`JTAG调试 <../api-guides/jtag-debugging/index>`)。由于是通过向 OpenOCD 发出命令来触发转储,因此必须打开 telnet 会话来向 OpenOCD 发出这些命令(运行 ``telnet localhost 4444``。GDB 也可以代替 telnet 来向 OpenOCD 发出命令,但是所有从 GDB 发出的命令都需要以 ``mon <oocd_command>`` 为前缀。
当目标机转储代码覆盖数据时,``.gcda`` 文件存储在项目的构建目录中。例如,如果 ``main`` 组件的 ``gcov_example_main.c`` 在编译时使用了 ``--coverage`` 选项,那么转储代码覆盖数据将在 ``build/esp-idf/main/CMakeFiles/__idf_main.dir/gcov_example_main.c.gcda``(如果使用传统 Make 构建系统,则是在 ``build/main/gcov_example_main.gcda`` 中)生成一个 ``gcov_example_main.gcda`` 文件。注意,编译过程中产生的 ``.gcno`` 文件也放在同一个目录下。
当目标机转储代码覆盖数据时,``.gcda`` 文件存储在项目的构建目录中。例如,如果 ``main`` 组件的 ``gcov_example_main.c`` 在编译时使用了 ``--coverage`` 选项,那么转储代码覆盖数据将在 ``build/esp-idf/main/CMakeFiles/__idf_main.dir/gcov_example_main.c.gcda`` 中生成一个 ``gcov_example_main.gcda`` 文件。注意,编译过程中产生的 ``.gcno`` 文件也放在同一个目录下。
代码覆盖数据的转储可以在应用程序的整个生命周期内多次进行。每次转储都会用最新的代码覆盖信息更新 ``.gcda`` 文件。代码覆盖数据是累积的,因此最新的数据将包含应用程序整个生命周期中每个代码路径的总执行次数。
@ -558,10 +554,7 @@ Gcov 和 Gcovr 都可以用来生成代码覆盖报告。安装 Xtensa 工具链
用户可以在自己的工程中定义额外的构建目标从而更方便地生成报告。可以通过一个简单的构建命令生成这样的报告。
CMake 构建系统
************************
对于 CMake 构建系统,请在您工程的 ``CMakeLists.txt`` 文件中添加以下内容:
请在您工程的 ``CMakeLists.txt`` 文件中添加以下内容:
.. code-block:: none
@ -573,32 +566,3 @@ CMake 构建系统
* ``cmake --build build/ --target gcovr-report``:在 ``$(BUILD_DIR_BASE)/coverage_report/html`` 目录下生成 HTML 格式代码覆盖报告。
* ``cmake --build build/ --target cov-data-clean``:删除所有代码覆盖数据文件。
Make 构建系统
************************
对于 Make 构建系统,请在您工程的 ``Makefile`` 文件中添加以下内容:
.. code-block:: none
GCOV := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))gcov
REPORT_DIR := $(BUILD_DIR_BASE)/coverage_report
gcovr-report:
echo "Generating coverage report in: $(REPORT_DIR)"
echo "Using gcov: $(GCOV)"
mkdir -p $(REPORT_DIR)/html
cd $(BUILD_DIR_BASE)
gcovr -r $(PROJECT_PATH) --gcov-executable $(GCOV) -s --html-details $(REPORT_DIR)/html/index.html
cov-data-clean:
echo "Remove coverage data files..."
find $(BUILD_DIR_BASE) -name "*.gcda" -exec rm {} +
rm -rf $(REPORT_DIR)
.PHONY: gcovr-report cov-data-clean
可使用以下命令:
* ``make gcovr-report``:在 ``$(BUILD_DIR_BASE)/coverage_report/html`` 目录下生成 HTML 格式代码覆盖报告。
* ``make cov-data-clean``:删除所有代码覆盖数据文件。

View File

@ -135,10 +135,6 @@ ROM 中的 :ref:`first-stage-bootloader` 从 flash 中读取 :ref:`second-stage-
如果引导加载程序二进制文件过大,则引导加载程序会构建将失败并显示 "Bootloader binary size [..] is too large for partition table offset" 的错误。如果此二进制文件已经被烧录,那么 {IDF_TARGET_NAME} 将无法启动 - 日志中将记录无效分区表或无效引导加载程序校验和的错误。
.. note::
对引导加载程序大小检查仅发生在 CMake 构建系统中,若使用的是旧版 GNU Make 构建系统,则不会检查大小,但如果引导加载程序太大,{IDF_TARGET_NAME} 将无法启动。
可以使用如下方法解决此问题:
- 将 :ref:`bootloader 编译器优化 <CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION>` 重新设置回默认值“Size”。
@ -163,5 +159,3 @@ ROM 中的 :ref:`first-stage-bootloader` 从 flash 中读取 :ref:`second-stage-
在引导加载程序的代码中,用户不能使用其他组件提供的驱动和函数,如果确实需要,请将该功能的实现部分放在项目的 `bootloader_components` 目录中(注意,这会增加引导加载程序的大小)。
如果引导加载程序过大,则可能与内存中的分区表重叠,分区表默认烧录在偏移量 0x8000 处。增加 :ref:`分区表偏移量 <CONFIG_PARTITION_TABLE_OFFSET>` ,将分区表放在 flash 中靠后的区域,这样可以增加引导程序的可用空间。
.. note:: 上述任意一种自定义引导程序的方法都需要使用 CMake 构建系统(即不支持传统的 Make 构建系统)。

View File

@ -1,535 +0,0 @@
构建系统 (传统 GNU Make)
==========================
:link_to_translation:`en:[English]`
.. include:: ../gnu-make-legacy.rst
本文将介绍乐鑫物联网开发框架中的 ``构建系统````组件`` 的相关概念。
如果您想了解如何构建一个新的 ESP-IDF 项目,请阅读本文档。
我们建议您使用 `ESP-IDF 模板工程 <https://github.com/espressif/esp-idf-template>`_ 来开始您的新项目。
使用构建系统
------------
ESP-IDF 的 :idf_file:`README.md` 文件对如何使用构建系统来构建项目作了简要的说明。
概述
----
一个 ESP-IDF 项目可以看作是许多不同组件的集合,例如对于一个展示当前湿度的网站服务器来说,它可能会包含如下一些组件:
- ESP32 基础库libcrom bindings 等)
- WiFi 驱动库
- TCP/IP 协议栈
- FreeRTOS 操作系统
- 网站服务器
- 湿度传感器的驱动
- 将上述组件组织在一起的主代码
ESP-IDF 可以显式地指定和配置每个组件。在构建项目的时候,构建系统会查找 ESP-IDF 目录、项目目录和用户自定义目录(可选)中所有的组件,然后使用基于文本的菜单系统让用户配置 ESP-IDF 项目中需要的每个组件。在配置结束后,构建系统开始编译整个项目。
概念
~~~~
- ``项目`` 特指一个目录,其中包含了构建可执行文件的所有源文件和配置,还有其他的支持型输出文件,比如分区表、数据/文件系统分区和引导程序。
- ``项目配置`` 保存在项目根目录下名为 sdkconfig 的文件中,它可以通过 ``make menuconfig`` 进行修改,且一个项目只能包含一个项目配置。
- ``应用程序`` 是由 ESP-IDF 构建得到的可执行文件。一个项目通常会构建两个应用程序:项目应用程序(主可执行文件,即用户自定义的固件)和引导程序(启动并初始化项目应用程序的引导程序)。
- ``组件`` 是模块化的、独立的代码,它们被编译成静态库(.a 文件)后再链接成应用程序,有些组件是 ESP-IDF 官方提供的,有些则可能来自其它项目。
以下内容并不是项目的组成部分:
- ``ESP-IDF`` 并不是项目的一部分,相反,它是独立的,并通过 IDF_PATH 环境变量链接到项目中,这样做就可以使 IDF 框架与您的项目分离,其中 IDF_PATH 变量保存了 ESP-IDF 目录的路径。
- 交叉编译工具链并不是项目的组成部分,它应该被安装在系统 PATH 环境变量中,或者可以在项目配置中显式指定工具链的前缀为本地的安装路径。
示例项目
~~~~~~~~
示例项目的目录树结构可能如下所示::
- myProject/
- Makefile
- sdkconfig
- components/ - component1/ - component.mk
- Kconfig
- src1.c
- component2/ - component.mk
- Kconfig
- src1.c
- include/ - component2.h
- main/ - src1.c
- src2.c
- component.mk
- build/
该示例项目 ``myProject`` 包含以下组成部分:
- 项目顶层 Makefile该 Makefile 设置了 ``PROJECT_NAME`` 变量,还可以定义作用于整个项目的其它 make 变量(可选)。顶层 Makefile 会导入核心 Makefile 文件 ``$(IDF_PATH)/make/project.mk`` ,由它负责实现 ESP-IDF 构建系统的剩余部分。
- 项目配置文件 sdkconfig执行 ``make menuconfig`` 后会创建或更新此文件,该文件中保存了项目中所有组件的配置信息(包括 ESP-IDF 本身)。``sdkconfig`` 文件可能会也可能不会被添加到项目的源代码管理系统中。
- 可选的组件目录中包含了属于项目一部分的自定义组件,不是每一个项目都需要它,但它有助于构建可重用代码或者导入第三方组件。
- ``main`` 目录是一个特殊的 ``伪组件``,它包含项目本身的源代码。``main`` 是默认名称Makefile 变量 ``COMPONENT_DIRS`` 默认会导入此组件,但您也可以修改此变量(或者设置 ``EXTRA_COMPONENT_DIRS`` )以查找其他位置的组件。
- ``build`` 目录在项目构建的时候创建或者更新,里面包含有构建生成的临时目标文件和库以及最终输出的二进制文件。此目录通常不会被添加到项目的源代码管理系统中,也不会随着项目源代码被发布。
组件目录中会包含组件自己的 Makefile 文件 ``component.mk`` ,里面会定义一些变量来控制该组件的构建过程,以及它与整个项目的集成。更多详细信息请参考 `组件 Makefiles <#component-makefiles>`_
每个组件还可以包含一个 ``Kconfig`` 文件,它用于定义 ``menuconfig`` 时展示的组件配置信息的选项规则。某些组件还可能还会包含 ``Kconfig.projbuild````Makefile.projbuild`` 特殊文件,他们可以用来覆盖项目的部分配置。
项目 Makefiles
~~~~~~~~~~~~~~
每个项目都有一个 Makefile ,它包含整个项目的构建设置。默认情况下,项目 Makefile 可以非常小。
最小 Makefile 示例
^^^^^^^^^^^^^^^^^^
::
PROJECT_NAME := myProject
include $(IDF_PATH)/make/project.mk
必须设置的项目变量
^^^^^^^^^^^^^^^^^^
- ``PROJECT_NAME``: 项目名称,最终输出的二进制文件也使用该名称,即 myProject.binmyProject.elf 。
可选的项目变量
^^^^^^^^^^^^^^
以下这些变量都有默认值,用户可以重写这些变量以自定义构建行为。查看 ``make/project.mk`` 文件可以获得所有的实现细节。
- ``PROJECT_PATH``:顶层项目目录,默认是包含 Makefile 文件的目录,许多其他的项目变量都基于此变量。注意,项目路径中不能包含有空格。
- ``BUILD_DIR_BASE``:所有对象、库、二进制文件的输出目录,默认为 ``$(PROJECT_PATH)/build``
- ``COMPONENT_DIRS``:组件的搜索目录,默认为 ``$(IDF_PATH)/components````$(PROJECT_PATH)/components````$(PROJECT_PATH)/main````EXTRA_COMPONENT_DIRS`` 。如果您不希望从这些目录中搜索组件,请重写此变量。
- ``EXTRA_COMPONENT_DIRS``:组件额外的搜索路径,可选。
- ``COMPONENTS`` 要构建进项目中的组件列表,默认为 ``COMPONENT_DIRS`` 指定目录中所有的组件。
- ``EXCLUDE_COMPONENTS`` 在构建的过程中需要剔除的组件列表,可选。请注意这只会减少构建的时间,并不会减少最终二进制文件的大小。
- ``TEST_EXCLUDE_COMPONENTS``:在构建单元测试的过程中需要剔除的组件列表,可选。
以上这些 Makefile 变量中的任何路径都要使用绝对路径,您可以使用 ``$(PROJECT_PATH)/xxx````$(IDF_PATH)/xxx``,或者使用 Make 内置函数 ``$(abspath xxx)`` 将相对路径转换为绝对路径。
以上这些变量要在 Makefile 中 ``include $(IDF_PATH)/make/project.mk`` 的前面进行设置。
.. _component-makefiles:
组件 Makefiles
~~~~~~~~~~~~~~
每个项目都包含一个或者多个组件,这些组件可以是 ESP-IDF 的一部分,也可以从其他组件目录添加。
组件是包含 ``component.mk`` 文件的任何目录。
搜索组件
~~~~~~~~
搜索 ``COMPONENT_DIRS`` 中指定的目录以查找项目会使用的组件,目录可以是组件本身(即他们包含 ``component.mk`` 文件),也可以是包含组件的上层目录。
运行 ``make list-components`` 命令可以查询这些变量的值,这有助于调试组件的搜索路径是否正确。
同名组件
^^^^^^^^
ESP-IDF 搜索组件时,会按照 ``COMPONENT_DIRS`` 指定的顺序依次进行,这意味着在默认情况下,首先是 ESP-IDF 组件,然后是项目组件,最后是 ``EXTRA_COMPONENT_DIRS`` 中的组件。如果这些目录中的两个或者多个包含具有相同名字的组件,则使用搜索到的最后一个位置的组件。这就允许将组件复制到项目目录中再修改来覆盖 ESP-IDF 组件如果使用这种方式ESP-IDF 目录本身可以保持不变。
.. _minimal-component-makefile:
最小组件 Makefile
^^^^^^^^^^^^^^^^^
最简单的 ``component.mk`` 文件可以是一个空文件,如果文件为空,则组件的默认构建行为会被设置为:
- makefile 所在目录中的所有源文件(``*.c````*.cpp````*.cc````*.S``)将会被编译进组件库中。
- 子目录 ``include`` 将被添加到其他组件的全局头文件搜索路径中。
- 组件库将会被链接到项目的应用程序中。
更完整的组件 makefile 可以查看 `组件 Makefile 示例 <#example-component-makefile>`_
请注意,空的 ``component.mk`` 文件同没有 ``component.mk`` 文件之间存在本质差异,前者会调用默认的组件构建行为,后者不会发生默认的组件构建行为。一个组件中如果只包含影响项目配置或构建过程的文件,那么它可以没有 ``component.mk`` 文件。
.. _preset-component-variables:
预设的组件变量
^^^^^^^^^^^^^^
以下特定于组件的变量可以在 ``component.mk`` 中使用,但不应该被修改。
- ``COMPONENT_PATH`` 组件的目录,即包含 ``component.mk`` 文件的绝对路径,路径中不能包含空格。
- ``COMPONENT_NAME`` 组件的名字,默认为组件目录的名称。
- ``COMPONENT_BUILD_DIR`` 组件的构建目录,即存放组件构建输出的绝对路径,它是 `$(BUILD_DIR_BASE)` 的子目录。该变量也是构建组件时的当前工作目录,所以 make 中的相对路径都以此目录为基础。
- ``COMPONENT_LIBRARY`` 组件构建后的静态库文件(相对于组件的构建目录)的名字,默认为 ``$(COMPONENT_NAME).a``
以下变量在项目顶层中设置,并被导出到组件中构建时使用:
- ``PROJECT_NAME`` 项目名称,在项目的 Makefile 中设置。
- ``PROJECT_PATH`` 包含项目 Makefile 的目录的绝对路径。
- ``COMPONENTS`` 此次构建中包含的所有组件的名字。
- ``CONFIG_*`` 项目配置中的每个值在 make 中都对应一个以 ``CONFIG_`` 开头的变量。
- ``CC````LD````AR````OBJCOPY`` gcc xtensa 交叉编译工具链中每个工具的完整路径。
- ``HOSTCC````HOSTLD````HOSTAR`` 主机本地工具链中每个工具的全名。
- ``IDF_VER`` ESP-IDF 的版本号,可以通过检索 ``$(IDF_PATH)/version.txt`` 文件(假如存在的话)或者使用 git 命令 ``git describe`` 来获取。这里推荐的格式是在一行中指定主 IDF 的发布版本号,例如标记为 ``v2.0`` 的发布版本或者是标记任意一次提交记录的 ``v2.0-275-g0efaa4f``。应用程序可以通过调用 :cpp:func:`esp_get_idf_version` 函数来使用该变量。
- ``IDF_VERSION_MAJOR``, ``IDF_VERSION_MINOR``, ``IDF_VERSION_PATCH``: ESP-IDF 的组件版本,可用于条件表达式。请注意这些信息的精确度不如 ``IDF_VER`` 变量,版本号 ``v4.0-dev-*`` ``v4.0-beta1`` ``v4.0-rc1````v4.0`` 对应的 ``IDF_VERSION_*`` 变量值是相同的,但是 ``IDF_VER`` 的值是不同的。
- ``PROJECT_VER``:项目版本。
* 如果设置了 :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` 选项,则将使用 :ref:`CONFIG_APP_PROJECT_VER` 的值作为项目版本。
* 如果在项目 Makefile 文件中设置了 ``PROJECT_VER`` 变量,则使用该值作为项目版本。
* 如果存在 ``$PROJECT_PATH/version.txt``,则用其内容为 ``PROJECT_VER``
* 如果项目位于 Git 仓库中,将使用 git 描述部分的内容作为项目版本。
* 如果以上均不存在,则 ``PROJECT_VER`` 为 "1"。
如果您在 ``component.mk`` 文件中修改这些变量,这并不会影响其它组件的构建,但可能会使您的组件变得难以构建或调试。
.. _optional-project-wide-component-variables:
可选的项目通用组件变量
^^^^^^^^^^^^^^^^^^^^^^
可以在 ``component.mk`` 中设置以下变量来控制整个项目的构建行为:
- ``COMPONENT_ADD_INCLUDEDIRS`` 相对于组件目录的路径,将被添加到项目中所有组件的头文件搜索路径中。如果该变量未被覆盖,则默认为 ``include`` 目录。如果一个头文件路径仅仅为当前组件所用,那么应该将该路径添加到 ``COMPONENT_PRIV_INCLUDEDIRS`` 中。
- ``COMPONENT_ADD_LDFLAGS`` 添加链接参数到全局 ``LDFLAGS`` 中用以指导链接最终的可执行文件,默认为 ``-l$(COMPONENT_NAME)``。如果将预编译好的库添加到此目录,请使用它们为绝对路径,即 ``$(COMPONENT_PATH)/libwhatever.a``
- ``COMPONENT_DEPENDS`` 需要在当前组件之前构建的组件列表,这对于处理链接时的依赖不是必需的,因为所有组件的头文件目录始终可用。如果一个组件会生成一个头文件,然后另外一个组件需要使用它,此时该变量就有必要进行设置。大多数的组件不需要设置此变量。
- ``COMPONENT_ADD_LINKER_DEPS`` 保存一些文件的路径,当这些文件发生改变时,会触发 ELF 文件重新链接。该变量通常用于链接脚本文件和二进制文件,大多数的组件不需要设置此变量。
以下变量仅适用于属于 ESP-IDF 的组件:
- ``COMPONENT_SUBMODULES`` 组件使用的 git 子模块的路径列表(相对于 ``COMPONENT_PATH``)。这些路径会在构建的过程中被检查(并在必要的时候初始化)。如果组件位于 ``IDF_PATH`` 目录之外,则忽略此变量。
可选的组件特定变量
^^^^^^^^^^^^^^^^^^
以下变量可以在 ``component.mk`` 中进行设置,用以控制该组件的构建行为:
- ``COMPONENT_PRIV_INCLUDEDIRS`` 相对于组件目录的目录路径,该目录仅会被添加到该组件源文件的头文件搜索路径中。
- ``COMPONENT_EXTRA_INCLUDES`` 编译组件的源文件时需要指定的额外的头文件搜索路径,这些路径将以 ``-l`` 为前缀传递给编译器。这和 ``COMPONENT_PRIV_INCLUDEDIRS`` 变量的功能有些类似,但是这些路径不会相对于组件目录进行扩展。
- ``COMPONENT_SRCDIRS`` 相对于组件目录的目录路径,这些路径用于搜索源文件(``*.cpp````*.c````*.S``),默认为 ``.``,即组件目录本身。重写该变量可以指定包含源文件的不同目录列表。
- ``COMPONENT_OBJS`` 要编译生成的目标文件,默认是 ``COMPONENT_SRCDIRS`` 中每个源文件的 .o 文件。重写该变量将允许您剔除 ``COMPONENT_SRCDIRS`` 中的某些源文件,否则他们将会被编译。相关示例请参阅 `指定需要编译的组件源文件 <#specify-source-files>`_
- ``COMPONENT_EXTRA_CLEAN`` 相对于组件构建目录的路径,指向 ``component.mk`` 文件中自定义 make 规则生成的任何文件,它们也是 ``make clean`` 命令需要删除的文件。相关示例请参阅 `源代码生成 <#source-code-generation>`_
- ``COMPONENT_OWNBUILDTARGET`` & ``COMPONENT_OWNCLEANTARGET`` 这些目标允许您完全覆盖组件的默认编译行为。有关详细信息,请参阅 `完全覆盖组件的 Makefile <#fully-overriding-component-makefile-legacy>`_。
- ``COMPONENT_CONFIG_ONLY`` 如果设置了此标志,则表示组件根本不会产生构建输出(即不会构建得到 ``COMPONENT_LIBRARY``),并且会忽略大多数其它组件变量。此标志用于 IDF 内部组件,其中仅包含 ``KConfig.projbuild`` 和/或 ``Makefile.projbuild`` 文件来配置项目,但是没有源文件。
- ``CFLAGS`` 传递给 C 编译器的标志。根据项目设置已经定义一组默认的 ``CFLAGS``,可以通过 ``CFLAGS +=`` 来为组件添加特定的标志,也可以完全重写该变量(尽管不推荐这么做)。
- ``CPPFLAGS`` 传递给 C 预处理器的标志(用于 ``.c````.cpp````.S`` 文件)。根据项目设置已经定义一组默认的 ``CPPFLAGS`` ,可以通过 ``CPPFLAGS +=`` 来为组件添加特定的标志,也可以完全重写该变量(尽管不推荐这么做)。
- ``CXXFLAGS`` 传递给 C++ 编译器的标志。根据项目设置已经定义一组默认的 ``CXXFLAGS`` ,可以通过 ``CXXFLAGS +=`` 来为组件添加特定的标志,也可以完全重写该变量(尽管不推荐这么做)。
- ``COMPONENT_ADD_LDFRAGMENTS``:链接器脚本生成功能的链接器片段文件的路径,请查看 :doc:`链接器脚本生成 <linker-script-generation>`.
如果要将编译标志应用于单个源文件,您可以将该源文件的目标规则覆盖,例如::
apps/dhcpserver.o: CFLAGS += -Wno-unused-variable
如果上游代码在编译的时候发出了警告,那这么做可能会很有效。
配置组件
~~~~~~~~
每个组件都可以包含一个 Kconfig 文件,和 ``component.mk`` 放在同一个目录下。Kconfig 中包含此组件在 ``make menuconfig`` 时要展示的配置规则的设置。
运行 menuconfig 时,可以在 ``Component Settings`` 菜单栏下找到这些设置。
创建一个组件的 Kconfig 文件,最简单的方法就是使用 ESP-IDF 中现有的 Kconfig 文件作为模板,在这基础上进行修改。
有关示例请参阅 `添加条件配置 <#add-conditional-configuration>`_
预处理器定义
~~~~~~~~~~~~
ESP-IDF 构建系统会在命令行中添加以下 C 预处理定义:
- ``ESP_PLATFORM`` — 可以用来检测在 ESP-IDF 内发生的构建行为。
- ``IDF_VER`` — ESP-IDF 的版本,请参阅 `预设的组件变量 <#preset-component-variables>`_
构建的内部过程
~~~~~~~~~~~~~~
顶层:项目 Makefile
^^^^^^^^^^^^^^^^^^^
- ``make`` 始终从项目目录处运行,并且项目的 makefile 名字通常为 Makefile 。
- 项目的 makefile 文件会设置 ``PROJECT_NAME`` ,并且可以自定义其他可选的项目变量。
- 项目 makefile 文件会导入 ``$(IDF_PATH)/make/project.mk`` ,该文件中会导入项目级的 Make 逻辑。
- ``project.mk`` 填写默认的项目级 make 变量,并导入项目配置中的 make 变量。如果生成的包含项目配置的 makefile 文件已经过期,那么它将会被重新生成(通过 ``project_config.mk`` 中的目标规则),然后 make 进程从顶层重新开始。
- ``project.mk`` 根据默认组件目录或者可选项目变量中设置的自定义组件列表来编译组件。
- 每个组件都可以设置一些 `可选的项目通用组件变量 <#optional-project-wide-component-variables>`_ ,他们会通过 ``component_project_vars.mk`` 被导入 ``project.mk`` 文件中。如果这些文件有缺失或者过期,他们会被重新生成(通过对组件 makefile 的递归调用),然后 make 进程从顶层重新开始。
- 组件中的 Makefile.projbuild 文件被包含在了 make 的进程中,以添加额外的目标或者配置。
- 默认情况下,项目 makefile 还为每个组件生成顶层的编译和清理目标,并设置 app 和 clean 目标来调用所有这些子目标。
- 为了编译每个组件,对组件 makefile 执行递归构建。
为了更好地理解项目的构建过程,请通读 ``project.mk`` 文件。
第二层:组件 Makefile 文件
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 每次调用组件 makefile 文件都是通过 ``$(IDF_PATH)/make/component_wrapper.mk`` 这个包装器进行的。
- 此组件包装器包含了所有组件的 ``Makefile.componentbuild`` 文件,使这些文件中的任何配置,变量都可用于每个组件。
- 调用 ``component_wrapper.mk`` 时将当前目录设置为组件构建目录,并将 ``COMPONENT_MAKEFILE`` 变量设置为 ``component.mk`` 的绝对路径。
- ``component_wrapper.mk`` 为所有组件变量设置默认值,然后导入 ``component.mk`` 文件来覆盖或修改这些变量。
- 如果未定义 ``COMPONENT_OWNBUILDTARGET````COMPONENT_OWNCLEANTARGET`` 文件,则会为组件的源文件和必备组件 ``COMPONENT_LIBRARY`` 静态库文件创建默认构建和清理目标。
- ``component_project_vars.mk`` 文件在 ``component_wrapper.mk`` 中有自己的目标,如果由于组件的 makefile 或者项目配置的更改而需要重建此文件,则从 ``project.mk`` 文件中进行评估。
为了更好地理解组件制作过程,请阅读 ``component_wrapper.mk`` 文件和 ESP-IDF 中的 ``component.mk`` 文件。
以非交互的方式运行 Make
~~~~~~~~~~~~~~~~~~~~~~~
如果在运行 ``make`` 的时候不希望出现交互式提示(例如:在 IDE 或自动构建系统中),可以将 ``BATCH_BUILD=1`` 添加到 make 的参数中(或者将其设置为环境变量)。
设置 ``BATCH_BUILD`` 意味着:
- 详细输出(与 ``V=1`` 相同,见下文),如果不需要详细输出,就设置 ``V=0``
- 如果项目配置缺少新配置项(来自新组件或者 ESP-IDF 更新),则项目使用默认值,而不是提示用户输入每个项目。
- 如果构建系统需要调用 ``menuconfig`` ,则会打印错误并且构建失败。
.. _make-size:
构建目标的进阶用法
~~~~~~~~~~~~~~~~~~
- ``make app````make bootloader````make partition table`` 可以根据需要为项目单独构建生成应用程序文件、启动引导文件和分区表文件。
- ``make erase_flash````make erase_otadata`` 会调用 esptool.py 脚本分别擦除整块闪存芯片或者其中 OTA 分区的内容。
- ``make size`` 会打印应用程序的大小信息。``make size-components````make size-files`` 两者功能相似,分别打印每个组件或者每个源文件大小的详细信息。
调试 Make 的过程
~~~~~~~~~~~~~~~~
调试 ESP-IDF 构建系统的一些技巧:
- 将 ``V=1`` 添加到 make 的参数中(或将其设置为环境变量)将使 make 回显所有已经执行的命令,以及为子 make 输入的每个目录。
- 运行 ``make -w`` 将导致 make 在为子 make 输入时回显每个目录——与 ``V=1`` 相同但不回显所有命令。
- 运行 ``make --trace`` (可能除了上述参数之一)将打印出构建时的每个目标,以及导致它构建的依赖项)。
- 运行 ``make -p`` 会打印每个 makefile 中每个生成的目标的(非常详细的)摘要。
更多调试技巧和通用的构建信息,请参阅 `GNU 构建手册 <http://www.gnu.org/software/make/manual/make.html>`_
.. _warn-undefined-variables-legacy:
警告未定义的变量
^^^^^^^^^^^^^^^^
默认情况下,如果引用了未定义的变量(如 ``$(DOES_NOT_EXIST)`` ,构建过程将会打印警告,这对于查找变量名称中的错误非常有用。
如果不想要此行为,可以在 menuconfig 顶层菜单下的 `SDK tool configuration` 中禁用它。
请注意,如果在 Makefile 中使用 ``ifdef`` 或者 ``ifndef`` ,则此选项不会出发警告。
覆盖项目的部分内容
~~~~~~~~~~~~~~~~~~
Makefile.projbuild
^^^^^^^^^^^^^^^^^^
如果一个组件含有必须要在项目构建过程的顶层进行计算的变量,则可以在组件目录下创建名为 ``Makefile.projbuild`` 的文件,项目在执行 ``project.mk`` 的时候会导入此 makefile 。
例如,如果您的组件需要为整个项目添加 CFLAGS不仅仅是为自身的源文件那么可以在 ``Makefile.projbuild`` 中设置 ``CFLAGS +=``
``Makefile.projbuild`` 文件在 ESP-IDF 中大量使用,用于定义项目范围的构建功能,例如 ``esptool.py`` 命令行参数和 ``bootloader`` 这个特殊的程序。
请注意, ``Makefile.projbuild`` 对于最常见的组件不是必需的 - 例如向项目中添加 include 目录,或者将 LDFLAGS 添加到最终链接步骤,同样可以通过 ``component.mk`` 文件来自定义这些值。有关详细信息,请参阅 `可选的项目通用组件变量 <#optional-project-wide-component-variables>`_
在此文件中设置变量或者目标时要小心,由于这些值包含在项目的顶层 makefile 中,因此他们可以影响或者破坏所有组件的功能!
KConfig.projbuild
^^^^^^^^^^^^^^^^^
这相当于 ``Makefile.projbuild`` 的组件配置 KConfig 文件,如果要在 menuconfig 的顶层添加配置选项,而不是在 ``组件配置`` 子菜单中,则可以在 ``component.mk`` 文件所在目录中的 KConfig.projbuild 文件中定义这些选项。
在此文件中添加配置时要小心,因为他们将包含在整个项目配置中,在可能的情况下,通常最好为组件创建和配置 KConfig 文件。
Makefile.componentbuild
^^^^^^^^^^^^^^^^^^^^^^^
对于一些特殊的组件,比如它们会使用工具从其余文件中生成源文件,这时就有必要将配置、宏或者变量的定义添加到每个组件的构建过程中。这是通过在组件目录中包含 ``Makefile.componentbuild`` 文件来实现的。此文件在 ``component.mk`` 文件之前被导入 ``component_wrapper.mk`` 中。同 ``Makefile.projbuild`` 文件一样,请留意这些文件,因为他们包含在每个组件的构建中,所有只有在编译完全不同的组件时才会出现 ``Makefile.componentbuild`` 错误。
仅配置的组件
^^^^^^^^^^^^
仅配置的组件是一类不包含源文件的特殊组件,只有 ``Kconfig.projbuild````Makefile.projbuild`` 文件,可以在 ``conponent.mk`` 文件中设置标志 ``COMPONENT_CONFIG_ONLY``。如果设置了此标志,则忽略大多数其他组件变量,并且不会为组件执行构建操作。
.. _example-component-makefile-legacy:
组件 Makefile 示例
~~~~~~~~~~~~~~~~~~
因为构建环境试图设置大多数情况都能工作的合理默认值,所以 ``component.mk`` 可能非常小,甚至是空的,请参考 `最小组件 Makefile <#minimal-component-makefile>`_。但是某些功能通常需要覆盖组件的变量。
以下是 ``component.mk`` 的一些更高级的示例:
增加源文件目录
^^^^^^^^^^^^^^
默认情况下,将忽略子目录。如果您的项目在子目录中而不是在组件的根目录中有源文件,那么您可以通过设置 ``COMPONENT_SRCDIRS`` 将其告知构建系统:
.. code::
COMPONENT_SRCDIRS := src1 src2
构建系统将会编译 src1/ 和 src2/ 子目录中的所有源文件。
.. _specify-source-files-legacy:
指定源文件
^^^^^^^^^^
标准 ``component.mk`` 逻辑将源目录中的所有 .S 和 .c 文件添加为无条件编译的源。通过将 ``COMPONENT_OBJS`` 变量手动设置为需要生成的对象的名称,可以绕过该逻辑并对要编译的对象进行硬编码::
COMPONENT_OBJS := file1.o file2.o thing/filea.o thing/fileb.o anotherthing/main.o
COMPONENT_SRCDIRS := . thing anotherthing
请注意,还需要另外设置 ``COMPONENT_SRCDIRS``
.. _add-conditional-configuration-legacy:
添加条件配置
^^^^^^^^^^^^
配置系统可用于有条件地编译某些文件,具体取决于 ``make menuconfig`` 中选择的选项。为此ESP-IDF 具有 ``compile_only_if````compile_only_if_not`` 的宏:
``Kconfig``::
config FOO_ENABLE_BAR
bool "Enable the BAR feature."
help
This enables the BAR feature of the FOO component.
``component.mk``::
$(call compile_only_if,$(CONFIG_FOO_ENABLE_BAR),bar.o)
从示例中可以看出, ``compile_only_if`` 宏将条件和目标文件列表作为参数。如果条件为真(在这种情况下:如果在 menuconfig 中启用了 BAR 功能),将始终编译目标文件(在本例中为 bar.o。相反的情况也是如此如果条件不成立bar.o 将永远不会被编译。 ``compile_only_if_not`` 执行相反的操作,如果条件为 false 则编译,如果条件为 true 则不编译。
这也可以用于选择或者删除实现,如下所示:
``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
``component.mk``::
# 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
$(call compile_only_if,$(or $(CONFIG_ENABLE_LCD_CONSOLE),$(CONFIG_ENABLE_LCD_PLOT)), font.o)
请注意使用 Make 或者函数来包含字体文件。其他的替换函数,比如 ``and````if`` 也适用于此处。也可以使用不在 menuconfig 中定义的变量ESP-IDF 使用默认的 Make 策略,判断一个空的或只包含空格的变量视为 false而其中任何非空格的变量都为 true 。
(注意:本文档的历史版本建议将目标文件添加到 ``COMPONENT_OBJS`` 中,虽然这仍然可行,但是只有当组件中的所有目标文件都明确命名时才会起作用,并且在 ``make clean`` 后并不会清除 make 中取消选择的目标文件)。
.. _source-code-generation-legacy:
源代码生成
^^^^^^^^^^
某些组件会出现源文件未随组件本身提供,而必须从另外一个文件生成的情况。假设我们的组件有一个头文件,该文件由 BMP 文件转换后的二进制数据组成,假设使用 bmp2h 的工具进行转换,然后将头文件包含在名为 graphics_lib.c 的文件中::
COMPONENT_EXTRA_CLEAN := logo.h
graphics_lib.o: logo.h
logo.h: $(COMPONENT_PATH)/logo.bmp
bmp2h -i $^ -o $@
这个示例会在当前目录(构建目录)中生成 graphics_lib.o 和 logo.h 文件,而 logo.bmp 随组件一起提供并位于组件路径下。因为 logo.h 是一个生成的文件,所以当调用 ``make clean`` 时需要清理它,这就是为什么要将它添加到 ``COMPONENT_EXTRA_CLEAN`` 变量中。
润色与改进
^^^^^^^^^^
将 logo.h 添加作为 ``graphics_lib.o`` 的依赖项会导致在编译 ``graphics_lib.c`` 之前先生成它。
如果另一个组件中的源文件需要使用 logo.h则必须将此组件的名称添加到另一个组件的 ``COMPONENT_DEPENDS`` 列表中,以确保组件按顺序编译。
嵌入二进制数据
^^^^^^^^^^^^^^
有时您的组件希望使用一个二进制文件或者文本文件,但是您又不希望将它重新格式化为 C 源文件。
这时,您可以在 ``component.mk`` 文件中设置变量 ``COMPONENT_EMBED_FILES``,以这种方式指定要嵌入的文件的名称::
COMPONENT_EMBED_FILES := server_root_cert.der
或者,如果文件是字符串,则可以使用变量 ``COMPONENT_EMBED_TXTFILES``,这将把文本文件的内容当成以 null 结尾的字符串嵌入::
COMPONENT_EMBED_TXTFILES := server_root_cert.pem
文件的内容会被编译进 flash 中的 .rodata 段,并通过符号名称来访问,如下所示::
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");
符号名称是根据文件的全名生成的,如 ``COMPONENT_EMBED_FILES`` 中的所示,字符 / . 等都将会被下划线替代。符号名称中的 ``_binary`` 前缀由 ``objcopy`` 添加,对于文本和二进制文件都是相同的。
有关使用此技术的示例,请查看 file_serving 示例 :example_file:`protocols/http_server/file_serving/main/CMakeLists.txt` 中的 main 组件,两个文件会在编译时加载并链接到固件中。
代码和数据的存放
----------------
ESP-IDF 还支持自动生成链接脚本,它允许组件通过链接片段文件定义其代码和数据在内存中的存放位置。构建系统会处理这些链接片段文件,并将处理后的结果扩充进链接脚本,从而指导应用程序二进制文件的链接过程。更多详细信息与快速上手指南,请参阅 :doc:`链接脚本生成机制 <linker-script-generation>`
.. _fully-overriding-component-makefile:
完全覆盖组件的 Makefile
~~~~~~~~~~~~~~~~~~~~~~~
显然,在某些情况下,所有这些配置都不足以满足某个组件,例如,当组件基本上是另一个第三方组件的包装器时,该第三方组件最初不打算在 ESP-IDF 构建系统下工作,在这种情况下,可以通过设置 ``COMPONENT_OWNBUILDTARGET`` 和可能的 ``COMPONENT_OWNCLEANTARGET``,并在 ``component.mk`` 中定义名为 ``build````clean`` 的目标。构建目标可以执行任何操作,只要它为项目生成了 ``$(COMPONENT_LIBRARY)`` ,并最终被链接到应用程序二进制文件中即可。
(实际上,这并不是必须的 - 如果 ``COMPONENT_ADD_LDFLAGS`` 变量被覆盖,那么组件可以指示链接器链接其他二进制文件。)
.. note:: 当外部构建系统使用 PSRAM 时,请记得将 ``-mfix-esp32-psram-cache-issue`` 添加到 C 编译器的参数中。关于该标志的更多详细信息,请参考 :ref:`CONFIG_SPIRAM_CACHE_WORKAROUND`
.. _esp-idf-template: https://github.com/espressif/esp-idf-template
.. _GNU Make Manual: https://www.gnu.org/software/make/manual/make.html
.. _custom-sdkconfig-defaults-legacy:
自定义 sdkconfig 的默认值
~~~~~~~~~~~~~~~~~~~~~~~~~
对于示例工程或者其他您不想指定完整 sdkconfig 配置的项目,但是您确实希望覆盖 ESP-IDF 默认值中的某些键值,则可以在项目中创建文件 ``sdkconfig.defaults``,运行 ``make defconfig`` 或从头创建新配置时将会使用此文件。
要想覆盖此文件的名称,请设置 ``SDKCONFIG_DEFAULTS`` 环境变量。
保存 flash 参数
~~~~~~~~~~~~~~~
在某些情况下,我们希望在没有 IDF 的情况下烧写目标板对于这种情况我们希望保存构建的二进制文件、esptool.py 和 esptool write_flash 命令的参数。可以简单编写一段脚本来保存二进制文件和 esptool.py并且使用命令 ``make print_flash_cmd`` 来查看烧写 flash 时的参数::
--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 参数作为 esptool write_flash 命令的参数::
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
构建 Bootloader
---------------
引导程序默认作为 ``make all`` 的一部分被构建,或者也可以通过 ``make bootloader-clean`` 来单独构建,此外还可以通过 ``make bootloader-list-components`` 来查看构建引导程序时包含的组件。
引导程序是一个特殊的组件,因为主项目中的二级引导程序拥有单独的 .EFL 和 .BIN 文件。但是它与主项目共享配置和构建目录。
这是通过在 components/bootloader/subproject 下添加子项目来完成的。这个子项目有自己的 Makefile但它希望通过 components/bootloader/Makefile.projectbuild 文件中的一些配置使自己从主项目的 Makefile 被调用。有关详细信息,请参阅这些文件。

View File

@ -5,10 +5,6 @@
本文档主要介绍 ESP-IDF 构建系统的实现原理以及 ``组件`` 等相关概念。如需您想了解如何组织和构建新的 ESP-IDF 项目或组件,请阅读本文档。
.. only:: esp32
.. 注解:: 本文档将介绍基于 CMake 的构建系统,它是 ESP-IDF V4.0 及以上版本的默认系统。此外 ESP-IDF 还支持 :doc:`基于 GNU Make 的构建系统 <build-system-legacy>`,基于 GNU Make 的构建系统是 ESP-IDF V4.0 以下版本的默认系统。
概述
====
@ -1546,30 +1542,13 @@ ESP-IDF 构建系统的列表文件位于 :idf:`/tools/cmake` 中。实现构建
请参考 :idf_file:`/tools/cmake/project.cmake` 获取更多信息。
.. _migrating_from_make:
从 ESP-IDF GNU Make 构建系统迁移到 CMake 构建系统
=================================================
ESP-IDF CMake 构建系统与旧版的 GNU Make 构建系统在某些方面非常相似,开发者都需要提供 include 目录、源文件等。然而,有一个语法上的区别,即对于 ESP-IDF CMake 构建系统,开发者需要将这些作为参数传递给注册命令 ``idf_component_register``
自动转换工具
------------
.. highlight:: bash
:idf_file:`/tools/cmake/convert_to_cmake.py` 中提供了一个项目自动转换工具。运行此命令时需要加上项目路径,如下所示::
$IDF_PATH/tools/cmake/convert_to_cmake.py /path/to/project_dir
项目目录必须包含 Makefile 文件,并确保主机已安装 GNU Make (``make``) 工具,并且被添加到了 PATH 环境变量中。
该工具会将项目 Makefile 文件和所有组件的 ``component.mk`` 文件转换为对应的 ``CMakeLists.txt`` 文件。
转换过程如下:该工具首先运行 ``make`` 来展开 ESP-IDF 构建系统设置的变量,然后创建相应的 CMakelists 文件来设置相同的变量。
.. important:: 当转换工具转换一个 ``component.mk`` 文件时,它并不能确定该组件依赖于哪些其他组件。这些信息需要通过编辑新的组件 ``CMakeLists.txt`` 文件并添加 ``REQUIRES`` 和/或 ``PRIV_REQUIRES`` 子句来手动添加。否则,组件中的源文件会因为找不到其他组件的头文件而编译失败。请参考 :ref:`component requirements` 获取更多信息。
转换工具并不能处理复杂的 Makefile 逻辑或异常的目标,这些需要手动转换。
CMake 中不可用的功能
--------------------

View File

@ -10,7 +10,6 @@ API 指南
:SOC_BT_SUPPORTED: BluFi <blufi>
引导加载程序 <bootloader>
构建系统 <build-system>
:esp32: 构建系统 (传统 GNU Make) <build-system-legacy>
深度睡眠唤醒存根 <deep-sleep-stub>
:SOC_USB_OTG_SUPPORTED: 通过 USB 升级设备固件 <dfu>
错误处理 <error-handling>
@ -38,11 +37,9 @@ API 指南
线程本地存储 <thread-local-storage>
工具 <tools/index>
:SOC_ULP_SUPPORTED: ULP 协处理器 <ulp>
:esp32: ULP (传统 GNU Make) <ulp-legacy>
:esp32s2: ULP-RISC-V 协处理器 <ulp-risc-v>
单元测试 (Target) <unit-tests>
单元测试 (Linux Host) <linux-host-testing>
:esp32: 单元测试 (传统 GNU Make) <unit-tests-legacy>
:SOC_USB_OTG_SUPPORTED: USB 控制台 <usb-otg-console>
:SOC_USB_SERIAL_JTAG_SUPPORTED: USB Serial/JTAG Controller Console <usb-serial-jtag-console>
Wi-Fi 驱动 <wifi>

View File

@ -45,18 +45,6 @@
首先,用户需要创建链接器片段文件。链接器片段文件是一个扩展名为 ``.lf`` 的文本文件想要存放的位置信息会写入该文件内。文件创建成功后需要将其呈现在构建系统中。ESP-IDF 支持的构建系统指南如下:
Make
""""
在组件目录的 ``component.mk`` 文件中设置 ``COMPONENT_ADD_LDFRAGMENTS`` 变量的值,使其指向已创建的链接器片段文件。路径可以为绝对路径,也可以为组件目录的相对路径。
.. code-block:: make
COMPONENT_ADD_LDFRAGMENTS += my_linker_fragment_file.lf
CMake
"""""
在组件目录的 ``CMakeLists.txt`` 文件中,指定 ``idf_component_register`` 调用引数 ``LDFRAGMENTS`` 的值。``LDFRAGMENTS`` 可以为绝对路径,也可为组件目录的相对路径,指向已创建的链接器片段文件。
.. code-block:: cmake

View File

@ -183,10 +183,6 @@ ESP-IDF 构建系统将自动检查生成的二进制文件大小与可用的分
即使分区大小检查返回错误并导致构建失败,仍然会生成可以烧录的二进制文件(它们对于可用空间来说过大,因此无法正常工作)。
.. note::
只有在使用 CMake 构建系统时才会对构建系统二进制文件大小进行检查。如果使用传统的 GNU Make 构建系统时,则可以手动检查文件大小,或在启动时会产生错误记录。
MD5 校验和
~~~~~~~~~~

View File

@ -6,10 +6,7 @@ IDF 监视器
IDF 监视器是一个串行终端程序用于收发目标设备串口的串行数据IDF 监视器同时还兼具 IDF 的其他特性。
在 IDF 中调用以下目标函数可以启用此监视器:
- **若使用 CMake 编译系统,则请调用**``idf.py monitor``
- **若使用传统 GNU Make 编译系统,请调用**``make monitor``
在 IDF 中调用 idf.py monitor 可以启用此监视器
操作快捷键
==================
@ -271,7 +268,7 @@ Windows 环境下已知问题
~~~~~~~~~~~~~~~~~~~~~~~~~~
- 由于 Windows 控制台限制,有些箭头键及其他一些特殊键无法在 GDB 中使用。
- 偶然情况下,``idf.py`` ``make`` 退出时,可能会在 IDF 监视器恢复之前暂停 30 秒。
- 偶然情况下,``idf.py`` 退出时,可能会在 IDF 监视器恢复之前暂停 30 秒。
- GDB 运行时,可能会暂停一段时间,然后才开始与 GDBStub 进行通信。
.. _addr2line: https://sourceware.org/binutils/docs/binutils/addr2line.html

View File

@ -1,165 +0,0 @@
ULP 协处理器 (传统的 GNU Make)
=================================
:link_to_translation:`en:[English]`
.. toctree::
:maxdepth: 1
指令集参考 <ulp_instruction_set>
使用宏进行编程(遗留)<ulp_macros>
.. include:: ../gnu-make-legacy.rst
ULPUltra Low Power 超低功耗)协处理器是一种简单的有限状态机 (FSM),可以在主处理器处于深度睡眠模式时,使用 ADC、温度传感器和外部 I2C 传感器执行测量操作。ULP 协处理器可以访问 RTC_SLOW_MEM 内存区域及 RTC_CNTL、RTC_IO、SARADC 等外设寄存器。ULP 协处理器使用 32 位固定宽度的指令32 位内存寻址,配备 4 个 16 位通用寄存器。
安装工具链
-----------
ULP 协处理器代码是用汇编语言编写的,并使用 `binutils-esp32ulp toolchain` 进行编译。
1. 从 https://github.com/espressif/binutils-esp32ulp/releases 网站下载预编译的最新版本工具链二进制文件。
2. 将工具链提取至目录中,向工具链的 ``bin/`` 目录中添加路径至 ``PATH`` 环境变量中。
编译 ULP 代码
--------------
若需要将 ULP 代码编译为某组件的一部分,则必须执行以下步骤:
1. 用汇编语言编写的 ULP 代码必须导入到一个或多个 `.S` 扩展文件中,且这些文件必须放在组件目录中一个独立的目录中,例如 `ulp/`
.. note: 该目录不要添加到 ``COMPONENT_SRCDIRS`` 环境变量中。因为 ESP-IDF 构建系统将基于文件扩展名编译在 ``COMPONENT_SRCDIRS`` 中搜索到的文件。对于 ``.S`` 文件,使用的是 ``xtensa-esp32-elf-as`` 汇编器。但这并不适用于 ULP 程序集文件,因此体现这种区别的最简单方法就是将 ULP 程序集文件放到单独的目录中。
2. 修改组件 makefile添加下列参数::
ULP_APP_NAME ?= ulp_$(COMPONENT_NAME)
ULP_S_SOURCES = $(COMPONENT_PATH)/ulp/ulp_source_file.S
ULP_EXP_DEP_OBJECTS := main.o
include $(IDF_PATH)/components/ulp/component_ulp_common.mk
代码解释如下:
ULP_APP_NAME
为生成的 ULP 应用程序命名,不带扩展名。此名称用于 ULP 应用程序的构建输出ELF 文件、map 文件、二进制文件、生成的头文件和链接器导出文件。
ULP_S_SOURCES
设置要传递给 ULP 汇编器的程序集文件列表。列表中的路径须是绝对路径,即以 ``$(COMPONENT_PATH)`` 开头的路径。如果列表中需列出多个文件,可使用函数 ``$(addprefix)``。因为路径与组件构建目录相关,因而不需前置。
ULP_EXP_DEP_OBJECTS
设置组件中目标文件名称的列表其中包含生成的头文件。此列表用以建立正确的依赖项并确保在此类文件被编译前生成头文件。ULP 应用程序头文件的定义请见下文。
include $(IDF_PATH)/components/ulp/component_ulp_common.mk
包含常见的 ULP 编译步骤。为 ULP 目标文件、ELF 文件、二进制文件等定义编译目标。
3. 使用常规方法(例如 ``idf.py build````idf.py app``)编译应用程序
在编译过程中,构建系统将按照以下步骤编译 ULP 程序:
1. **通过 C 预处理器运行每个程序集文件 (foo.S)。** 此步骤在组件编译目录中生成预处理的程序集文件 (foo.ulp.pS),同时生成依赖文件 (foo.ulp.d)。
2. **通过汇编器运行预处理过的汇编源码。** 此步骤会生成目标文件 (foo.ulp.o) 和清单文件 (foo.ulp.lst)。生成的清单文件用于调试,不用于构建过程的后续步骤。
3. **通过 C 预处理器运行链接器脚本模板。** 模版位于 components/ulp/ld 目录中。
4. **将目标文件链接到 ELF 输出文件** (ulp_app_name.elf)。此步骤生成的 .map 文件 (ulp_app_name.map) 可能会用于调试。
5. **将 ELF 文件中的内容转储为二进制文件** (ulp_app_name.bin),以便嵌入到应用程序中。
6. **使用 esp32ulp-elf-nm 在 ELF 文件中生成全局符号列表** (ulp_app_name.sym)。
7. **创建 LD 导出脚本和头文件** (ulp_app_name.ld 和 ulp_app_name.h),包含来自 ulp_app_name.sym 的符号。此步骤通过 esp32ulp_mapgen.py 工具来完成。
8. **将生成的二进制文件添加到要嵌入应用程序的二进制文件列表中。**
访问 ULP 程序变量
------------------
在 ULP 程序中定义的全局符号也可以在主程序中使用。
例如ULP 程序可以定义 ``measurement_count`` 变量,此变量规定了芯片从深度睡眠模式唤醒之前,程序需要进行 ADC 测量的次数::
.global measurement_count
measurement_count: .long 0
/* later, use measurement_count */
move r3, measurement_count
ld r3, r3, 0
主程序需要在启动 ULP 程序之前初始化 ``measurement_count`` 变量,构建系统通过生成定义 ULP 程序中全局符号的 ``$(ULP_APP_NAME).h````$(ULP_APP_NAME).ld`` 文件,可以实现上述操作;这些文件包含了 ULP 程序中所有全局符号,文件名以 ``ulp_`` 开头。
头文件包含对此类符号的声明::
extern uint32_t ulp_measurement_count;
注意,所有符号(包括变量、数组、函数)均被声明为 ``uint32_t``。对于函数和数组,先获取符号地址,然后转换为适当的类型。
生成的链接器脚本文件定义了符号在 RTC_SLOW_MEM 中的位置::
PROVIDE ( ulp_measurement_count = 0x50000060 );
如果要从主程序访问 ULP 程序变量,应先使用 ``include`` 语句包含生成的头文件,这样,就可以像访问常规变量一样访问 ulp 程序变量。操作如下::
#include "ulp_app_name.h"
// later
void init_ulp_vars() {
ulp_measurement_count = 64;
}
注意ULP 程序只能使用 RTC 内存中 32 位字的低 16 位,因为寄存器是 16 位的,并且不存在从字的高位加载的指令。
同样ULP 储存指令将寄存器值写入 32 位字的低 16 位中。写入高 16 位的值取决于存储指令的地址,因此在读取 ULP 写的变量时,主应用程序需要屏蔽高 16 位,例如::
printf("Last measurement value: %d\n", ulp_last_measurement & UINT16_MAX);
启动 ULP 程序
---------------
要运行 ULP 程序,主应用程序需要调用 ``ulp_load_binary`` 函数将 ULP 程序加载到 RTC 内存中,然后调用 ``ulp_run`` 函数,启动 ULP 程序。
注意,在 menuconfig 中必须启用 "Enable Ultra Low Power (ULP) Coprocessor" 选项,以便为 ULP 预留内存。"RTC slow memory reserved for coprocessor" 选项设置的值必须足够储存 ULP 代码和数据。如果应用程序组件包含多个 ULP 程序,则 RTC 内存必须足以容纳最大的程序。
每个 ULP 程序均以二进制 BLOB 的形式嵌入到 ESP-IDF 应用程序中。应用程序可以引用此 BLOB并以下面的方式加载此 BLOB (假设 ULP_APP_NAME 已被定义为 ``ulp_app_name``::
extern const uint8_t bin_start[] asm("_binary_ulp_app_name_bin_start");
extern const uint8_t bin_end[] asm("_binary_ulp_app_name_bin_end");
void start_ulp_program() {
ESP_ERROR_CHECK( ulp_load_binary(
0 /* load address, set to 0 when using default linker scripts */,
bin_start,
(bin_end - bin_start) / sizeof(uint32_t)) );
}
.. doxygenfunction:: ulp_load_binary
一旦上述程序加载到 RTC 内存后,应用程序即可启动此程序,并将入口点的地址传递给 ``ulp_run`` 函数::
ESP_ERROR_CHECK( ulp_run(&ulp_entry - RTC_SLOW_MEM) );
.. doxygenfunction:: ulp_run
上述生成的头文件 ``$(ULP_APP_NAME).h`` 声明了入口点符号。在 ULP 应用程序的汇编源代码中,此符号必须标记为 ``.global``::
.global entry
entry:
/* code starts here */
ULP 程序流
-----------
ULP 协处理器由定时器启动,而调用 ``ulp_run`` 则可启动此定时器。定时器为 RTC_SLOW_CLK 的 Tick 事件计数默认情况下Tick 由内部 150 kHz 晶振器生成)。使用 ``SENS_ULP_CP_SLEEP_CYCx_REG`` 寄存器 (x = 0..4) 设置 Tick 数值。第一次启动 ULP 时,使用 ``SENS_ULP_CP_SLEEP_CYC0_REG`` 设置定时器 Tick 数值之后ULP 程序可以使用 ``sleep`` 指令来另外选择 ``SENS_ULP_CP_SLEEP_CYCx_REG`` 寄存器。
此应用程序可以调用 ``ulp_set_wakeup_period`` 函数来设置 ULP 定时器周期值 (SENS_ULP_CP_SLEEP_CYCx_REG, x = 0..4)。
.. doxygenfunction:: ulp_set_wakeup_period
一旦定时器数值达到在所选的 ``SENS_ULP_CP_SLEEP_CYCx_REG`` 寄存器中设置的数值ULP 协处理器就会启动,并调用 ``ulp_run`` 的入口点,开始运行程序。
程序保持运行,直到遇到 ``halt`` 指令或非法指令才停止。一旦程序停止ULP 协处理器电源关闭,定时器再次启动。
如果想禁用定时器(禁用定时器可有效防止 ULP 程序再次运行),请清除 ``RTC_CNTL_STATE0_REG`` 寄存器中的 ``RTC_CNTL_ULP_CP_SLP_TIMER_EN`` 位,可在 ULP 代码或主程序中进行以上操作。
.. _binutils-esp32ulp toolchain: https://github.com/espressif/binutils-esp32ulp

View File

@ -20,10 +20,6 @@ ULP 协处理器代码是用汇编语言编写的,并使用 `binutils-esp32ulp
如果你已经按照 :doc:`快速入门指南 <../../get-started/index>` 中的介绍安装好了 ESP-IDF 及其 CMake 构建系统,那么 ULP 工具链已经被默认安装到了你的开发环境中。
.. only:: esp32
如果你的 ESP-IDF 仍在使用传统的基于 GNU Make 的构建系统,请参考 :doc:`ulp-legacy` 一文中的说明,完成工具链的安装。
编译 ULP 代码
-------------

View File

@ -1,253 +0,0 @@
单元测试(传统的 GNU Make
=====================================
:link_to_translation:`en:[English]`
.. include:: ../gnu-make-legacy.rst
ESP-IDF
中附带了一个基于 ``Unity`` 的单元测试应用程序框架,且所有的单元测试用例分别保存在
ESP-IDF 仓库中每个组件的 ``test`` 子目录中。
添加常规测试用例
----------------
单元测试被添加在相应组件的 ``test`` 子目录中,测试用例写在 C 文件中,一个
C 文件可以包含多个测试用例。测试文件的名字要以 “test” 开头。
测试文件需要包含 ``unity.h`` 头文件,此外还需要包含待测试 C
模块需要的头文件。
测试用例需要通过 C 文件中特定的函数来添加,如下所示:
.. code:: c
TEST_CASE("test name", "[module name]"
{
// 在这里添加测试用例
}
第一个参数是字符串,用来描述当前测试。第二个参数是字符串,用方括号中的标识符来表示,标识符用来对相关测试或具有特定属性的测试进行分组。
.. note::
没有必要在每个测试用例中使用 ``UNITY_BEGIN()````UNITY_END()``
来声明主函数的区域, ``unity_platform.c`` 会自动调用 ``UNITY_BEGIN()`` 然后运行测试用例,最后调用 ``UNITY_END()``
每一个 `测试` 子目录下都需包含
``component.mk`` 文件,并且其中至少要包含如下的一行代码::
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
更多关于如何在 Unity 下编写测试用例的信息,请查阅
http://www.throwtheswitch.org/unity 。
添加多设备测试用例
------------------
常规测试用例会在一个 DUTDevice Under Test在试设备上执行.但是,那些需要互相通信的组件(比如
GPIO、SPI需要与其通信的其他设备因此不能使用常规测试用例进行测试。多设备测试用例包括写入多个测试函数并在多个 DUT 进行运行测试。
以下是一个多设备测试用例:
.. code:: c
void gpio_master_test()
{
gpio_config_t slave_config = {
.pin_bit_mask = 1 << MASTER_GPIO_PIN,
.mode = GPIO_MODE_INPUT,
};
gpio_config(&slave_config);
unity_wait_for_signal("output high level");
TEST_ASSERT(gpio_get_level(MASTER_GPIO_PIN) == 1);
}
void gpio_slave_test()
{
gpio_config_t master_config = {
.pin_bit_mask = 1 << SLAVE_GPIO_PIN,
.mode = GPIO_MODE_OUTPUT,
};
gpio_config(&master_config);
gpio_set_level(SLAVE_GPIO_PIN, 1);
unity_send_signal("output high level");
}
TEST_CASE_MULTIPLE_DEVICES("gpio multiple devices test example", "[driver]", gpio_master_test, gpio_slave_test);
``TEST_CASE_MULTIPLE_DEVICES`` 用来声明多设备测试用例,
- 第一个参数指定测试用例的名字。
- 第二个参数是测试用例的描述。
- 从第三个参数开始可以指定最多5个测试函数每个函数都是单独运行在一个
DUT 上的测试入口点。
在不同的 DUT 上运行的测试用例,通常会要求它们之间进行同步。我们提供
``unity_wait_for_signal````unity_send_signal`` 这两个函数来使用 UART
去支持同步操作。如上例中的场景slave 应该在在 master 设置好 GPIO
电平后再去读取 GPIO 电平DUT 的 UART
终端会打印提示信息,并要求用户进行交互。
DUT1master终端
.. code::
Waiting for signal: [output high level]!
Please press "Enter" key once any board send this signal.
DUT2slave终端
.. code::
Send signal: [output high level]!
一旦 DUT2 发送了该信号,您需要在 DUT1 按回车键,然后 DUT1 会从
``unity_wait_for_signal`` 函数中解除阻塞,并开始更改 GPIO 的电平。
信号也可以用来在不同设备之间传递参数。例如DUT1 希望得到 DUT2 的 MAC 地址来进行蓝牙连接,
这时,可使用 ``unity_wait_for_signal_param`` 以及 ``unity_send_signal_param``
DUT1 终端::
Waiting for signal: [dut2 mac address]!
Please input parameter value from any board send this signal and press "Enter" key.
DUT2 终端::
Send signal: [dut2 mac address][10:20:30:40:50:60]!
一旦 DUT2 发送信号,您需要在 DUT1 输入 ``10:20:30:40:50:60`` 并按回车键,然后 DUT1 会获取 DUT2 的 MAC 地址字符串,并从 ``unity_wait_for_signal_param`` 函数中解除阻塞,然后蓝牙连接 DUT2。
添加多阶段测试用例
------------------
常规的测试用例无需重启就会结束(或者仅需要检查是否发生了重启),可有些时候我们想在某些特定类型的重启事件后运行指定的测试代码,例如,我们想在深度睡眠唤醒后检查复位的原因是否正确。首先我们需要出发深度睡眠复位事件,然后检查复位的原因。为了实现这一点,我们可以定义多阶段测试用例来将这些测试函数组合在一起。
.. code:: c
static void trigger_deepsleep(void)
{
esp_sleep_enable_timer_wakeup(2000);
esp_deep_sleep_start();
}
void check_deepsleep_reset_reason()
{
soc_reset_reason_t reason = esp_rom_get_reset_reason(0);
TEST_ASSERT(reason == RESET_REASON_CORE_DEEP_SLEEP);
}
TEST_CASE_MULTIPLE_STAGES("reset reason check for deepsleep", "[esp32]", trigger_deepsleep, check_deepsleep_reset_reason);
多阶段测试用例向用户呈现了一组测试函数,它需要用户进行交互(选择用例并选择不同的阶段)来运行。
编译单元测试程序
----------------
按照 esp-idf 顶层目录的 README 文件中的说明进行操作,请确保 ``IDF_PATH``
环境变量已经被设置指向了 esp-idf 的顶层目录。
切换到 ``tools/unit-test-app`` 目录下进行配置和编译:
- ``make menuconfig`` - 配置单元测试程序。
- ``make TESTS_ALL=1`` - 编译单元测试程序,测试每个组件 ``test``
子目录下的用例。
- ``make TEST_COMPONENTS='xxx'`` - 编译单元测试程序,测试指定的组件。
- ``make TESTS_ALL=1 TEST_EXCLUDE_COMPONENTS='xxx'`` -
编译单元测试程序,测试所有(除开指定)的组件。(例如
``make TESTS_ALL=1 TEST_EXCLUDE_COMPONENTS='ulp mbedtls'`` -
编译所有的单元测试,不包括 ``ulp````mbedtls`` 组件。)
当编译完成时,它会打印出烧写芯片的指令。您只需要运行 ``make flash``
即可烧写所有编译输出的文件。
您还可以运行 ``make flash TESTS_ALL=1`` 或者
``make TEST_COMPONENTS='xxx'``
来编译并烧写,所有需要的文件都会在烧写之前自动重新编译。
使用 ``menuconfig`` 可以设置烧写测试程序所使用的串口。
运行单元测试
------------
烧写完成后重启 ESP32 它将启动单元测试程序。
当单元测试应用程序空闲时,输入回车键,它会打印出测试菜单,其中包含所有的测试项目。
.. code::
Here's the test menu, pick your combo:
(1) "esp_ota_begin() verifies arguments" [ota]
(2) "esp_ota_get_next_update_partition logic" [ota]
(3) "Verify bootloader image in flash" [bootloader_support]
(4) "Verify unit test app image" [bootloader_support]
(5) "can use new and delete" [cxx]
(6) "can call virtual functions" [cxx]
(7) "can use static initializers for non-POD types" [cxx]
(8) "can use std::vector" [cxx]
(9) "static initialization guards work as expected" [cxx]
(10) "global initializers run in the correct order" [cxx]
(11) "before scheduler has started, static initializers work correctly" [cxx]
(12) "adc2 work with wifi" [adc]
(13) "gpio master/slave test example" [ignore][misc][test_env=UT_T2_1][multi_device]
(1) "gpio_master_test"
(2) "gpio_slave_test"
(14) "SPI Master clockdiv calculation routines" [spi]
(15) "SPI Master test" [spi][ignore]
(16) "SPI Master test, interaction of multiple devs" [spi][ignore]
(17) "SPI Master no response when switch from host1 (SPI2) to host2 (SPI3)" [spi]
(18) "SPI Master DMA test, TX and RX in different regions" [spi]
(19) "SPI Master DMA test: length, start, not aligned" [spi]
(20) "reset reason check for deepsleep" [esp32][test_env=UT_T2_1][multi_stage]
(1) "trigger_deepsleep"
(2) "check_deepsleep_reset_reason"
常规测试用例会打印用例名字和描述,主从测试用例还会打印子菜单(已注册的测试函数的名字)。
可以输入以下任意一项来运行测试用例:
- 引号中的测试用例的名字(例如 ``"esp_ota_begin() verifies arguments"``),运行单个测试用例。
- 测试用例的序号(例如 ``1``),运行单个测试用例。
- 方括号中的模组名称(例如 ``[cxx]``),运行指定模组的所有的测试用例。
- 星号 (``*``),运行所有测试用例。
``[multi_device]````[multi_stage]``
标签告诉测试运行者该用例是多设备测试还是多阶段测试。这些标签由
``TEST_CASE_MULTIPLE_STAGES````TEST_CASE_MULTIPLE_DEVICES``
宏自动生成。
一旦选择了多设备测试用例,它会打印一个子菜单:
.. code::
Running gpio master/slave test example...
gpio master/slave test example
(1) "gpio_master_test"
(2) "gpio_slave_test"
您需要输入数字以选择在 DUT 上运行的测试。
与多设备测试用例相似,多阶段测试用例也会打印子菜单:
.. code::
Running reset reason check for deepsleep...
reset reason check for deepsleep
(1) "trigger_deepsleep"
(2) "check_deepsleep_reset_reason"
第一次执行此用例时,输入 ``1`` 来运行第一阶段(触发深度睡眠)。在重启
DUT 并再次选择运行此用例后,输入 ``2``
来运行第二阶段。只有在最后一个阶段通过并且之前所有的阶段都成功触发了复位的情况下,该测试才算通过。

View File

@ -42,49 +42,21 @@ spiffsgen.py
镜像生成后,用户可以使用 ``esptool.py````parttool.py`` 烧录镜像。
用户可以在命令行或脚本中手动单独调用 ``spiffsgen.py``,也可以直接从构建系统调用 ``spiffs_create_partition_image`` 来使用 ``spiffsgen.py``
在 Make 构建系统中运行::
SPIFFS_IMAGE_FLASH_IN_PROJECT := ...
SPIFFS_IMAGE_DEPENDS := ...
$(eval $(call spiffs_create_partition_image,<partition>,<base_dir>))
在 CMake 构建系统中运行::
用户可以在命令行或脚本中手动单独调用 ``spiffsgen.py``,也可以直接从构建系统调用 ``spiffs_create_partition_image`` 来使用 ``spiffsgen.py``::
spiffs_create_partition_image(<partition> <base_dir> [FLASH_IN_PROJECT] [DEPENDS dep dep dep...])
在构建系统中使用 ``spiffsgen.py`` 更为方便,构建配置会自动传递给 ``spiffsgen.py`` 工具,确保生成的镜像可用于构建。比如,单独调用 ``spiffsgen.py`` 时需要用到 *image_size* 参数,但在构建系统中调用 ``spiffs_create_partition_image`` 时,仅需要 *partition* 参数,镜像大小将直接从工程分区表中获取。
Make 构建系统和 CMake 构建系统结构有所不同,请注意以下几点:
使用 ``spiffs_create_partition_image``,必须从组件 CMakeLists.txt 文件调用。
- 在 Make 构建系统中使用 ``spiffs_create_partition_image``,需从工程 Makefile 中调用;
- 在 CMake 构建系统中使用 ``spiffs_create_partition_image``,需从组件 CMakeLists.txt 文件调用。
用户也可以指定 ``FLASH_IN_PROJECT``,然后使用 ``idf.py flash````make flash`` 将镜像与应用程序二进制文件、分区表等一起自动烧录至设备,例如:
在 Make 构建系统中运行::
SPIFFS_IMAGE_FLASH_IN_PROJECT := 1
$(eval $(call spiffs_create_partition_image,<partition>,<base_dir>))
在 CMake 构建系统中运行::
用户也可以指定 ``FLASH_IN_PROJECT``,然后使用 ``idf.py flash`` 将镜像与应用程序二进制文件、分区表等一起自动烧录至设备,例如::
spiffs_create_partition_image(my_spiffs_partition my_folder FLASH_IN_PROJECT)
不指定 FLASH_IN_PROJECT/SPIFFS_IMAGE_FLASH_IN_PROJECT 也可以生成镜像,但须使用 ``esptool.py````parttool.py`` 或自定义构建系统目标手动烧录。
有时基本目录中的内容是在构建时生成的,用户可以使用 DEPENDS/SPIFFS_IMAGE_DEPENDS 指定目标,因此可以在生成镜像之前执行此目标。
在 Make 构建系统中运行::
dep:
...
SPIFFS_IMAGE_DEPENDS := dep
$(eval $(call spiffs_create_partition_image,<partition>,<base_dir>))
在 CMake 构建系统中运行::
有时基本目录中的内容是在构建时生成的,用户可以使用 DEPENDS/SPIFFS_IMAGE_DEPENDS 指定目标,因此可以在生成镜像之前执行此目标::
add_custom_target(dep COMMAND ...)
@ -138,7 +110,6 @@ mkspiffs
:example:`storage/spiffs` 目录下提供了 SPIFFS 应用示例。该示例初始化并挂载了一个 SPIFFS 分区,然后使用 POSIX 和 C 库 API 写入和读取数据。请参考 ``example`` 目录下的 README.md 文件,获取详细信息。
高级 API 参考
------------------------

View File

@ -23,7 +23,7 @@
提交一个新的示例项目之前,需要检查以下内容:
- 示例项目的名字(包括 ``Makefile````README.md`` 中)应使用 ``example``,而不要写 “demo”“test” 等词汇。
- 示例项目的名字(包括 ``README.md`` 中)应使用 ``example``,而不要写 “demo”“test” 等词汇。
- 每个示例项目只能有一个主要功能。如果某个示例项目有多个主要功能,请将其拆分为两个或更多示例项目。
- 每个示例项目应包含一个 ``README.md`` 文件,建议使用 :idf_file:`示例项目 README 模板 <docs/TEMPLATE_EXAMPLE_README.md>`
- 示例项目中的函数和变量的命令要遵循 :ref:`命名规范 <style-guide-naming>` 中的要求。对于仅在示例项目源文件中使用的非静态变量/函数,请使用 ``example`` 或其他类似的前缀。

View File

@ -1,65 +0,0 @@
在用户配置文件中添加 IDF_PATH传统 GNU Make
==============================================
:link_to_translation:`en:[English]`
.. include:: ../gnu-make-legacy.rst
为了在系统多次启动时,保留 ``IDF_PATH`` 环境变量的设置,请按照以下说明将该变量的设置增加至用户配置文件。
.. _add-idf_path-to-profile-windows-legacy:
Windows 操作系统
-----------------
用户配置文件脚本保存在 ``C:/msys32/etc/profile.d/`` 路径下,每次打开 MSYS2 窗口时均会执行。
#. 在 ``C:/msys32/etc/profile.d/`` 目录下创建一个新的脚本文件,并将其命名为 ``export_idf_path.sh``
#. 指定您的 ESP-IDF 保存路径,这通常与您的系统配置有关,比如 ``C:\msys32\home\user-name\esp\esp-idf``
#. 在脚本文件中加入下方 ``export`` 命令行,例::
export IDF_PATH="C:/msys32/home/user-name/esp/esp-idf"
注意请将反斜杠替换为 Windows 操作系统路径要求的正斜杠。
#. 保存脚本文件。
#. 关闭 MSYS2 窗口,并重新打开。运行以下命令,检查 ``IDF_PATH`` 是否成功设置::
printenv IDF_PATH
如果设置成功,则此时将打印之前在脚本中输入的路径。
如果您不希望永久设置 ``IDF_PATH`` 变量,也可以在每次打开 MSYS2 窗口时进行手动设置::
export IDF_PATH="C:/msys32/home/user-name/esp/esp-idf"
如果您是在安装 ESP32 软件的过程中从 :ref:`get-started-setup-path-legacy` 章节跳转至此,请返回 :ref:`get-started-start-project-legacy` 章节。
.. _add-idf_path-to-profile-linux-macos-legacy:
Linux 和 MacOS 操作系统
-------------------------
``~/.profile`` 文件中增加以下命令,设置 ``IDF_PATH`` 变量::
export IDF_PATH=~/esp/esp-idf
退出并重新登陆,检查设置是否生效。
.. note::
如果您已将 ``/bin/bash`` 设置为登录 shell且同时存在 ``.bash_profile````.profile``,则请更新 ``.bash_profile``
运行以下命令,检查 ``IDF_PATH`` 是否成功设置::
printenv IDF_PATH
如果设置成功,则此时将打印之前在 ``~/.profile`` 文件中输入(或手动设置)的路径。
如果您不希望永久设置 ``IDF_PATH`` 变量,也可以在每次重新打开终端窗口时进行手动设置::
export IDF_PATH=~/esp/esp-idf
如果您是在安装 ESP32 软件的过程中从 :ref:`get-started-setup-path-legacy` 章节跳转至此,请返回 :ref:`get-started-start-project-legacy` 章节。

View File

@ -1,110 +0,0 @@
**********************************************
Eclipse IDE 的创建和烧录指南(传统 GNU Make
**********************************************
:link_to_translation:`en:[English]`
.. include:: ../gnu-make-legacy.rst
.. _eclipse-install-steps-legacy:
安装 Eclipse IDE
================
Eclipse IDE 是一个可视化的集成开发环境,可用于编写、编译和调试 ESP-IDF 项目。
* 首先,请在您的平台上安装相应的 ESP-IDF具体步骤请按照您的操作系统Windows、OS X 和 Linux对应的指示进行安装。
* 我们建议,您可以首先使用命令行创建一个项目,大致熟悉项目的创建流程。此外,您还需要使用命令行 (``make menuconfig``) 对您的 ESP-IDF 项目进行配置。目前Eclipse 还无法配置 ESP-IDF 项目。
* 从 eclipse.org_ 下载对应操作系统的 Eclipse 安装器。
* 运行 Eclipse Installer选择 **"Eclipse for C/C++ Development"** (有的版本也可能显示为 CDT
配置 Eclipse
==============
打开安装好的 Eclipse IDE并按照以下步骤进行操作
导入新项目
----------
* Eclipse 需使用 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 所在的完整安装路径。Windows 用户可以从 Windows 浏览器复制 ``IDF_PATH``
* 编辑 ``PATH`` 环境变量。保留当前值,并将该路径增加至 Xtensa 工具链安装路径后,作为 IDF 设置的一部分(如已增加至 PATH则可忽略。工具链的常见路径为 ``/home/user-name/esp/xtensa-esp32-elf/bin`` (例)。注意,您需要在补充的路径前增加一个冒号(`:`。Windows 用户需要将 ``PATH`` 环境变量前增加 ``C:\msys32\mingw32\bin;C:\msys32\opt\xtensa-esp32-elf\bin;C:\msys32\usr\bin``。注意,请根据 msys32 的具体安装路径,修改 ``PATH`` 环境变量。
* MacOS 用户需要增加一个 ``PYTHONPATH`` 环境变量,并将其设置为 ``/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages``。保证系统中预先安装的 Python (需安装 pyserial 模块)可以覆盖 Eclipse 内置的任何 Python。
**特别说明**:如果您的 IDF_PATH 或项目不在 ``C:\msys32\home`` 之下,则应使用自定义编译命令:``python ${IDF_PATH}/tools/windows/eclipse_make.py`` (请注意,这种方法可能导致编译时间显著增加。)
* 前往 **"C/C++ General"** -> **"Preprocessor Include Paths"** 属性页面。点击 **"Providers"** 选项卡。
* 从 **"Providers"** 列表中选择 **"CDT Cross GCC Built-in Compiler Settings"**,将 **"Command to get compiler specs"** 修改为 ``xtensa-esp32-elf-gcc ${FLAGS} -std=c++11 -E -P -v -dD "${INPUTS}"``
* 从 **"Providers"** 列表中选择 **"CDT GCC Build Output Parser"**,将 **"Compiler command pattern"** 修改为 ``xtensa-esp32-elf-(gcc|g\+\+|c\+\+|cc|cpp|clang)``
* 前往 **“C/C++ General”** -> **“Indexer”** 属性页面。
* 勾选 **“Enable project specific settings”**,启用本页面上的其他设置。
* 取消勾选 **“Allow heuristic resolution of includes”**。勾选该选项有时会导致 Eclipse 无法找到正确的头文件目录。
* 前往 **“C/C++ Build”** -> **“Behavior”** 属性页面。
* 勾选 **“Enable parallel build”**,启用“并行编译”配置。
.. _eclipse-build-project-legacy:
在 Eclipse 中构建项目
-----------------------
在首次创建项目前Eclipse IDE 可能会显示大量有关未定义值的错误和警告,这是因为 ESP-IDF 在编译过程中会自动生成一些源文件。因此,这些错误和警告均会在项目编译完成后消失。
* 点击 **“OK”**,关闭 Eclipse IDE 中的 **“Properties”** 对话框。
* 在 Eclipse IDE 界面外,打开命令提示符窗口。进入项目目录,运行 ``make menuconfig`` 设置项目的 ESP-IDF 配置。现阶段,您还无法在 Eclipse 中完成本操作。
.. note:
如果您尝试跳过配置步骤直接开始编译ESP-IDF 将在命令行提示需完成配置,但 Eclipse 暂时无法处理这种情况,因此编译将挂起或失败。
* 回到 Eclipse IDE 界面,选择 **“Project”** -> **“Build”** 开始编译项目。
**小提示**:如果您的项目不是通过 Eclipse 创建的,则在选择 **“Project”** -> **“Build”** 前还需进行 **“Project”** -> **“Clean”** 操作。如此操作后Eclipse 才能查看所有源文件的编译器参数,并借此确定头文件包含路径。
在 Eclipse 中烧录项目
------------------------------------
您可以将 ``make flash`` 目标集成在 Eclipse 项目中,这样就可以通过 Eclipse UI 调用 ``esptool.py`` 进行烧录:
* 打开 **“Project Explorer”**,并右击您的项目(请注意右击项目本身,而非项目下的子文件,否则 Eclipse 可能会找到错误的 ``Makefile``)。
* 从菜单中选择 **“Build Targets”** -> **“Create...”**。
* 目标名称输入 “flash”其他选项使用默认值。
* 这时,您可以选择 **“Project”** -> **“Build Target”** -> **“Build”** (快捷键Shift + F9创建自定义烧录目标用于编译、烧录项目。
注意,您仍需要通过 ``make menuconfig`` 设置串行端口和其他烧录选项。``make menuconfig`` 仍需通过命令行操作(具体请见对应操作系统的指南)。
如有需要,请按照相同步骤添加 ``bootloader````partition_table`` 目标。
.. _eclipse.org: https://www.eclipse.org/

View File

@ -1,154 +0,0 @@
与 ESP32 创建串口连接(传统 GNU Make 系统)
================================================
:link_to_translation:`en:[English]`
.. include:: ../gnu-make-legacy.rst
本章节主要介绍如何创建 ESP32 和 PC 之间的串口连接。
连接 ESP32 和 PC
--------------------
用 USB 线将 ESP32 开发板连接到 PC。如果设备驱动程序没有自动安装请先确认 ESP32 开发板上的 USB 转串口芯片(或外部转串口适配器)型号,然后在网上搜索驱动程序,并进行手动安装。
以下是乐鑫 ESP32 等开发板驱动程序的链接:
.. csv-table::
:header: 开发板, USB 驱动, 备注
:widths: 40, 20, 40
ESP32-DevKitC, `CP210x`_
`ESP32-LyraT <https://www.espressif.com/en/products/hardware/esp32-lyrat>`_, `CP210x`_
`ESP32-LyraTD-MSC <https://www.espressif.com/en/products/hardware/esp32-lyratd-msc>`_, `CP210x`_
ESP32-PICO-KIT, `CP210x`_
ESP-WROVER-KIT, `FTDI`_
ESP32 Demo 板, `FTDI`_
`ESP-Prog`_, `FTDI`_, 编程板 (w/o ESP32)
`ESP32-MeshKit-Sense <https://github.com/espressif/esp-dev-kits/blob/master/esp32-meshkit-sensor/docs/ESP32-MeshKit-Sense_guide_cn.md>`_, n/a, 搭配 `ESP-Prog`_ 使用
`ESP32-Sense Kit <https://github.com/espressif/esp-dev-kits/blob/master/esp32-sense-kit/docs/esp32_sense_kit_guide_cn.md>`_, n/a, 搭配 `ESP-Prog`_ 使用
.. _CP210x: https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers
.. _FTDI: https://www.ftdichip.com/Drivers/VCP.htm
.. _ESP-Prog: https://github.com/espressif/esp-dev-kits/blob/master/esp-prog/docs/ESP-Prog_guide_cn.md
* CP210x: `CP210x USB to UART Bridge VCP Drivers <https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers>`_
* FTDI: `FTDI Virtual COM Port Drivers <https://www.ftdichip.com/Drivers/VCP.htm>`_
以上驱动仅用作参考。正常情况下,当上述任一 ESP32 开发板与 PC 连接时,打包在操作系统中的驱动程序将会开始自动安装。
查看端口Windows 用户)
---------------------------
检查 Windows 设备管理器中的 COM 端口列表。断开 ESP32 与 PC 的连接,然后重连。查看从列表中消失后再次出现的是哪个端口。
以下为 ESP32 DevKitC 和 ESP32 WROVER KIT 串口:
.. figure:: ../../_static/esp32-devkitc-in-device-manager.png
:align: center
:alt: Windows 设备管理器中 ESP32-DevKitC 的 USB 至 UART 桥
:figclass: align-center
Windows 设备管理器中 ESP32-DevKitC 的 USB 至 UART 桥
.. figure:: ../../_static/esp32-wrover-kit-in-device-manager.png
:align: center
:alt: Windows 设备管理器中 ESP-WROVER-KIT 的两个 USB 串行端口
:figclass: align-center
Windows 设备管理器中 ESP-WROVER-KIT 的两个 USB 串行端口
查看端口Linux 和 MacOS 用户)
----------------------------------
查看 ESP32 开发板(或外部转串口适配器)的串口设备名称,请运行两次下述命令。首先,断开开发板或适配器,第一次运行命令;然后,连接开发板或适配器,第二次运行命令。其中,第二次运行命令后出现的端口即是 ESP32 对应的串口:
Linux ::
ls /dev/tty*
MacOS ::
ls /dev/cu.*
.. _linux-dialout-group-legacy:
将用户增加至 Linux 的 ``dialout``
-------------------------------------
当前登录用户应当拥有通过 USB 对串口进行读写的权限。在多数 Linux 版本中,您都可以通过以下命令,将用户添加到 ``dialout`` 组,来获取读写权限::
sudo usermod -a -G dialout $USER
在 Arch Linux 中,需要通过以下命令将用户添加到 ``uucp`` 组中::
sudo usermod -a -G uucp $USER
请重新登录,确保串口读写权限可以生效。
确认串口连接
-------------
现在,请使用串口终端程序,验证串口连接是否可用。在本示例中,我们将使用 `PuTTY SSH Client <https://www.putty.org/>`_ 进行验证。该工具同时适用于 Windows 和 Linux 操作系统。您也可以使用其他串口程序,设置通信参数如下。
运行终端,配置串口:波特率 = 115200数据位 = 8停止位 = 1奇偶校验 = N。在 Windows 和 Linux 中配置串口和通信参数(如 115200-8-1-N的截图如下。注意这里一定要选择在上述步骤中确认的串口进行配置。
.. figure:: ../../_static/putty-settings-windows.png
:align: center
:alt: 在 Windows 操作系统中使用 PuTTY 设置串口通信参数
:figclass: align-center
在 Windows 操作系统中使用 PuTTY 设置串口通信参数
.. figure:: ../../_static/putty-settings-linux.png
:align: center
:alt: 在 Linux 操作系统中使用 PuTTY 设置串口通信参数
:figclass: align-center
在 Linux 操作系统中使用 PuTTY 设置串口通信参数
然后,请在终端打开串口,查看 ESP32 是否有任何打印,具体打印内容取决于加载至 ESP32 的程序。ESP32 打印示例
.. 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
...
如果打印出的日志是可读的(而不是乱码),则表示串口连接正常。此时,您可以继续进行安装,并最终将应用程序下载到 ESP32。
.. note::
在某些串口接线方式下,在 ESP32 启动并开始打印串口日志前,需要在终端程序中禁用串口 RTS DTR 引脚。该问题仅存在于将 RTS DTR 引脚直接连接到 EN GPIO0 引脚上的情况,绝大多数开发板(包括乐鑫所有的开发板)都没有这个问题。更多详细信息,参见 `esptool 文档`_
.. note::
验证完成后,请关闭串口终端。我们将在后续步骤中向 ESP32 下载新的应用程序,如果未关闭终端,则该应用程序将无法访问串口。
如果您是在安装 ESP32 软件的过程中从 :ref:`get-started-connect-legacy` 章节跳转至此,请返回 :ref:`get-started-configure-legacy` 章节。
.. _esptool 文档: https://github.com/espressif/esptool/wiki/ESP32-Boot-Mode-Selection#automatic-bootloader

View File

@ -1,461 +0,0 @@
***************************
快速入门(传统 GNU Make
***************************
:link_to_translation:`en:[English]`
.. include:: ../gnu-make-legacy.rst
本文档旨在指导用户搭建 ESP32 硬件开发的软件环境,通过一个简单的示例展示如何使用 ESP-IDF (Espressif IoT Development Framework) 配置菜单,并编译、下载固件至 ESP32 开发板等步骤。
.. include-build-file:: inc/version-note.inc
概述
====
ESP32 SoC 芯片支持以下功能:
* 2.4 GHz Wi-Fi
* 蓝牙
* 高性能双核
* 超低功耗协处理器
* 多种外设
ESP32 采用 40 nm 工艺制成,具有最佳的功耗性能、射频性能、稳定性、通用性和可靠性,适用于各种应用场景和不同功耗需求。
乐鑫为用户提供完整的软、硬件资源,进行 ESP32 硬件设备的开发。其中,乐鑫的软件开发环境 ESP-IDF 旨在协助用户快速开发物联网 (IoT) 应用,可满足用户对 Wi-Fi、蓝牙、低功耗等方面的要求。
准备工作
========
硬件:
* 一款 **ESP32** 开发板
* **USB 数据线** (A 转 Micro-B)
* PCWindows、Linux 或 macOS
软件:
* 设置 **工具链**,用于编译 ESP32 **应用程序**;
* 获取 **ESP-IDF** 软件开发框架。该框架已经基本包含 ESP32 使用的 API软件库和源代码和运行 **工具链** 的脚本;
* 安装 C 语言编程(**工程**)的 **文本编辑器**,例如 `Eclipse <https://www.eclipse.org/>`_
开发板简介
==========
请点击下方连接,了解有关具体开发板的详细信息。
.. toctree::
:maxdepth: 1
ESP32-DevKitC <../hw-reference/esp32/get-started-devkitc>
ESP-WROVER-KIT <../hw-reference/esp32/get-started-wrover-kit>
ESP32-PICO-KIT <../hw-reference/esp32/get-started-pico-kit>
ESP32-Ethernet-Kit <../hw-reference/esp32/get-started-ethernet-kit>
ESP32-DevKit-S(-R) <../hw-reference/esp32/user-guide-devkits-r-v1.1>
.. _get-started-step-by-step-legacy:
详细安装步骤
============
请根据下方详细步骤,完成安装过程。
设置开发环境
~~~~~~~~~~~~
* :doc:`Windows <windows-setup>`:doc:`Linux <linux-setup>`:doc:`macOS <macos-setup>`:ref:`get-started-setup-toolchain-legacy`
* :ref:`get-started-get-esp-idf-legacy`
* :ref:`get-started-setup-path-legacy`
* :ref:`get-started-get-packages-legacy`
创建您的第一个工程
~~~~~~~~~~~~~~~~~~
* :ref:`get-started-start-project-legacy`
* :ref:`get-started-connect-legacy`
* :ref:`get-started-configure-legacy`
* :ref:`get-started-build-and-flash-legacy`
* :ref:`get-started-monitor-legacy`
.. _get-started-setup-toolchain-legacy:
第一步:设置工具链
==================
工具链指一套用于编译代码和应用程序的程序。
为了加快开发进度,您可以直接使用乐鑫提供的预制工具链。请根据您的操作系点击对应的链接,并按照链接中的指导进行安装。
.. toctree::
:hidden:
Windows <windows-setup>
Linux <linux-setup>
macOS <macos-setup>
+-----------------+---------------+---------------+
| |windows-logo| | |linux-logo| | |macos-logo| |
+-----------------+---------------+---------------+
| Windows_ | Linux_ | `macOS`_ |
+-----------------+---------------+---------------+
.. |windows-logo| image:: ../../_static/windows-logo.png
:target: ../get-started-legacy/windows-setup.html
.. |linux-logo| image:: ../../_static/linux-logo.png
:target: ../get-started-legacy/linux-setup.html
.. |macos-logo| image:: ../../_static/macos-logo.png
:target: ../get-started-legacy/macos-setup.html
.. _Windows: ../get-started-legacy/windows-setup.html
.. _Linux: ../get-started-legacy/linux-setup.html
.. _macOS: ../get-started-legacy/macos-setup.html
.. note::
在本文档中Linux 和 macOS 操作系统中 ESP-IDF 的默认安装路径为 ``~/esp``Windows 操作系统的默认路径为 ``%userprofile%\esp``。您也可以将 ESP-IDF 安装在任何其他路径下但请注意在使用命令行时进行相应替换。注意ESP-IDF 不支持带有空格的路径。
此外, 您也可以根据自身经验和实际需求,对环境进行个性化设置,而非使用预制工具链。此时,请前往 :ref:`get-started-customized-setup-legacy` 章节获取更多信息。
.. _get-started-get-esp-idf-legacy:
第二步:获取 ESP-IDF
=====================
除了工具链,您还需要供 ESP32 使用的 API软件库和源代码具体请见 `ESP-IDF 仓库 <https://github.com/espressif/esp-idf>`_
获取本地副本:打开终端,切换到你要存放 ESP-IDF 的工作目录,使用 ``git clone`` 命令克隆远程仓库。
打开终端,后运行以下命令:
.. include-build-file:: inc/git-clone-bash.inc
ESP-IDF 将下载至 ``~/esp/esp-idf``
请前往 :doc:`/versions`,查看 ESP-IDF 不同版本的具体适用场景。
.. include-build-file:: inc/git-clone-notes.inc
.. note::
在克隆远程仓库时,不要忘记加上 ``--recursive`` 选项。否则,请接着运行以下命令,获取所有子模块::
cd esp-idf
git submodule update --init
.. _get-started-setup-path-legacy:
第三步:设置环境变量
=======================
工具链通过环境变量 ``IDF_PATH`` 获得 ESP-IDF 的目录。因此,您需要在 PC 中设置该环境变量,否则无法编译工程。
您可以在每次重启会话时手动设置,也可以在用户配置中进行永久设置,具体请前往 :doc:`add-idf_path-to-profile` 章节,查看 :ref:`Windows <add-idf_path-to-profile-windows-legacy>`:ref:`Linux 及 MacOS <add-idf_path-to-profile-linux-macos-legacy>` 操作系统的具体设置方式。
.. _get-started-get-packages-legacy:
第四步:安装 Python 软件包
==========================
ESP-IDF 所需的 Python 软件包位于 ``IDF_PATH/requirements.txt`` 中。您可以运行以下命令进行安装::
python -m pip install --user -r $IDF_PATH/requirements.txt
.. note::
请注意查询您所使用的 Python 解释器的版本(运行命令 ``python --version``),并根据查询结果将上方命令中的 ``python`` 替换为 ``python3``, ``python3.7``,例如::
python3 -m pip install --user -r $IDF_PATH/requirements.txt
.. _get-started-start-project-legacy:
第五步:开始创建工程
=====================
现在,您可以开始准备开发 ESP32 应用程序了。您可以从 ESP-IDF 中 :idf:`examples` 目录下的 :example:`get-started/hello_world` 工程开始。
:example:`get-started/hello_world` 复制至您本地的 ``~/esp`` 目录下:
Linux 和 macOS 操作系统
~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: bash
cd ~/esp
cp -r $IDF_PATH/examples/get-started/hello_world .
Windows 操作系统
~~~~~~~~~~~~~~~~~~
.. code-block:: batch
cd %userprofile%\esp
xcopy /e /i %IDF_PATH%\examples\get-started\hello_world hello_world
ESP-IDF 的 :idf:`examples` 目录下有一系列示例工程,都可以按照上面的方法进行创建。您可以按照上述方法复制并运行其中的任何示例,也可以直接编译示例,无需进行复制。
.. important::
ESP-IDF 编译系统不支持带有空格的路径。
.. _get-started-connect-legacy:
第六步:连接设备
===================
现在,请将您的 ESP32 开发板连接到 PC并查看开发板使用的串口。
通常,串口在不同操作系统下显示的名称有所不同:
- **Windows 操作系统:** ``COM1``
- **Linux 操作系统:**``/dev/tty`` 开始
- **macOS 操作系统:**``/dev/cu.`` 开始
有关如何查看串口名称的详细信息,请见 :doc:`establish-serial-connection`
.. note::
请记住串口名,您会在下面的步骤中用到。
.. _get-started-configure-legacy:
第七步:配置
=============
请进入 :ref:`get-started-start-project-legacy` 中提到的 ``hello_world`` 目录,并运行工程配置工具 ``menuconfig``
Linux 和 macOS 操作系统
~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: bash
cd ~/esp/hello_world
make menuconfig
Windows 操作系统
~~~~~~~~~~~~~~~~~~~
.. code-block:: batch
cd %userprofile%\esp\hello_world
make menuconfig
如果之前的步骤都正确,则会显示下面的菜单:
.. figure:: ../../_static/project-configuration.png
:align: center
:alt: 工程配置 — 主窗口
:figclass: align-center
工程配置 — 主窗口
进入菜单后,选择 ``Serial flasher config`` > ``Default serial port`` 配置串口(设备将通过该串口加载工程)。按回车键确认选择,点击 ``< Save >`` 保存配置,然后点击 ``< Exit >`` 退出 ``menuconfig``
``menuconfig`` 工具的常见操作见下。
* 上下箭头:移动
* ``回车``:进入子菜单
* ``ESC 键``:返回上级菜单或退出
* ``英文问号``:调出帮助菜单(退出帮助菜单,请按回车键)。
* ``空格``或 ``Y 键``:选择 ``[*]`` 配置选项;``N 键``:禁用 ``[*]`` 配置选项
* ``英文问号`` (查询配置选项):调出有关该选项的帮助菜单
* ``/ 键``:寻找配置工程
.. attention::
如果您使用的是 ESP32-DevKitC板载 ESP32-SOLO-1 模组),请在烧写示例程序前,前往 ``menuconfig`` 中使能单核模式(:ref:`CONFIG_FREERTOS_UNICORE`)。
.. _get-started-build-and-flash-legacy:
第八步:编译和烧录
====================
请使用以下命令,编译烧录工程::
make flash
运行以上命令可以编译应用程序和所有 ESP-IDF 组件,接着生成 bootloader、分区表和应用程序二进制文件。接着这些二进制文件将被烧录至 ESP32 开发板。
烧录过程中可能遇到的问题
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如果在运行给定命令时出现如“连接失败”这样的错误,原因之一则可能是运行 ``esptool.py`` 出现错误。``esptool.py`` 是构建系统调用的程序,用于重置芯片、与 ROM 引导加载器交互以及烧录固件的工具。解决该问题的一个简单的方法就是按照以下步骤进行手动复位。如果问题仍未解决,请参考 `Troubleshooting <https://github.com/espressif/esptool#bootloader-wont-respond>`_ 获取更多信息。
``esptool.py`` 通过使 USB 转串口转接器芯片(如 FTDI 或 CP210x的 DTR 和 RTS 控制线生效来自动复位 {IDF_TARGET_NAME}(请参考 :doc:`establish-serial-connection` 获取更多详细信息)。DTR 和 RTS 控制线又连接到 {IDF_TARGET_NAME} 的 ``GPIO0````CHIP_PU`` (EN) 管脚上,因此 DTR 和 RTS 的电压电平变化会使 {IDF_TARGET_NAME} 进入固件下载模式。相关示例可查看 ESP32 DevKitC 开发板的 `原理图 <https://dl.espressif.com/dl/schematics/esp32_devkitc_v4-sch-20180607a.pdf>`_
一般来说,使用官方的 esp-idf 开发板不会出现问题。但是,``esptool.py`` 在以下情况下不能自动重置硬件。
- 您的硬件没有连接到 ``GPIO0````CIHP_PU`` 的 DTR 和 RTS 控制线
- DTR 和 RTS 控制线的配置方式不同
- 根本没有这样的串行控制线路
根据您硬件的种类,也可以将您 {IDF_TARGET_NAME} 开发板手动设置成固件下载模式(复位)。
- 对于 Espressif 的开发板,您可以参考对应开发板的入门指南或用户指南。例如,可以通过按住 **Boot** 按钮 (``GPIO0``) 再按住 **EN** 按钮(``CHIP_PU``) 来手动复位 esp-idf 开发板。
- 对于其他类型的硬件,可以尝试将 ``GPIO0`` 拉低。
常规操作
~~~~~~~~~~~~~~~~
如果一切顺利,您可在烧录完成后看到类似下方的打印信息。接着,开发板将会复位,应用程序 "hello_world" 开始启动。
.. code-block:: bash
esptool.py v3.0-dev
Flashing binaries to serial port /dev/ttyUSB0 (app at offset 0x10000)...
esptool.py v3.0-dev
Serial port /dev/cu.SLAB_USBtoUART
Connecting........____
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, Coding Scheme None
Crystal is 40MHz
MAC: 30:ae:a4:15:21:b4
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0220
Compressed 26704 bytes to 15930...
Wrote 26704 bytes (15930 compressed) at 0x00001000 in 1.4 seconds (effective 151.9 kbit/s)...
Hash of data verified.
Compressed 147984 bytes to 77738...
Wrote 147984 bytes (77738 compressed) at 0x00010000 in 6.9 seconds (effective 172.7 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 103...
Wrote 3072 bytes (103 compressed) at 0x00008000 in 0.0 seconds (effective 1607.9 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
如果您希望使用 Eclipse IDE而非 ``make`` 编译系统,请参考 :doc:`Eclipse guide <eclipse-setup>`
.. _get-started-monitor-legacy:
第九步:监视器
===============
您可以使用 ``make monitor`` 命令,监视 “hello_world” 的运行情况。
运行该命令后,:doc:`IDF 监视器 <../api-guides/tools/idf-monitor>` 应用程序将启动::
$ 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
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
ets Jun 8 2016 00:22:57
...
此时,您就可以在启动日志和诊断日志之后,看到打印的 “Hello world!” 了。
.. code-block:: bash
...
Hello world!
This is esp32 chip with 2 CPU cores, WiFi/BT/BLE, silicon revision 1, 4MB external flash
Restarting in 10 seconds...
Restarting in 9 seconds...
Restarting in 8 seconds...
Restarting in 7 seconds...
您可使用快捷键 ``Ctrl+]``,退出 IDF 监视器。
如果 IDF 监视器在烧录后很快发生错误,或打印信息全是乱码(见下),很有可能是因为您的开发板采用了 26 MHz 晶振,而 ESP-IDF 默认支持大多数开发板使用的 40 MHz 晶振。
.. figure:: ../../_static/get-started-garbled-output.png
:align: center
:alt: 乱码输出
:figclass: align-center
此时,请您:
1. 退出监视器。
2. 打开 :ref:`menuconfig <get-started-configure-legacy>`
3. 进入 ``Component config`` --> ``ESP32-specific`` --> ``Main XTAL frequency`` 进行配置,将 :ref:`CONFIG_ESP32_XTAL_FREQ_SEL` 设置为 26 MHz。
4. 然后,请重新 :ref:`编译和烧录 <get-started-build-and-flash-legacy>` 应用程序。
.. note::
您也可以运行以下命令,一次性执行构建、烧录和监视过程::
make flash monitor
此外,请前往 :doc:`IDF 监视器 <../api-guides/tools/idf-monitor>`,了解更多使用 IDF 监视器的快捷键和其他详情。
**恭喜,您已完成 ESP32 的入门学习!**
现在,您可以尝试一些其他 :idf:`examples`,或者直接开发自己的应用程序。
环境变量
========
用户可以在使用 ``make`` 命令时 **直接设置** 部分环境变量,而无需进入 ``make menuconfig`` 进行重新配置。这些变量包括:
.. list-table::
:widths: 25 75
:header-rows: 1
* - 变量
- 描述与使用方式
* - ``ESPPORT``
- 覆盖 ``flash````monitor`` 命令使用的串口。例:``make flash ESPPORT=/dev/ttyUSB1``, ``make monitor ESPPORT=COM1``
* - ``ESPBAUD``
- 覆盖烧录 ESP32 时使用的串口速率。例:``make flash ESPBAUD=9600``
* - ``MONITORBAUD``
- 覆盖监控时使用的串口速率。例:``make monitor MONITORBAUD=9600``
.. note::
您可导出环境变量(例:``export ESPPORT=/dev/ttyUSB1``)。在同一会话窗口中,如果未被同步覆盖,所有 ``make`` 命令均会使用导出的环境变量值。
更新 ESP-IDF
=============
乐鑫会不时推出更新版本的 ESP-IDF修复 bug 或推出新的特性。因此,您在使用时,也应注意更新您本地的版本。最简单的方法是:直接删除您本地的 ``esp-idf`` 文件夹,然后按照 :ref:`get-started-get-esp-idf-legacy` 中的指示,重新完成克隆。
如果您希望将 ESP-IDF 克隆到新的路径下,请务必 :doc:`重新设置 IDF_PATH <add-idf_path-to-profile>`。否则,工具链将无法找到 ESP-IDF。
此外,您可以仅更新变更部分。具体方式,请前往 :ref:`更新 <updating>` 章节查看。
相关文档
========
.. toctree::
:maxdepth: 1
add-idf_path-to-profile
establish-serial-connection
make-project
eclipse-setup
../api-guides/tools/idf-monitor
toolchain-setup-scratch
.. Note: These two targets may be used from git-clone-notes.inc depending on version, don't remove
.. _Stable version: https://docs.espressif.com/projects/esp-idf/en/stable/
.. _Releases page: https://github.com/espressif/esp-idf/releases

View File

@ -1,76 +0,0 @@
****************************************************
从零开始设置 Linux 环境下的工具链(传统 GNU Make
****************************************************
:link_to_translation:`en:[English]`
.. include:: ../gnu-make-legacy.rst
.. note::
安装工具链的标准方法请见 :doc:`这里 <linux-setup>`。请参考 :ref:`工具链自定义设置 <get-started-customized-setup-legacy>` 章节,查看可能需要从头开始设置工具链的情况。
安装准备
========
编译 ESP-IDF 需要以下软件包:
- Ubuntu and Debian::
sudo apt-get install gcc git wget make libncurses-dev flex bison gperf python python-pip python-setuptools python-serial python-cryptography python-future python-pyparsing python-pyelftools libffi-dev libssl-dev
- Arch::
sudo pacman -S --needed gcc git make ncurses flex bison gperf python-pyserial python-cryptography python-future python-pyparsing python-pyelftools
.. note::
一些旧的2014年之前Linux 发行版中使用的 ``pyserial`` 版本可能是 2.x ESP-IDF 并不支持。这种情况下,请按照 :ref:`get-started-get-packages-legacy` 章节的介绍,使用 ``pip`` 安装软件包。
从源代码编译工具链
==================
- 安装依赖项:
- CentOS 7::
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
- Ubuntu 16.04 或以上 ::
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
- Arch::
TODO
- 创建工作目录,并进入该目录::
mkdir -p ~/esp
cd ~/esp
- 下载并编译 ``crosstool-NG``
.. include-build-file:: inc/scratch-build-code.inc
- 编译工具链::
./ct-ng xtensa-esp32-elf
./ct-ng build
chmod -R u+w builds/xtensa-esp32-elf
编译得到的工具链会被保存到 ``~/esp/crosstool-NG/builds/xtensa-esp32-elf``。请按照 :ref:`标准设置指南 <setup-linux-toolchain-add-it-to-path-legacy>` 的介绍,将工具链添加到 ``PATH``
后续步骤
========
继续设置开发环境,请前往 :ref:`get-started-get-esp-idf-legacy` 章节。

View File

@ -1,106 +0,0 @@
********************************************
Linux 平台工具链的标准设置(传统 GNU Make
********************************************
:link_to_translation:`en:[English]`
.. include:: ../gnu-make-legacy.rst
安装准备
========
编译 ESP-IDF 需要以下软件包:
- CentOS 7::
sudo yum install gcc git wget make flex bison gperf python python2-cryptography
- Ubuntu and Debian::
sudo apt-get install gcc git wget make flex bison gperf python python-pip python-setuptools python-serial python-cryptography python-future python-pyparsing python-pyelftools libffi-dev libssl-dev
- Arch::
sudo pacman -S --needed gcc git make flex bison gperf python-pyserial python-cryptography python-future python-pyparsing python-pyelftools
.. note::
一些旧的2014年之前Linux 发行版中使用的 ``pyserial`` 版本可能是 2.x ESP-IDF 并不支持。这种情况下,请按照 :ref:`get-started-get-packages-legacy` 章节的介绍,使用 ``pip`` 安装软件包。
工具链设置
==========
.. include-build-file:: inc/download-links.inc
Linux 版的 ESP32 工具链可以从 Espressif 的网站下载:
- 64 位 Linux
|download_link_linux64|
- 32 位 Linux
|download_link_linux32|
1. 下载压缩文件之后,解压到 ``~/esp`` 目录中:
- 64 位 Linux
.. include-build-file:: inc/unpack-code-linux64.inc
- 32 位 Linux
.. include-build-file:: inc/unpack-code-linux32.inc
.. _setup-linux-toolchain-add-it-to-path-legacy:
2. 工具链将被解压到 ``~/esp/xtensa-esp32-elf/`` 路径下。
为了正常使用工具链,您必须更新 ``~/.profile`` 文件中的 ``PATH`` 环境变量。此外,您还可以在 ``~/.profile`` 文件中增加以下代码,这样一来,所有终端窗口均可以使用 ``xtensa-esp32-elf``::
export PATH="$HOME/esp/xtensa-esp32-elf/bin:$PATH"
或者,您可以为上述命令创建一个别名。这样,您只有在需要时才可以使用工具链。如需设置别名,请将以下代码增加至您的 ``〜/ .profile`` 文件中::
alias get_esp32='export PATH="$HOME/esp/xtensa-esp32-elf/bin:$PATH"'
这样,您可以在终端输入 ``get_esp32`` 命令将工具链添加至您的 ``PATH``,从而使用工具链。
.. note::
如果您已将 ``/bin/bash`` 设置为登录 shell且同时存在 ``.bash_profile````.profile``,则请更新 ``.bash_profile`` 。在 CentOS 环境下, ``alias`` 需要添加到 ``.bashrc`` 文件中。
3. 退出并重新登录以使 ``.profile`` 更改生效。运行以下命令来检查 ``PATH`` 设置是否正确 ::
printenv PATH
检查字符串的开头是否包含类似的工具链路径::
$ printenv PATH
/home/user-name/esp/xtensa-esp32-elf/bin:/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`` 替换为您的安装主目录。
权限问题 /dev/ttyUSB0
------------------------------
某些 Linux 版本可能在烧写 ESP32 时会出现 ``Failed to open port /dev/ttyUSB0`` 错误消息,这可以通过 :ref:`将当前用户添加到 dialout 组 <linux-dialout-group-legacy>` 来解决。
后续步骤
==========
继续设置开发环境,请前往 :ref:`get-started-get-esp-idf-legacy` 章节。
相关文档
=================
.. toctree::
:maxdepth: 1
linux-setup-scratch
.. _AUR: https://wiki.archlinux.org/index.php/Arch_User_Repository

View File

@ -1,74 +0,0 @@
********************************************************
从零开始设置 Mac OS 环境下的工具链(传统 GNU Make
********************************************************
:link_to_translation:`en:[English]`
.. include:: ../gnu-make-legacy.rst
.. note::
安装工具链的标准方法请见 :doc:`这里 <macos-setup>`。请参考 :ref:`工具链自定义设置 <get-started-customized-setup-legacy>` 章节,查看可能需要从头开始设置工具链的情况。
安装准备
========
- 安装 pip::
sudo easy_install pip
.. note::
``pip`` 稍后将用于安装 :ref:`必要的 Python 软件包 <get-started-get-packages-legacy>`
从源代码编译工具链
===================
- 安装依赖项:
- 安装 MacPorts_ 或 homebrew_ 安装包管理器。MacPorts 需要完整的 XCode 软件,而 homebrew 只需要安装 XCode 命令行工具即可。
.. _homebrew: https://brew.sh/
.. _MacPorts: https://www.macports.org/install.php
- 对于 MacPorts::
sudo port install gsed gawk binutils gperf grep gettext wget libtool autoconf automake
- 对于 homebrew::
brew install gnu-sed gawk binutils gperftools gettext wget help2man libtool autoconf automake
- 创建一个文件系统镜像(区分大小写)::
hdiutil create ~/esp/crosstool.dmg -volname "ctng" -size 10g -fs "Case-sensitive HFS+"
- 挂载::
hdiutil mount ~/esp/crosstool.dmg
- 创建指向您工作目录的符号链接::
mkdir -p ~/esp
ln -s /Volumes/ctng ~/esp/ctng-volume
- 前往新创建的目录 ::
cd ~/esp/ctng-volume
- 下载并编译 ``crosstool-NG``
.. include-build-file:: inc/scratch-build-code.inc
- 编译工具链::
./ct-ng xtensa-esp32-elf
./ct-ng build
chmod -R u+w builds/xtensa-esp32-elf
编译得到的工具链会被保存到 ``~/esp/ctng-volume/crosstool-NG/builds/xtensa-esp32-elf``。请按照 :ref:`标准设置指南 <setup-macos-toolchain-add-it-to-path-legacy>` 的介绍,将工具链添加到 ``PATH``
后续步骤
========
继续设置开发环境,请前往 :ref:`get-started-get-esp-idf-legacy` 章节。

View File

@ -1,60 +0,0 @@
************************************************
Mac OS 平台工具链的标准设置(传统 GNU Make
************************************************
:link_to_translation:`en:[English]`
.. include:: ../gnu-make-legacy.rst
安装准备
========
- 安装 pip::
sudo easy_install pip
.. note::
``pip`` 稍后将用于安装 :ref:`所需 Python 包 <get-started-get-packages-legacy>`
工具链设置
==========
.. include-build-file:: inc/download-links.inc
Mac OS 版本的 ESP32 工具链可以从以下地址下载:
|download_link_osx|
下载压缩文件之后,解压到 ``~/esp`` 目录中:
.. include-build-file:: inc/unpack-code-osx.inc
.. _setup-macos-toolchain-add-it-to-path-legacy:
工具链将被解压到 ``~/esp/xtensa-esp32-elf/`` 路径下。
为了正常使用工具链,您必须更新 ``~/.profile`` 文件中的 ``PATH`` 环境变量。此外,您还可以在 ``~/.profile`` 文件中增加以下代码,这样一来,所有终端窗口均可以使用 ``xtensa-esp32-elf``::
export PATH=$HOME/esp/xtensa-esp32-elf/bin:$PATH
或者,您可以为上述命令创建一个别名。这样,您只有在需要时才可以使用工具链。如需设置别名,请将以下代码增加至您的 ``〜/ .profile`` 文件中::
alias get_esp32="export PATH=$HOME/esp/xtensa-esp32-elf/bin:$PATH"
这样,您可以在终端输入 ``get_esp32`` 命令将工具链添加至您的 ``PATH``,从而使用工具链。
后续步骤
========
继续设置开发环境,请前往 :ref:`get-started-get-esp-idf-legacy` 章节。
相关文档
========
.. toctree::
:maxdepth: 1
macos-setup-scratch

View File

@ -1,77 +0,0 @@
通过 make 指令创建和烧录项目(传统 GNU Make
=================================================
:link_to_translation:`en:[English]`
.. include:: ../gnu-make-legacy.rst
寻找项目
--------
除了 `esp-idf-template <https://github.com/espressif/esp-idf-template>`_ 项目模版外ESP-IDF 还在 GitHub 仓库中的 :idf:`examples` 目录下提供多个示例项目。
请找到并进入您想要的项目,开始配置、构建该项目。
配置项目
--------
::
make menuconfig
编译项目
--------
::
make all
该命令将配置 app 和 bootloader并根据配置生成分区表。
烧录项目
--------
``make all`` 完成后将打印一行命令,提示您如何使用 esptool.py 烧录芯片。不过,您可以使用以下命令进行烧录::
make flash
该命令可以将整个项目(包括 app、bootloader 和分区表)烧录至新芯片。此外,如果分区表中存在 ota_data则该命令还会同时将初始 ota_data 烧录至芯片。
该命令允许您直接从 factory 分区中运行新加载的 app如果 factory 分区不存在,则从第一个 OTA 分区开始运行)。
您可以使用 ``make menuconfig`` 配置串口的烧录。
在运行 ``make flash`` 之前无需单独运行 ``make all````make flash`` 命令本身就可以自动构建所需的文件。
仅编译和烧录应用程序
--------------------
在首次烧录完成后,您可以只希望烧录并编译应用程序,而不再包括 bootloader 和分区表。这种情况可以使用以下命令:
* ``make app`` -- 仅编译应用程序
* ``make app-flash`` -- 仅烧录应用程序
``make app-flash`` -- 在有需要时自动重新编译应用程序
如果没有变化,每次都重新烧录、编译 bootloader 和分区表也没有坏处。
分区表
------
项目编译完成后,"build" 目录下将出现一个名为 "my_app.bin" (例)的二进制文件。这是一个可由 bootloader 加载的 ESP32 映像文件。
ESP32 的一块 flash 可以包含多个应用程序,以及多种数据(校准数据、文件系统、参数存储等)。因此,在向 flash 烧录分区表时,通常保留 0x8000 的偏移量。
分区表中的每个条目都有名称标签、类型app、数据或其他、子类型及在 flash 中的偏移量。
使用分区表最简便的方法是:运行 ``make menuconfig``,选择一个预定义分区表:
* "Single factory app, no OTA"
* "Factory app, two OTA definitions"
上述两种情况中factory app 在 flash 中的烧录偏移地址均为 0x10000。运行 ``make partition_table`` 命令可以打印分区表摘要。
更多有关 :doc:`分区表 <../api-guides/partition-tables>` 及自定义分区表的内容,请见 :doc:`相关文档 <../api-guides/partition-tables>`

View File

@ -1,28 +0,0 @@
.. _get-started-customized-setup-legacy:
***********************************************
工具链自定义设置(传统 GNU Make 系统)
***********************************************
除了从乐鑫官网(请见 :ref:`get-started-setup-toolchain-legacy`)下载二进制工具链外,您还可以自行编译工具链。
.. include:: ../gnu-make-legacy.rst
如无特殊需求,建议直接使用我们提供的预编译二进制工具链。不过,您可以在以下情况考虑自行编译工具链:
- 需要定制工具链编译配置
- 需要使用其他 GCC 版本(如 4.8.5
- 需要破解 gcc、newlib 或 libstdc++
- 有相关兴趣或时间充裕
- 不信任从网站下载的 bin 文件
如需自行编译工具链,请查看以下文档:
.. toctree::
:maxdepth: 1
windows-setup-scratch
linux-setup-scratch
macos-setup-scratch

View File

@ -1,122 +0,0 @@
******************************************************
从零开始设置 Windows 环境下的工具链(传统 GNU Make
******************************************************
.. include:: ../gnu-make-legacy.rst
手动安装所有工具能更好地控制整个安装流程,同时也方便高阶用户进行自定义安装。此外,经验不足的用户还可以参考 :doc:`预编译环境 <windows-setup>` 中的步骤进行准备。
使用预编译环境对工具链进行快速标准设置,请参照 :doc:`windows-setup`
.. _configure-windows-toolchain-from-scratch-legacy:
从零开始配置工具链和环境
==============================================
本流程包括:首先,安装 MSYS2_其次安装 ESP-IDF 所需的 Python 工具包;最后,下载并安装 Xtensa 工具链。
* 请前往 MSYS2_ 安装器页面,并下载 ``msys2-i686-xxxxxxx.exe`` 安装器(我们仅支持 32-bit MSYS 环境32 位和 64 位 Window 均可使用)。截止至本文最新更新之时,最新版安装器为 ``msys2-i686-20161025.exe``
* 完成所有安装步骤。**最后一步时,请不要勾选 "Run MSYS2 32-bit now"。**
* 安装完成后,请从“开始”菜单中找到 "MSYS2 MinGW 32-bit",运行“命令提示符”窗口。
* 为什么要特别打开这个终端窗口MSYS2 会对不同环境进行区分。默认的 "MSYS" 环境与 Cygwin 相仿,会为 Windows 系统的 API 调用增加一个转换层。但为了使用支持 COM 端口的原生 Python我们需要准备好 "MinGW" 环境。
* GitHub 上的 ESP-IDF 仓库的 `tools` 目录下可以找到名为 ``windows_install_prerequisites.sh`` 的脚本。如果您还没有本地 ESP-IDF 副本,也可以从以下地址进行下载(请下载 raw 格式)::idf_raw:`tools/windows/windows_install_prerequisites.sh`,并将其保存至您的电脑。
* 请在 MSYS2 终端窗口中指定该脚本的保存路径。注意,路径格式与 Window 路径相同,但需使用正斜杠 (``/``) 而不是反斜杠 (``\``)。例 ``C:/Users/myuser/Downloads/windows_install_prerequisites.sh``。当然,您也可以直接打开查看该脚本的内容。
* ``windows_install_prerequisites.sh`` 脚本将帮您下载并安装支持 ESP-IDF 的软件包和 ESP32 工具链。
疑难解答
~~~~~~~~~~~~~~~
* MSYS 可能在脚本运行过程中进行自动升级,导致无法使用。此时,您会看到以下错误信息::
*** fatal error - cygheap base mismatch detected - 0x612E5408/0x612E4408
这个问题很大可能是由于 cygwin DLL 版本不兼容。
这种情况下,请完全关闭终端窗口(相当于终止所有进程),并重新打开一个窗口。然后,请在新窗口中重新运行 ``windows_install_prerequisites.sh`` (小技巧:您可以使用“向上箭头”找到之前运行的命令)。此时,更新流程将重启。
* 注意MSYS2 是一个“滚动”发行版,因此安装脚本可能会为您安装比“预编译环境”中更新的软件包。因此,如果遇到与 MSYS2 安装包有关的错误,请前往 `MSYS2-packages 问题列表`_ 页面寻找答案。如果未找到所需答案,请 `提交一个 IDF Issue`_
中国地区的 MSYS2 镜像
~~~~~~~~~~~~~~~~~~~~~~
中国地区有一些(非官方)的 MSYS2 镜像,这可以大幅提高中国地区的下载速度。
如需添加这些镜像,请在运行安装脚本前修改以下两个 MSYS2 镜像列表文件。镜像文件的保存路径为 ``/etc/pacman.d``,比如 ``c:\msys2\etc\pacman.d``
请在 ``mirrorlist.mingw32`` 最上方增加如下语句::
Server = https://mirrors.ustc.edu.cn/msys2/mingw/i686/
Server = http://mirror.bit.edu.cn/msys2/REPOS/MINGW/i686
请在 ``mirrorlist.msys`` 最上方增加如下语句::
Server = http://mirrors.ustc.edu.cn/msys2/msys/$arch
Server = http://mirror.bit.edu.cn/msys2/REPOS/MSYS2/$arch
HTTP 代理
~~~~~~~~~~
您可以在运行“设置脚本”之前,在终端中设置 ``http_proxy`` 变量,从而允许使用 HTTP 代理下载 MSYS 和 PIP::
export http_proxy='http://http.proxy.server:PORT'
或者修改证书::
export http_proxy='http://user:password@http.proxy.server:PORT'
如需始终用代理使用 MSYS请在 MSYS 目录中增加 ``/etc/profile``
其他设置:下载工具链
============================================
.. include-build-file:: inc/download-links.inc
如果您已经安装了 MSYS2或者想要以不同的方式执行操作您可以在此处下载工具链
|download_link_win32|
.. note::
如果您已完成了 :ref:`configure-windows-toolchain-from-scratch-legacy` 中介绍的所有步骤,则已经拥有了工具链,这里无需重复下载。
.. important::
仅拥有工具链 *尚无法* 让您在 Windows 中使用 ESP-IDF。除此之外您还至少需要安装 GNU make、bash 和 sed。上述环境已经包括这些配置此外还有一个主机编译器这样才能使用 menuconfig
后续步骤
==========
继续设置开发环境,请前往 :ref:`get-started-get-esp-idf-legacy` 章节。
.. _updating-existing-windows-environment-legacy:
更新环境
========================
当 IDF 有更新时,有时需要安装新的工具链或为 Windows MSYS2 环境添加新的系统要求。
此时,您无需重新配置环境,仅需更新现有 Windows 环境和工具链即可。
- 将 IDF 更新至您希望的版本。
- 请运行 IDF 仓库中的 ``tools/windows/windows_install_prerequisites.sh`` 脚本。该脚本将帮您安装所有新的软件包,并下载更新工具链至最新版本。
注意,该脚本在更新 MSYS2 时也会遇到 疑难解答_ 中介绍的问题。
如需要同时支持多个 IDF 版本,您可以在不同的目录下配置独立的 MSYS2 环境。或者,您还可以下载多个工具链,并将其解压缩到不同的目录下,然后使用 PATH 环境变量指定默认工具链。
.. _MSYS2: https://www.msys2.org/
.. _MSYS2-packages 问题列表: https://github.com/Alexpux/MSYS2-packages/issues/
.. _提交一个 IDF Issue: https://github.com/espressif/esp-idf/issues/new

View File

@ -1,73 +0,0 @@
**********************************************
Windows 平台工具链的标准设置(传统 GNU Make
**********************************************
:link_to_translation:`en:[English]`
.. include:: ../gnu-make-legacy.rst
概述
====
Windows 系统没有内置的 "make" 环境,所以除了安装工具链之外,您还需要一个兼容 GNU 的环境。这里,我们使用 MSYS2_ 环境兼容 GNU。您无需一直使用这个环境比如您可以使用 :doc:`Eclipse <eclipse-setup>` 或其他前端,仅需在后台运行 MSYS2_ 即可。
工具链设置
==========
最简便的工具链设置方法是从下方地址下载 Windows 多合一工具链和 MSYS2 压缩包文件:
https://dl.espressif.com/dl/esp32_win32_msys2_environment_and_esp2020r2_toolchain-20200601.zip
请将压缩包文件解压至 ``C:\``(或其他目录,但本文档中以 ``C:\`` 为例),该文件将为您创建一个带有预配置环境的 ``msys32`` 目录。
开始尝试
========
请运行 ``C:\msys32\mingw32.exe`` 文件,打开一个 MSYS2 MINGW32 终端窗口。该窗口的环境为 bash shell。请创建一个名为 ``esp`` 的文件夹,作为 ESP32 应用程序开发的默认目录。您可以使用以下命令创建文件夹::
mkdir -p ~/esp
您还可以通过 ``cd ~/esp`` 命令,进入刚刚创建的文件夹。如无其他问题,本步骤到此结束。
.. figure:: ../../_static/msys2-terminal-window.png
:align: center
:alt: MSYS2 MINGW32 shell 窗口
:figclass: align-center
MSYS2 MINGW32 shell 窗口
请在后续步骤中,使用本窗口配置 ESP32 的开发环境。
后续步骤
==========
继续设置开发环境,请前往 :ref:`get-started-get-esp-idf-legacy` 章节。
更新环境
========
当 IDF 有更新时,有时需要安装新的工具链或为 Windows MSYS2 环境添加新的要求。如需将旧版本预编译环境中的数据迁移至新版本,您可以:
1. 复制旧的 MSYS2 环境(即 ``C:\msys32``),并将其移动/重命名到不同目录下(即 ``C:\msys32_old``)。
2. 使用上述步骤,下载新的预编译环境。
3. 将新的 MSYS2 环境解压缩至 ``C:\msys32`` (或您指定的其他位置)。
4. 找到旧的 ``C:\msys32_old\home`` 文件夹,并将其移动至 ``C:\msys32``
5. 此时,如无其他需要,您可以删除旧的 ``C:\msys32_old\home`` 文件夹。
注意,您可以在电脑中安装多个不同的 MSYS2 环境,仅需将它们保存在不同的路径下即可。
此外,您还可以 :ref:`直接更新现有环境(无需下载新的版本)<updating-existing-windows-environment-legacy>`,但步骤更加复杂。
相关文档
========
.. toctree::
:maxdepth: 1
windows-setup-scratch
.. _MSYS2: https://www.msys2.org/

View File

@ -11,8 +11,3 @@ ESP-IDF V4.0 默认采用基于 CMake 的构建系统。
.. 注解::
`ESP-IDF Eclipse 插件 <https://github.com/espressif/idf-eclipse-plugin/blob/master/README.md>`_ 中使用的是 macOS 截图,但安装指南对 Windows、Linux 和 macOS 均适用。
.. only:: esp32
如需使用针对 GNU Make 传统构建系统的 Eclipse IDE 开发环境,请前往 :doc:`快速入门(传统 GNU Make</get-started-legacy/index>`,查看 :doc:`Eclipse IDE 的创建和烧录指南(传统 GNU Make</get-started-legacy/eclipse-setup>`

View File

@ -812,7 +812,6 @@ Windows 操作系统
vscode-setup
../api-guides/tools/idf-monitor
toolchain-setup-scratch
:esp32: ../get-started-legacy/index
.. _Stable version: https://docs.espressif.com/projects/esp-idf/zh_CN/stable/
.. _Releases page: https://github.com/espressif/esp-idf/releases

View File

@ -8,9 +8,6 @@
使用 ESP-IDF 工具安装器对工具链及其他工具进行快速标准设置,请参照 :doc:`windows-setup`
.. note::
基于 GNU Make 的构建系统要求 Windows 兼容 MSYS2_ Unix基于 CMake 的构建系统则无此要求。
.. _get-esp-idf-windows-command-line:
获取 ESP-IDF
@ -54,7 +51,7 @@ Ninja 编译工具
^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. 注解::
目前Ninja 仅提供支持 64 位 Windows 版本的 bin 文件。您也可以配合其他编译工具(如 mingw-make在 32 位 Windows 版本中使用 CMake 和 ``idf.py`` 。但是目前暂无关于此工具的说明文档。
目前Ninja 仅提供支持 64 位 Windows 版本的 bin 文件。
请从 `下载页面 <ninja-dl_>`_ 下载最新发布的 Windows 平台稳定版 Ninja_。
@ -85,9 +82,6 @@ Python 安装完成后,从 Windows 开始菜单中打开“命令提示符”
然后,请将该目录下的 ``bin`` 子目录 :ref:`添加到 Path 环境变量 <add-directory-windows-path>`。例如,将目录 ``C:\Program Files\{IDF_TARGET_TOOLCHAIN_PREFIX}\bin`` 添加到 Path 环境变量。
.. 注解::
如果您已安装 MSYS2 环境(适用 "GNU Make" 编译系统),则可以跳过下载那一步,直接添加目录 ``C:\msys32\opt\{IDF_TARGET_TOOLCHAIN_PREFIX}\bin`` 到 Path 环境变量,因为 MSYS2 环境已包含工具链。
.. _add-directory-windows-path:
@ -110,7 +104,6 @@ Python 安装完成后,从 Windows 开始菜单中打开“命令提示符”
.. _Ninja: https://ninja-build.org/
.. _ninja-dl: https://github.com/ninja-build/ninja/releases
.. _Python: https://www.python.org/downloads/windows/
.. _MSYS2: https://www.msys2.org/
.. _kconfig-frontends releases page: https://github.com/espressif/kconfig-frontends/releases
.. Note: These two targets may be used from git-clone-notes.inc depending on version, don't remove
.. _Stable version: https://docs.espressif.com/projects/esp-idf/zh_CN/stable/

View File

@ -4,10 +4,6 @@ Windows 平台工具链的标准设置
:link_to_translation:`en:[English]`
.. only:: esp32
.. 注解::
目前,基于 CMake 的构建系统仅支持 64 位 Windows 版本。32 位 Windows 版本的用户可根据 :doc:`传统 GNU Make 构建系统<../get-started-legacy/windows-setup>` 中的介绍进行操作。
概述
============
@ -16,11 +12,6 @@ ESP-IDF 需要安装一些必备工具,才能围绕 {IDF_TARGET_NAME} 构建
在本入门指南中,我们通过 **命令提示符** 进行有关操作。不过,您在安装 ESP-IDF 后还可以使用 :doc:`Eclipse <eclipse-setup>` 或其他支持 CMake 的图形化工具 IDE。
.. only:: esp32
.. 注解::
较早 ESP-IDF 版本使用 :doc:`传统 GNU Make 构建系统<../get-started-legacy/windows-setup>` 和 MSYS2_ Unix 兼容环境。但如今已非必需,用户可直接通过 Windows 命令提示符使用 ESP-IDF。
.. note::
限定条件:
- 请注意 ESP-IDF 和 ESP-IDF 工具的安装路径不能超过 90 个字符,安装路径过长可能会导致构建失败。

View File

@ -1,3 +0,0 @@
.. note:: ESP-IDF V4.0 及之后版本的默认构建系统为 CMake。本文档主要针对之前基于 GNU Make 的传统构建系统。请注意,未来,我们可能不会继续支持基于 GNU Make 的构建系统。

View File

@ -0,0 +1 @@
.. include:: ../../en/migration-guides/build-system.rst

View File

@ -1,8 +1,9 @@
ESP-IDF 5.0 迁移指南
********************
:link_to_translation:`zh_CN:[中文]`
:link_to_translation:`en:[English]`
.. toctree::
:maxdepth: 1
外设 <peripherals>
构建系统 <build-system>

View File

@ -2,7 +2,6 @@
# Automatically generated file. DO NOT EDIT.
# Espressif IoT Development Framework (ESP-IDF) Project Configuration
#
CONFIG_IDF_CMAKE=y
CONFIG_IDF_TARGET_ARCH_XTENSA=y
CONFIG_IDF_TARGET="esp32"
CONFIG_IDF_TARGET_ESP32=y

View File

@ -24,19 +24,15 @@
#include "ble_mesh_console_decl.h"
#if CONFIG_IDF_CMAKE
#define CONFIG_ESPTOOLPY_PORT "Which is choosen by Users for CMake"
#endif
static void register_free(void);
static void register_restart(void);
static void register_make(void);
void register_system(void)
{
register_free();
register_restart();
register_make();
}
/** 'restart' command restarts the program */
@ -76,106 +72,3 @@ static void register_free(void)
};
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
}
static int make(int argc, char **argv)
{
int count = REG_READ(RTC_CNTL_STORE0_REG);
if (++count >= 3) {
printf("This is not the console you are looking for.\n");
return 0;
}
REG_WRITE(RTC_CNTL_STORE0_REG, count);
const char *make_output =
R"(LD build/console.elf
esptool.py v2.1-beta1
)";
const char* flash_output[] = {
R"(Flashing binaries to serial port )" CONFIG_ESPTOOLPY_PORT R"( (app at offset 0x10000)...
esptool.py v2.1-beta1
Connecting....
)",
R"(Chip is ESP32D0WDQ6 (revision 0)
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0220
Compressed 15712 bytes to 9345...
)",
R"(Wrote 15712 bytes (9345 compressed) at 0x00001000 in 0.1 seconds (effective 1126.9 kbit/s)...
Hash of data verified.
Compressed 333776 bytes to 197830...
)",
R"(Wrote 333776 bytes (197830 compressed) at 0x00010000 in 3.3 seconds (effective 810.3 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 82...
)",
R"(Wrote 3072 bytes (82 compressed) at 0x00008000 in 0.0 seconds (effective 1588.4 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting...
)"
};
const char* monitor_output =
R"(MONITOR
)" LOG_COLOR_W R"(--- idf_monitor on )" CONFIG_ESPTOOLPY_PORT R"( 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --
)" LOG_RESET_COLOR;
bool need_make = false;
bool need_flash = false;
bool need_monitor = false;
for (int i = 1; i < argc; ++i) {
if (strcmp(argv[i], "all") == 0) {
need_make = true;
} else if (strcmp(argv[i], "flash") == 0) {
need_make = true;
need_flash = true;
} else if (strcmp(argv[i], "monitor") == 0) {
need_monitor = true;
} else if (argv[i][0] == '-') {
/* probably -j option */
} else if (isdigit((int) argv[i][0])) {
/* might be an argument to -j */
} else {
printf("make: *** No rule to make target `%s'. Stop.\n", argv[i]);
/* Technically this is an error, but let's not spoil the output */
return 0;
}
}
if (argc == 1) {
need_make = true;
}
if (need_make) {
printf("%s", make_output);
}
if (need_flash) {
size_t n_items = sizeof(flash_output) / sizeof(flash_output[0]);
for (int i = 0; i < n_items; ++i) {
printf("%s", flash_output[i]);
vTaskDelay(200/portTICK_PERIOD_MS);
}
}
if (need_monitor) {
printf("%s", monitor_output);
esp_restart();
}
return 0;
}
static void register_make(void)
{
const esp_console_cmd_t cmd = {
.command = "make",
.help = NULL, /* Do not include in 'help' output */
.hint = "all | flash | monitor",
.func = &make,
};
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
}

View File

@ -25,8 +25,6 @@ In the `Example Configuration` menu:
* Set `SoftAP Password`
* Set `Maximal STA connections`
When using the legacy GNU Make build system, set `Default serial port` under `Serial flasher config`.
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:

View File

@ -13,7 +13,6 @@ See the README.md file in the upper level 'examples' directory for more informat
* Open the project configuration menu (`idf.py menuconfig`)
* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../README.md) for more details.
* When using Make build system, set `Default serial port` under `Serial flasher config`.
* If using a different folder than `certs` for storing certificates then update `Custom Certificate Bundle Path` under `Component config` - `mbedTLS` - `Certificate Bundle`
### Build and Flash

View File

@ -16,7 +16,6 @@ Shows how to use mDNS to advertise lookup services and hosts
* Open the project configuration menu (`idf.py menuconfig`)
* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../README.md) for more details.
* When using Make build system, set `Default serial port` under `Serial flasher config`.
* Set `mDNS Hostname` as host name prefix for the device and its instance name in `mDNS Instance Name`
* Disable `Resolve test services` to prevent the example from querying defined names/services on startup (cause warnings in example logs, as illustrated below)

View File

@ -17,7 +17,6 @@ This example can be executed on any ESP32 board, the only required interface is
* Open the project configuration menu (`idf.py menuconfig`)
* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details.
* When using Make build system, set `Default serial port` under `Serial flasher config`.
PEM certificate for this example could be extracted from an openssl `s_client` command connecting to mqtt.eclipseprojects.io.
In case a host operating system has `openssl` and `sed` packages installed, one could execute the following command to download and save the root certificate to a file (Note for Windows users: Both Linux like environment or Windows native packages may be used).

View File

@ -57,7 +57,6 @@ RSA private key is nothing but the client private key ( RSA ) generated in Step
#### 4) Connection cofiguration
* Open the project configuration menu (`idf.py menuconfig`)
* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details.
* When using Make build system, set `Default serial port` under `Serial flasher config`.
### Build and Flash

View File

@ -17,7 +17,6 @@ This example can be executed on any ESP32 board, the only required interface is
* Open the project configuration menu (`idf.py menuconfig`)
* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details.
* When using Make build system, set `Default serial port` under `Serial flasher config`.
* Generate your client keys and certificate

View File

@ -30,9 +30,8 @@ as required by MQTT API. (See the example source for details: `"BAD123" -> 0xBA,
### Configure the project
* Run `make menuconfig` (or `idf.py menuconfig` if using CMake build system)
* Run `idf.py menuconfig`
* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details.
* When using Make build system, set `Default serial port` under `Serial flasher config`.
### Build and Flash

View File

@ -18,7 +18,6 @@ This example can be executed on any ESP32 board, the only required interface is
* Open the project configuration menu (`idf.py menuconfig`)
* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details.
* When using Make build system, set `Default serial port` under `Serial flasher config`.
### Build and Flash

View File

@ -17,7 +17,6 @@ This example can be executed on any ESP32 board, the only required interface is
* Open the project configuration menu (`idf.py menuconfig`)
* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details.
* When using Make build system, set `Default serial port` under `Serial flasher config`.
### Build and Flash

View File

@ -16,7 +16,6 @@ This example can be executed on any ESP32 board, the only required interface is
* Open the project configuration menu (`idf.py menuconfig`)
* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details.
* When using Make build system, set `Default serial port` under `Serial flasher config`.
Note how to create a PEM certificate for mqtt.eclipseprojects.io:

View File

@ -15,8 +15,6 @@ Open the project configuration menu (`idf.py menuconfig`):
* The time synchronization period is defined by `CONFIG_LWIP_SNTP_UPDATE_DELAY`. This option allows you to set the time synchronization period (default is one hour). This option does not affect this example because after synchronization the program goes into deep sleep for 10 seconds. If you modify this example or use the code from this example, keep in mind that this option will trigger time synchronization. You can change it in `Component config-->LWIP-->SNTP-->Request interval to update time (ms)` menu.
* When using Make build system, set `Default serial port` under `Serial flasher config`.
## Obtaining time using LwIP SNTP module
When this example boots first time after ESP32 is reset, it connects to WiFi and obtains time using SNTP.

View File

@ -22,7 +22,7 @@ To run this example, you need to have one ESP32 development board integrated wit
### Configure the project
Enter project configuration by `idf.py menuconfig` (or `make menuconfig` if using legacy GNU Make build system) and navigate into:
Enter project configuration by `idf.py menuconfig` and navigate into:
* `Example Connection Configuration` menu to choose the connection details:

View File

@ -20,12 +20,6 @@ file. An erased partition's contents is compared to a generated blank file.
Before running either of the example scripts, it is necessary to build and flash the firmware using the usual means:
Make:
```bash
make build flash
```
CMake:
```bash
idf.py build flash
```

View File

@ -20,12 +20,6 @@ partition for all switches performed.
Before running either of the example scripts, it is necessary to build and flash the firmware using the usual means:
Make:
```bash
make build flash
```
CMake:
```bash
idf.py build flash
```

View File

@ -1,101 +0,0 @@
# Functionality common to both top-level project makefile (project.mk)
# and component makefiles (component_wrapper.mk)
#
PYTHON=$(call dequote,$(CONFIG_SDK_PYTHON))
# Include project config makefile, if it exists.
#
# (Note that we only rebuild this makefile automatically for some
# targets, see project_config.mk for details.)
SDKCONFIG_MAKEFILE ?= $(abspath $(BUILD_DIR_BASE)/include/config/auto.conf)
-include $(SDKCONFIG_MAKEFILE)
export SDKCONFIG_MAKEFILE # sub-makes (like bootloader) will reuse this path
# BATCH_BUILD flag disables interactive terminal features, defaults to verbose build
ifdef BATCH_BUILD
V ?= 1
endif
#Handling of V=1/VERBOSE=1 flag
#
# if V=1, $(summary) does nothing and $(details) will echo extra details
# if V is unset or not 1, $(summary) echoes a summary and $(details) does nothing
VERBOSE ?=
V ?= $(VERBOSE)
ifeq ("$(V)","1")
summary := @true
details := @echo
else
summary := @echo
details := @true
# disable echoing of commands, directory names
MAKEFLAGS += --silent
endif # $(V)==1
ifdef CONFIG_SDK_MAKE_WARN_UNDEFINED_VARIABLES
MAKEFLAGS += --warn-undefined-variables
endif
# Get version variables
include $(IDF_PATH)/make/version.mk
# General make utilities
# convenience variable for printing an 80 asterisk wide separator line
SEPARATOR:="*******************************************************************************"
# macro to remove quotes from an argument, ie $(call dequote,$(CONFIG_BLAH))
define dequote
$(subst ",,$(1))
endef
# " comment kept here to keep syntax highlighting happy
# macro to keep an absolute path as-is, but resolve a relative path
# against a particular parent directory
#
# $(1) path to resolve
# $(2) directory to resolve non-absolute path against
#
# Path and directory don't have to exist (definition of a "relative
# path" is one that doesn't start with /)
#
# $(2) can contain a trailing forward slash or not, result will not
# double any path slashes.
#
# example $(call resolvepath,$(CONFIG_PATH),$(CONFIG_DIR))
define resolvepath
$(abspath $(foreach dir,$(1),$(if $(filter /%,$(dir)),$(dir),$(subst //,/,$(2)/$(dir)))))
endef
# macro to include a target only if it's on the list of targets that make
# was invoked with
#
# This allows you to have something like an "order-only phony prerequisite",
# ie a prerequisite that determines an order phony targets have to run in.
#
# Because normal order-only prerequisites don't work with phony targets.
#
# example $(call prereq_if_explicit,erase_flash)
define prereq_if_explicit
$(filter $(1),$(MAKECMDGOALS))
endef
# macro to kill duplicate items in a list without messing up the sort order of the list.
# Will only keep the unique items; if there are non-unique items in the list, it will remove
# the later recurring ones so only the first one remains.
# Copied from http://stackoverflow.com/questions/16144115/makefile-remove-duplicate-words-without-sorting
define uniq
$(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
endef
# macro to strip leading ../s from a path
# Given $(1) which is a directory, remove any leading ../s from it
# (recursively keeps removing ../ until not found)
# if the path contains nothing but ../.., a single . is returned (cwd)
define stripLeadingParentDirs
$(foreach path,$(1),$(if $(subst ..,,$(path)),$(if $(filter ../%,$(path)),$(call stripLeadingParentDirs,$(patsubst ../%,%,$(path))),$(path)),.))
endef

View File

@ -1 +0,0 @@
$(warning Deprecated feature: No longer necessary to include component_common.mk from $(COMPONENT_PATH)/component.mk)

View File

@ -1,350 +0,0 @@
# Component wrapper makefile
#
# This makefile gets called recursively from the project make, once for each component.
# COMPONENT_MAKEFILE is set to point at the component.mk file for the component itself,
# which is included as part of this process (after default variables are defined).
#
# This makefile comprises multiple stages, marked in blocked comments below.
#
# CWD is the build directory of the component.
ifndef PROJECT_PATH
$(error Make was invoked from $(CURDIR). However please do not run make from the sdk or a component directory; invoke make from the project directory. See the ESP-IDF README for details.)
endif
################################################################################
# 1) Set default variables for the component build (including configuration
# loaded from sdkconfig.)
################################################################################
# Find the path to the component
COMPONENT_PATH := $(abspath $(dir $(COMPONENT_MAKEFILE)))
export COMPONENT_PATH
# COMPONENT_BUILD_DIR is otherwise known as CWD for the build
COMPONENT_BUILD_DIR := $(abspath .)
# include elements common to both project & component makefiles
# (includes project configuration set via menuconfig)
include $(IDF_PATH)/make/common.mk
# Some of the following defaults may be overriden by the component's component.mk makefile,
# during the next step:
# Absolute path of the .a file
COMPONENT_LIBRARY = lib$(COMPONENT_NAME).a
# Source dirs a component has. Default to root directory of component.
COMPONENT_SRCDIRS = .
#Names of binary & text files to embed as raw content in the component library
COMPONENT_EMBED_FILES ?=
COMPONENT_EMBED_TXTFILES ?=
# By default, include only the include/ dir.
COMPONENT_ADD_INCLUDEDIRS = include
COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME)
# Name of the linker fragment files this component presents to the Linker
# script generator
COMPONENT_ADD_LDFRAGMENTS ?=
# Define optional compiling macros
define compile_exclude
COMPONENT_OBJEXCLUDE += $(1)
endef
define compile_include
COMPONENT_OBJINCLUDE += $(1)
endef
define compile_only_if
$(eval $(if $(1), $(call compile_include, $(2)), $(call compile_exclude, $(2))))
endef
define compile_only_if_not
$(eval $(if $(1), $(call compile_exclude, $(2)), $(call compile_include, $(2))))
endef
COMPONENT_ADD_LINKER_DEPS ?=
COMPONENT_DEPENDS ?=
COMPONENT_EXTRA_CLEAN ?=
COMPONENT_EXTRA_INCLUDES ?=
COMPONENT_OBJEXCLUDE ?=
COMPONENT_OBJINCLUDE ?=
COMPONENT_SUBMODULES ?=
################################################################################
# 2) Include the component.mk for the specific component (COMPONENT_MAKEFILE) to
# override variables & optionally define custom targets. Also include global
# component makefiles.
################################################################################
# Include any Makefile.componentbuild file letting components add
# configuration at the global component level
# Save component_path; we pass it to the called Makefile.componentbuild
# as COMPILING_COMPONENT_PATH, and we use it to restore the current
# COMPONENT_PATH later.
COMPILING_COMPONENT_PATH := $(COMPONENT_PATH)
define includeCompBuildMakefile
ifeq ("$(V)","1")
$$(info including $(1)/Makefile.componentbuild...)
endif
COMPONENT_PATH := $(1)
include $(1)/Makefile.componentbuild
endef
$(foreach componentpath,$(COMPONENT_PATHS), \
$(if $(wildcard $(componentpath)/Makefile.componentbuild), \
$(eval $(call includeCompBuildMakefile,$(componentpath)))))
#Restore COMPONENT_PATH to what it was
COMPONENT_PATH := $(COMPILING_COMPONENT_PATH)
# Include component.mk for this component.
include $(COMPONENT_MAKEFILE)
################################################################################
# 3) Set variables that depend on values that may changed by component.mk
################################################################################
ifndef COMPONENT_CONFIG_ONLY # Skip steps 3-5 if COMPONENT_CONFIG_ONLY is set
# Object files which need to be linked into the library
# By default we take all .c, .cpp, .cc & .S files in COMPONENT_SRCDIRS.
ifndef COMPONENT_OBJS
# Find all source files in all COMPONENT_SRCDIRS
COMPONENT_OBJS := $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.c,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.c)))
COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.cpp,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.cpp)))
COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.cc,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.cc)))
COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.S,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.S)))
# Make relative by removing COMPONENT_PATH from all found object paths
COMPONENT_OBJS := $(patsubst $(COMPONENT_PATH)/%,%,$(COMPONENT_OBJS))
else
# Add in components defined by conditional compiling macros
COMPONENT_OBJS += $(COMPONENT_OBJINCLUDE)
endif
# Remove any leading ../ from paths, so everything builds inside build dir
COMPONENT_OBJS := $(call stripLeadingParentDirs,$(COMPONENT_OBJS))
# Do the same for COMPONENT_OBJEXCLUDE (used below)
COMPONENT_OBJEXCLUDE := $(call stripLeadingParentDirs,$(COMPONENT_OBJEXCLUDE))
# COMPONENT_OBJDIRS is COMPONENT_SRCDIRS with the same transform applied
COMPONENT_OBJDIRS := $(call stripLeadingParentDirs,$(COMPONENT_SRCDIRS))
# Remove items disabled by optional compilation
COMPONENT_OBJS := $(foreach obj,$(COMPONENT_OBJS),$(if $(filter $(abspath $(obj)),$(abspath $(COMPONENT_OBJEXCLUDE))), ,$(obj)))
# Remove duplicates
COMPONENT_OBJS := $(call uniq,$(COMPONENT_OBJS))
# Object files with embedded binaries to add to the component library
# Correspond to the files named in COMPONENT_EMBED_FILES & COMPONENT_EMBED_TXTFILES
COMPONENT_EMBED_OBJS ?= $(addsuffix .bin.o,$(notdir $(COMPONENT_EMBED_FILES))) $(addsuffix .txt.o,$(notdir $(COMPONENT_EMBED_TXTFILES)))
# If we're called to compile something, we'll get passed the COMPONENT_INCLUDES
# variable with all the include dirs from all the components in random order. This
# means we can accidentally grab a header from another component before grabbing our own.
# To make sure that does not happen, re-order the includes so ours come first.
COMPONENT_PRIV_INCLUDEDIRS ?=
OWN_INCLUDES:=$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_PRIV_INCLUDEDIRS) $(COMPONENT_ADD_INCLUDEDIRS)))
COMPONENT_INCLUDES := $(OWN_INCLUDES) $(filter-out $(OWN_INCLUDES),$(COMPONENT_INCLUDES))
################################################################################
# 4) Define a target to generate component_project_vars.mk Makefile which
# contains common per-component settings which are included directly in the
# top-level project make
#
# (Skipped if COMPONENT_CONFIG_ONLY is set.)
################################################################################
# macro to generate variable-relative paths inside component_project_vars.mk, whenever possible
# ie put literal $(IDF_PATH), $(PROJECT_PATH) and $(BUILD_DIR_BASE) into the generated
# makefiles where possible.
#
# This means if directories move (breaking absolute paths), don't need to 'make clean'
define MakeVariablePath
$(subst $(IDF_PATH),$$(IDF_PATH),$(subst $(PROJECT_PATH),$$(PROJECT_PATH),$(subst $(BUILD_DIR_BASE),$$(BUILD_DIR_BASE),$(1))))
endef
# component_project_vars.mk target for the component. This is used to
# take component.mk variables COMPONENT_ADD_INCLUDEDIRS,
# COMPONENT_ADD_LDFLAGS, COMPONENT_DEPENDS and COMPONENT_SUBMODULES
# and inject those into the project make pass.
#
# The target here has no dependencies, as the parent target in
# project.mk evaluates dependencies before calling down to here. See
# GenerateComponentTargets macro in project.mk.
#
# If you are thinking of editing the output of this target for a
# component-specific feature, please don't! What you want is a
# Makefile.projbuild for your component (see docs/build-system.rst for
# more.)
#
# Note: The :: target here is not a mistake. This target should always be
# executed, as dependencies are checked by the parent project-level make target.
# See https://www.gnu.org/software/make/manual/make.html#index-_003a_003a-rules-_0028double_002dcolon_0029
component_project_vars.mk::
$(details) "Building component project variables list $(abspath $@)"
@echo '# Automatically generated build file. Do not edit.' > $@
@echo 'COMPONENT_INCLUDES += $(call MakeVariablePath,$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS))))' >> $@
@echo 'COMPONENT_LDFLAGS += $(call MakeVariablePath,-L$(COMPONENT_BUILD_DIR) $(COMPONENT_ADD_LDFLAGS))' >> $@
@echo 'COMPONENT_LINKER_DEPS += $(call MakeVariablePath,$(call resolvepath,$(COMPONENT_ADD_LINKER_DEPS),$(COMPONENT_PATH)))' >> $@
@echo 'COMPONENT_SUBMODULES += $(call MakeVariablePath,$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_SUBMODULES))))' >> $@
@echo 'COMPONENT_LIBRARIES += $(COMPONENT_NAME)' >> $@
@echo 'COMPONENT_LDFRAGMENTS += $(call MakeVariablePath,$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_LDFRAGMENTS))))' >> $@
@echo 'component-$(COMPONENT_NAME)-build: $(addprefix component-,$(addsuffix -build,$(COMPONENT_DEPENDS)))' >> $@
ifdef COMPONENT_OWNBUILDTARGET
@echo 'COMPONENT_$(COMPONENT_NAME)_BUILDTARGET := $(COMPONENT_OWNBUILDTARGET)' >> $@
endif
ifdef COMPONENT_OWNCLEANTARGET
@echo 'COMPONENT_$(COMPONENT_NAME)_CLEANTARGET := $(COMPONENT_OWNCLEANTARGET)' >> $@
endif
################################################################################
# 5) Where COMPONENT_OWNBUILDTARGET / COMPONENT_OWNCLEANTARGET
# is not set by component.mk, define default build, clean, etc. targets
#
# (Skipped if COMPONENT_CONFIG_ONLY is set.)
################################################################################
# Default build behaviour: define a phony build target and a COMPONENT_LIBRARY link target.
ifndef COMPONENT_OWNBUILDTARGET
.PHONY: build
build: $(COMPONENT_LIBRARY)
# Build the archive. We remove the archive first, otherwise ar will get confused if we update
# an archive when multiple filenames have the same name (src1/test.o and src2/test.o)
$(COMPONENT_LIBRARY): $(COMPONENT_OBJS) $(COMPONENT_EMBED_OBJS)
$(summary) AR $(patsubst $(PWD)/%,%,$(CURDIR))/$@
rm -f $@
$(AR) $(ARFLAGS) $@ $(COMPONENT_OBJS) $(COMPONENT_EMBED_OBJS)
endif
# If COMPONENT_OWNCLEANTARGET is not set, define a phony clean target
ifndef COMPONENT_OWNCLEANTARGET
CLEAN_FILES := $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(COMPONENT_OBJEXCLUDE) $(COMPONENT_OBJEXCLUDE:.o=.d) $(COMPONENT_EMBED_OBJS) $(COMPONENT_EXTRA_CLEAN) component_project_vars.mk
.PHONY: clean
clean:
$(summary) RM $(CLEAN_FILES)
rm -f $(CLEAN_FILES)
endif
DEBUG_FLAGS ?= -ggdb
# Include all dependency files already generated
-include $(COMPONENT_OBJS:.o=.d)
# This is a fix for situation where the project or IDF dir moves, and instead
# of rebuilding the target the build fails until make clean is run
#
# It adds an empty dependency rule for the (possibly non-existent) source file itself,
# which prevents it not being found from failing the build
#
# $1 == Source File, $2 == .o file used for .d file name
define AppendSourceToDependencies
echo "$1:" >> $$(patsubst %.o,%.d,$2)
endef
# This pattern is generated for each COMPONENT_SRCDIR to compile the files in it.
define GenerateCompileTargets
# $(1) - directory containing source files, relative to $(COMPONENT_PATH) - one of $(COMPONENT_SRCDIRS)
# $(2) - output build directory, which is $(1) with any leading ".."s converted to "."s to ensure output is always under build/
#
$(2)/%.o: $$(COMPONENT_PATH)/$(1)/%.c $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(COMPONENT_OBJDIRS)
$$(summary) CC $$(patsubst $$(PWD)/%,%,$$(CURDIR))/$$@
$$(CC) $$(CFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I $(1) -c $$(abspath $$<) -o $$@
$(call AppendSourceToDependencies,$$<,$$@)
$(2)/%.o: $$(COMPONENT_PATH)/$(1)/%.cpp $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(COMPONENT_OBJDIRS)
$$(summary) CXX $$(patsubst $$(PWD)/%,%,$$(CURDIR))/$$@
$$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I $(1) -c $$(abspath $$<) -o $$@
$(call AppendSourceToDependencies,$$<,$$@)
$(2)/%.o: $$(COMPONENT_PATH)/$(1)/%.cc $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(COMPONENT_OBJDIRS)
$$(summary) CXX $$(patsubst $$(PWD)/%,%,$$(CURDIR))/$$@
$$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I $(1) -c $$(abspath $$<) -o $$@
$(call AppendSourceToDependencies,$$<,$$@)
$(2)/%.o: $$(COMPONENT_PATH)/$(1)/%.S $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(COMPONENT_OBJDIRS)
$$(summary) AS $$(patsubst $$(PWD)/%,%,$$(CURDIR))/$$@
$$(CC) $$(CPPFLAGS) $$(DEBUG_FLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I $(1) -c $$(abspath $$<) -o $$@
$(call AppendSourceToDependencies,$$<,$$@)
# CWD is build dir, create the build subdirectory if it doesn't exist
#
# (NB: Each .o file depends on all relative component build dirs $(COMPONENT_OBJDIRS), including $(2), to work
# around a behaviour make 3.81 where the first pattern (randomly) seems to be matched rather than the best fit. ie if
# you have objects a/y.o and a/b/c.o then c.o can be matched with $(1)=a & %=b/c, meaning that subdir 'a/b' needs to be
# created but wouldn't be created if $(2)=a. Make 4.x doesn't have this problem, it seems to preferentially
# choose the better match ie $(2)=a/b and %=c )
#
# Note: This may cause some issues for out-of-tree source files and make 3.81 :/
#
$(2):
mkdir -p $(2)
endef
# Generate all the compile target patterns
$(foreach srcdir,$(COMPONENT_SRCDIRS), $(eval $(call GenerateCompileTargets,$(srcdir),$(call stripLeadingParentDirs,$(srcdir)))))
## Support for embedding binary files into the ELF as symbols
OBJCOPY_EMBED_ARGS := --input-target binary --output-target elf32-xtensa-le --binary-architecture xtensa --rename-section .data=.rodata.embedded
# Generate pattern for embedding text or binary files into the app
# $(1) is name of file (as relative path inside component)
# $(2) is txt or bin depending on file contents
#
# txt files are null-terminated before being embedded (otherwise
# identical behaviour.)
#
define GenerateEmbedTarget
# copy the input file into the build dir (using a subdirectory
# in case the file already exists elsewhere in the build dir)
embed_bin/$$(notdir $(1)): $(call resolvepath,$(1),$(COMPONENT_PATH)) | embed_bin
cp $$< $$@
embed_txt/$$(notdir $(1)): $(call resolvepath,$(1),$(COMPONENT_PATH)) | embed_txt
cp $$< $$@
printf '\0' >> $$@ # null-terminate text files
# messing about with the embed_X subdirectory then using 'cd' for objcopy is because the
# full path passed to OBJCOPY makes it into the name of the symbols in the .o file
$$(notdir $(1)).$(2).o: embed_$(2)/$$(notdir $(1))
$(summary) EMBED $$(patsubst $$(PWD)/%,%,$$(CURDIR))/$$@
cd embed_$(2); $(OBJCOPY) $(OBJCOPY_EMBED_ARGS) $$(notdir $$<) ../$$@
CLEAN_FILES += embed_$(2)/$$(notdir $(1))
endef
embed_txt embed_bin:
mkdir -p $@
# generate targets to embed binary & text files
$(foreach binfile,$(COMPONENT_EMBED_FILES), $(eval $(call GenerateEmbedTarget,$(binfile),bin)))
$(foreach txtfile,$(COMPONENT_EMBED_TXTFILES), $(eval $(call GenerateEmbedTarget,$(txtfile),txt)))
else # COMPONENT_CONFIG_ONLY is set
build:
$(details) "No build needed for $(COMPONENT_NAME) (COMPONENT_CONFIG_ONLY)"
clean:
$(summary) RM component_project_vars.mk
rm -f component_project_vars.mk
component_project_vars.mk:: # no need to add variables via component.mk
@echo '# COMPONENT_CONFIG_ONLY target sets no variables here' > $@
endif # COMPONENT_CONFIG_ONLY

View File

@ -1,55 +0,0 @@
# Makefile to support the linker script generation mechanism
LDGEN_FRAGMENT_FILES = $(COMPONENT_LDFRAGMENTS)
LDGEN_LIBRARIES=$(foreach libcomp,$(COMPONENT_LIBRARIES),$(BUILD_DIR_BASE)/$(libcomp)/lib$(libcomp).a)
# Target to generate linker script generator from fragments presented by each of
# the components
ifeq ($(OS),Windows_NT)
define ldgen_process_template
$(BUILD_DIR_BASE)/ldgen_libraries: $(LDGEN_LIBRARIES) $(IDF_PATH)/make/ldgen.mk
printf "$(foreach info,$(LDGEN_LIBRARIES),$(subst \,/,$(shell cygpath -m $(info)))\n)" > $(BUILD_DIR_BASE)/ldgen_libraries
$(2): $(1) $(LDGEN_FRAGMENT_FILES) $(SDKCONFIG) $(BUILD_DIR_BASE)/ldgen_libraries | prepare_kconfig_files
@echo 'Generating $(notdir $(2))'
$(PYTHON) $(IDF_PATH)/tools/ldgen/ldgen.py \
--input $(1) \
--config $(SDKCONFIG) \
--fragments $(LDGEN_FRAGMENT_FILES) \
--libraries-file $(BUILD_DIR_BASE)/ldgen_libraries \
--output $(2) \
--kconfig $(IDF_PATH)/Kconfig \
--env "COMPONENT_KCONFIGS=$(foreach k, $(COMPONENT_KCONFIGS), $(shell cygpath -m $(k)))" \
--env "COMPONENT_KCONFIGS_PROJBUILD=$(foreach k, $(COMPONENT_KCONFIGS_PROJBUILD), $(shell cygpath -m $(k)))" \
--env "COMPONENT_KCONFIGS_SOURCE_FILE=$(shell cygpath -m $(COMPONENT_KCONFIGS_SOURCE_FILE))" \
--env "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE=$(shell cygpath -m $(COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE))" \
--env "IDF_CMAKE=n" \
--objdump $(OBJDUMP)
endef
else # Windows_NT
define ldgen_process_template
$(BUILD_DIR_BASE)/ldgen_libraries: $(LDGEN_LIBRARIES) $(IDF_PATH)/make/ldgen.mk
printf "$(foreach library,$(LDGEN_LIBRARIES),$(library)\n)" > $(BUILD_DIR_BASE)/ldgen_libraries
$(2): $(1) $(LDGEN_FRAGMENT_FILES) $(SDKCONFIG) $(BUILD_DIR_BASE)/ldgen_libraries | prepare_kconfig_files
@echo 'Generating $(notdir $(2))'
$(PYTHON) $(IDF_PATH)/tools/ldgen/ldgen.py \
--input $(1) \
--config $(SDKCONFIG) \
--fragments $(LDGEN_FRAGMENT_FILES) \
--libraries-file $(BUILD_DIR_BASE)/ldgen_libraries \
--output $(2) \
--kconfig $(IDF_PATH)/Kconfig \
--env "COMPONENT_KCONFIGS=$(COMPONENT_KCONFIGS)" \
--env "COMPONENT_KCONFIGS_PROJBUILD=$(COMPONENT_KCONFIGS_PROJBUILD)" \
--env "COMPONENT_KCONFIGS_SOURCE_FILE=$(COMPONENT_KCONFIGS_SOURCE_FILE)" \
--env "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE=$(COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE)" \
--env "IDF_CMAKE=n" \
--env "IDF_ENV_FPGA=n" \
--objdump $(OBJDUMP)
endef
endif # Windows_NT
define ldgen_create_commands
ldgen-clean:
rm -f $(BUILD_DIR_BASE)/ldgen_libraries
endef

View File

@ -1,786 +0,0 @@
#
# Main Project Makefile
# This Makefile is included directly from the user project Makefile in order to call the component.mk
# makefiles of all components (in a separate make process) to build all the libraries, then links them
# together into the final file. If so, PWD is the project dir (we assume).
#
#
# This makefile requires the environment variable IDF_PATH to be set to the top-level esp-idf directory
# where this file is located.
#
.PHONY: build-components menuconfig defconfig all build clean all_binaries check-submodules size size-components size-files size-symbols list-components
MAKECMDGOALS ?= all
all: all_binaries | check_python_dependencies
# see below for recipe of 'all' target
#
# # other components will add dependencies to 'all_binaries'. The
# reason all_binaries is used instead of 'all' is so that the flash
# target can build everything without triggering the per-component "to
# flash..." output targets.)
help:
@echo "Welcome to Espressif IDF build system. Some useful make targets:"
@echo ""
@echo "make menuconfig - Configure IDF project"
@echo "make defconfig - Set defaults for all new configuration options"
@echo ""
@echo "make all - Build app, bootloader, partition table"
@echo "make flash - Flash app, bootloader, partition table to a chip"
@echo "make clean - Remove all build output"
@echo "make size - Display the static memory footprint of the app"
@echo "make size-components, size-files - Finer-grained memory footprints"
@echo "make size-symbols - Per symbol memory footprint. Requires COMPONENT=<component>"
@echo "make erase_flash - Erase entire flash contents"
@echo "make erase_otadata - Erase ota_data partition; First bootable partition (factory or OTAx) will be used on next boot."
@echo " This assumes this project's partition table is the one flashed on the device."
@echo "make monitor - Run idf_monitor tool to monitor serial output from app"
@echo "make simple_monitor - Monitor serial output on terminal console"
@echo "make list-components - List all components in the project"
@echo ""
@echo "make app - Build just the app"
@echo "make app-flash - Flash just the app"
@echo "make app-clean - Clean just the app"
@echo "make print_flash_cmd - Print the arguments for esptool when flash"
@echo "make check_python_dependencies - Check that the required python packages are installed"
@echo ""
@echo "See also 'make bootloader', 'make bootloader-flash', 'make bootloader-clean', "
@echo "'make partition_table', etc, etc."
# Non-interactive targets. Mostly, those for which you do not need to build a binary
NON_INTERACTIVE_TARGET += defconfig clean% %clean help list-components print_flash_cmd check_python_dependencies
# dependency checks
ifndef MAKE_RESTARTS
ifeq ("$(filter 4.% 3.81 3.82,$(MAKE_VERSION))","")
$(warning esp-idf build system only supports GNU Make versions 3.81 or newer. You may see unexpected results with other Makes.)
endif
ifdef MSYSTEM
ifneq ("$(MSYSTEM)","MINGW32")
$(warning esp-idf build system only supports MSYS2 in "MINGW32" mode. Consult the ESP-IDF documentation for details.)
endif
endif # MSYSTEM
endif # MAKE_RESTARTS
# can't run 'clean' along with any non-clean targets
ifneq ("$(filter clean% %clean,$(MAKECMDGOALS))" ,"")
ifneq ("$(filter-out clean% %clean,$(MAKECMDGOALS))", "")
$(error esp-idf build system doesn't support running 'clean' targets along with any others. Run 'make clean' and then run other targets separately.)
endif
endif
OS ?=
# make IDF_PATH a "real" absolute path
# * works around the case where a shell character is embedded in the environment variable value.
# * changes Windows-style C:/blah/ paths to MSYS style /c/blah
ifeq ("$(OS)","Windows_NT")
# On Windows MSYS2, make wildcard function returns empty string for paths of form /xyz
# where /xyz is a directory inside the MSYS root - so we don't use it.
SANITISED_IDF_PATH:=$(realpath $(IDF_PATH))
else
SANITISED_IDF_PATH:=$(realpath $(wildcard $(IDF_PATH)))
endif
export IDF_PATH := $(SANITISED_IDF_PATH)
ifndef IDF_PATH
$(error IDF_PATH variable is not set to a valid directory.)
endif
ifdef IDF_TARGET
ifneq ($(IDF_TARGET),esp32)
$(error GNU Make based build system only supports esp32 target, but IDF_TARGET is set to $(IDF_TARGET))
endif
else
export IDF_TARGET := esp32
endif
ifneq ("$(IDF_PATH)","$(SANITISED_IDF_PATH)")
# implies IDF_PATH was overriden on make command line.
# Due to the way make manages variables, this is hard to account for
#
# if you see this error, do the shell expansion in the shell ie
# make IDF_PATH=~/blah not make IDF_PATH="~/blah"
$(error If IDF_PATH is overriden on command line, it must be an absolute path with no embedded shell special characters)
endif
ifneq ("$(IDF_PATH)","$(subst :,,$(IDF_PATH))")
$(error IDF_PATH cannot contain colons. If overriding IDF_PATH on Windows, use MSYS Unix-style /c/dir instead of C:/dir)
endif
# disable built-in make rules, makes debugging saner
MAKEFLAGS_OLD := $(MAKEFLAGS)
MAKEFLAGS +=-rR
# Default path to the project: we assume the Makefile including this file
# is in the project directory
ifndef PROJECT_PATH
PROJECT_PATH := $(abspath $(dir $(firstword $(MAKEFILE_LIST))))
export PROJECT_PATH
endif
# A list of the "common" makefiles, to use as a target dependency
COMMON_MAKEFILES := $(abspath $(IDF_PATH)/make/project.mk $(IDF_PATH)/make/common.mk $(IDF_PATH)/make/version.mk $(IDF_PATH)/make/component_wrapper.mk $(firstword $(MAKEFILE_LIST)))
export COMMON_MAKEFILES
# The directory where we put all objects/libraries/binaries. The project Makefile can
# configure this if needed.
ifndef BUILD_DIR_BASE
BUILD_DIR_BASE := $(PROJECT_PATH)/build
endif
ifneq ("$(BUILD_DIR_BASE)","$(subst :,,$(BUILD_DIR_BASE))")
$(error BUILD_DIR_BASE ($(BUILD_DIR_BASE)) cannot contain colons. If setting this path on Windows, use MSYS Unix-style /c/dir instead of C:/dir)
endif
BUILD_DIR_BASE := $(abspath $(BUILD_DIR_BASE))
export BUILD_DIR_BASE
# Component directories. These directories are searched for components (either the directory is a component,
# or the directory contains subdirectories which are components.)
# The project Makefile can override these component dirs, or add extras via EXTRA_COMPONENT_DIRS
ifndef COMPONENT_DIRS
EXTRA_COMPONENT_DIRS ?=
COMPONENT_DIRS := $(PROJECT_PATH)/components $(EXTRA_COMPONENT_DIRS) $(IDF_PATH)/components $(PROJECT_PATH)/main
endif
# Make sure that every directory in the list is an absolute path without trailing slash.
# This is necessary to split COMPONENT_DIRS into SINGLE_COMPONENT_DIRS and MULTI_COMPONENT_DIRS below.
COMPONENT_DIRS := $(foreach cd,$(COMPONENT_DIRS),$(abspath $(cd)))
export COMPONENT_DIRS
ifdef SRCDIRS
$(warning SRCDIRS variable is deprecated. These paths can be added to EXTRA_COMPONENT_DIRS or COMPONENT_DIRS instead.)
COMPONENT_DIRS += $(abspath $(SRCDIRS))
endif
# List of component directories, i.e. directories which contain a component.mk file
SINGLE_COMPONENT_DIRS := $(abspath $(dir $(dir $(foreach cd,$(COMPONENT_DIRS),\
$(wildcard $(cd)/component.mk)))))
# List of components directories, i.e. directories which may contain components
MULTI_COMPONENT_DIRS := $(filter-out $(SINGLE_COMPONENT_DIRS),$(COMPONENT_DIRS))
# The project Makefile can define a list of components, but if it does not do this
# we just take all available components in the component dirs.
# A component is COMPONENT_DIRS directory, or immediate subdirectory,
# which contains a component.mk file.
#
# Use the "make list-components" target to debug this step.
ifndef COMPONENTS
# Find all component names. The component names are the same as the
# directories they're in, so /bla/components/mycomponent/component.mk -> mycomponent.
# We need to do this for MULTI_COMPONENT_DIRS only, since SINGLE_COMPONENT_DIRS
# are already known to contain component.mk.
COMPONENTS := $(dir $(foreach cd,$(MULTI_COMPONENT_DIRS),$(wildcard $(cd)/*/component.mk))) \
$(SINGLE_COMPONENT_DIRS)
COMPONENTS := $(sort $(foreach comp,$(COMPONENTS),$(lastword $(subst /, ,$(comp)))))
endif
# After a full manifest of component names is determined, subtract the ones explicitly
# omitted by the project Makefile.
EXCLUDE_COMPONENTS ?=
ifdef EXCLUDE_COMPONENTS
COMPONENTS := $(filter-out $(subst ",,$(EXCLUDE_COMPONENTS)), $(COMPONENTS))
# to keep syntax highlighters happy: "))
endif
export COMPONENTS
# Resolve all of COMPONENTS into absolute paths in COMPONENT_PATHS.
# For each entry in COMPONENT_DIRS:
# - either this is directory with multiple components, in which case check that
# a subdirectory with component name exists, and it contains a component.mk file.
# - or, this is a directory of a single component, in which case the name of this
# directory has to match the component name
#
# If a component name exists in multiple COMPONENT_DIRS, we take the first match.
#
# NOTE: These paths must be generated WITHOUT a trailing / so we
# can use $(notdir x) to get the component name.
COMPONENT_PATHS := $(foreach comp,$(COMPONENTS),\
$(firstword $(foreach cd,$(COMPONENT_DIRS),\
$(if $(findstring $(cd),$(MULTI_COMPONENT_DIRS)),\
$(abspath $(dir $(wildcard $(cd)/$(comp)/component.mk))),)\
$(if $(findstring $(cd),$(SINGLE_COMPONENT_DIRS)),\
$(if $(filter $(comp),$(notdir $(cd))),$(cd),),)\
)))
export COMPONENT_PATHS
TEST_COMPONENTS ?=
TEST_EXCLUDE_COMPONENTS ?=
TESTS_ALL ?=
# If TESTS_ALL set to 1, set TEST_COMPONENTS_LIST to all components.
# Otherwise, use the list supplied in TEST_COMPONENTS.
ifeq ($(TESTS_ALL),1)
TEST_COMPONENTS_LIST := $(filter-out $(TEST_EXCLUDE_COMPONENTS), $(COMPONENTS))
else
TEST_COMPONENTS_LIST := $(TEST_COMPONENTS)
endif
TEST_COMPONENT_PATHS := $(foreach comp,$(TEST_COMPONENTS_LIST),$(firstword $(foreach dir,$(COMPONENT_DIRS),$(wildcard $(dir)/$(comp)/test))))
TEST_COMPONENT_NAMES := $(foreach comp,$(TEST_COMPONENT_PATHS),$(lastword $(subst /, ,$(dir $(comp))))_test)
# Set default values that were not previously defined
CC ?= gcc
LD ?= ld
AR ?= ar
OBJCOPY ?= objcopy
OBJDUMP ?= objdump
SIZE ?= size
# Set host compiler and binutils
HOSTCC := $(CC)
HOSTLD := $(LD)
HOSTAR := $(AR)
HOSTOBJCOPY := $(OBJCOPY)
HOSTSIZE := $(SIZE)
export HOSTCC HOSTLD HOSTAR HOSTOBJCOPY SIZE
# Set variables common to both project & component (includes config)
include $(IDF_PATH)/make/common.mk
# Notify users when some of the required python packages are not installed
.PHONY: check_python_dependencies
check_python_dependencies:
ifndef IS_BOOTLOADER_BUILD
$(PYTHON) $(IDF_PATH)/tools/check_python_dependencies.py
endif
# include the config generation targets (dependency: COMPONENT_PATHS)
#
# (bootloader build doesn't need this, config is exported from top-level)
ifndef IS_BOOTLOADER_BUILD
include $(IDF_PATH)/make/project_config.mk
endif
#####################################################################
# If SDKCONFIG_MAKEFILE hasn't been generated yet (detected if no
# CONFIG_IDF_TARGET), stop the Makefile pass now to allow config to
# be created. make will build SDKCONFIG_MAKEFILE and restart,
# reevaluating everything from the top.
#
# This is important so config is present when the
# component_project_vars.mk files are generated.
#
# (After both files exist, if SDKCONFIG_MAKEFILE is updated then the
# normal dependency relationship will trigger a regeneration of
# component_project_vars.mk)
#
#####################################################################
ifndef CONFIG_IDF_TARGET
ifdef IS_BOOTLOADER_BUILD # we expect config to always have been expanded by top level project
$(error "Internal error: config has not been passed correctly to bootloader subproject")
endif
ifdef MAKE_RESTARTS
$(warning "Config was not evaluated after the first pass of 'make'")
endif
else # CONFIG_IDF_TARGET
#####################################################################
# Config is valid, can include rest of the Project Makefile
#####################################################################
# Initialise project-wide variables which can be added to by
# each component.
#
# These variables are built up via the component_project_vars.mk
# generated makefiles (one per component).
#
# See docs/build-system.rst for more details.
COMPONENT_INCLUDES :=
COMPONENT_LDFLAGS :=
COMPONENT_SUBMODULES :=
COMPONENT_LIBRARIES :=
COMPONENT_LDFRAGMENTS :=
# COMPONENT_PROJECT_VARS is the list of component_project_vars.mk generated makefiles
# for each component.
#
# Including $(COMPONENT_PROJECT_VARS) builds the COMPONENT_INCLUDES,
# COMPONENT_LDFLAGS variables and also targets for any inter-component
# dependencies.
#
# See the component_project_vars.mk target in component_wrapper.mk
COMPONENT_PROJECT_VARS := $(addsuffix /component_project_vars.mk,$(notdir $(COMPONENT_PATHS) ) $(TEST_COMPONENT_NAMES))
COMPONENT_PROJECT_VARS := $(addprefix $(BUILD_DIR_BASE)/,$(COMPONENT_PROJECT_VARS))
# this line is -include instead of include to prevent a spurious error message on make 3.81
-include $(COMPONENT_PROJECT_VARS)
# Also add top-level project include path, for top-level includes
COMPONENT_INCLUDES += $(abspath $(BUILD_DIR_BASE)/include/)
export COMPONENT_INCLUDES
all:
ifdef CONFIG_SECURE_BOOT
@echo "(Secure boot enabled, so bootloader not flashed automatically. See 'make bootloader' output)"
ifndef CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES
ifdef SECURE_SIGNED_APPS_ECDSA_SCHEME
@echo "App built but not signed. Sign app & partition data before flashing, via espsecure.py:"
@echo "espsecure.py sign_data --version 1 --keyfile KEYFILE $(APP_BIN)"
@echo "espsecure.py sign_data --version 1 --keyfile KEYFILE $(PARTITION_TABLE_BIN)"
else
@echo "App built but not signed. Sign app & partition data before flashing, via espsecure.py:"
@echo "espsecure.py sign_data --version 2 --keyfile KEYFILE $(APP_BIN)"
endif
endif
@echo "To flash app & partition table, run 'make flash' or:"
else
ifdef CONFIG_APP_BUILD_GENERATE_BINARIES
@echo "To flash all build output, run 'make flash' or:"
endif
endif
ifdef CONFIG_APP_BUILD_GENERATE_BINARIES
@echo $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS)
else
@echo "Binary is not available for flashing"
endif
# If we have `version.txt` then prefer that for extracting IDF version
ifeq ("$(wildcard ${IDF_PATH}/version.txt)","")
IDF_VER_T := $(shell cd ${IDF_PATH} && git describe --always --dirty --match v*.*)
else
IDF_VER_T := $(shell cat ${IDF_PATH}/version.txt)
endif
IDF_VER := $(shell echo "$(IDF_VER_T)" | cut -c 1-31)
# Set default LDFLAGS
EXTRA_LDFLAGS ?=
LDFLAGS ?= -nostdlib \
$(EXTRA_LDFLAGS) \
-Wl,--gc-sections \
-Wl,-static \
-Wl,--start-group \
$(COMPONENT_LDFLAGS) \
-lgcc \
-lstdc++ \
-lgcov \
-Wl,--end-group \
-Wl,-EL
# Set default CPPFLAGS, CFLAGS, CXXFLAGS
# These are exported so that components can use them when compiling.
# If you need your component to add CFLAGS/etc for it's own source compilation only, set CFLAGS += in your component's Makefile.
# If you need your component to add CFLAGS/etc globally for all source
# files, set CFLAGS += in your component's Makefile.projbuild
# If you need to set CFLAGS/CPPFLAGS/CXXFLAGS at project level, set them in application Makefile
# before including project.mk. Default flags will be added before the ones provided in application Makefile.
# CPPFLAGS used by C preprocessor
# If any flags are defined in application Makefile, add them at the end.
CPPFLAGS ?=
EXTRA_CPPFLAGS ?=
CPPFLAGS := -DESP_PLATFORM -D IDF_VER=\"$(IDF_VER)\" -MMD -MP $(CPPFLAGS) $(EXTRA_CPPFLAGS)
PROJECT_VER ?=
export IDF_VER
export PROJECT_NAME
export PROJECT_VER
# Warnings-related flags relevant both for C and C++
COMMON_WARNING_FLAGS = -Wall -Werror=all \
-Wno-error=unused-function \
-Wno-error=unused-but-set-variable \
-Wno-error=unused-variable \
-Wno-error=deprecated-declarations \
-Wextra \
-Wno-unused-parameter -Wno-sign-compare
ifdef CONFIG_COMPILER_DISABLE_GCC8_WARNINGS
COMMON_WARNING_FLAGS += -Wno-parentheses \
-Wno-sizeof-pointer-memaccess \
-Wno-clobbered \
-Wno-format-overflow \
-Wno-stringop-truncation \
-Wno-misleading-indentation \
-Wno-cast-function-type \
-Wno-implicit-fallthrough \
-Wno-unused-const-variable \
-Wno-switch-unreachable \
-Wno-format-truncation \
-Wno-memset-elt-size \
-Wno-int-in-bool-context
endif
ifdef CONFIG_COMPILER_WARN_WRITE_STRINGS
COMMON_WARNING_FLAGS += -Wwrite-strings
endif #CONFIG_COMPILER_WARN_WRITE_STRINGS
# Flags which control code generation and dependency generation, both for C and C++
COMMON_FLAGS = \
-Wno-frame-address \
-ffunction-sections -fdata-sections \
-fstrict-volatile-bitfields \
-mlongcalls \
-nostdlib
ifndef IS_BOOTLOADER_BUILD
# stack protection (only one option can be selected in menuconfig)
ifdef CONFIG_COMPILER_STACK_CHECK_MODE_NORM
COMMON_FLAGS += -fstack-protector
endif
ifdef CONFIG_COMPILER_STACK_CHECK_MODE_STRONG
COMMON_FLAGS += -fstack-protector-strong
endif
ifdef CONFIG_COMPILER_STACK_CHECK_MODE_ALL
COMMON_FLAGS += -fstack-protector-all
endif
# Placing jump tables in flash would cause issues with code that required
# to be placed in IRAM
COMMON_FLAGS += -fno-jump-tables
COMMON_FLAGS += -fno-tree-switch-conversion
# Optimization flags are set based on menuconfig choice
ifdef CONFIG_COMPILER_OPTIMIZATION_SIZE
OPTIMIZATION_FLAGS = -Os -freorder-blocks
endif
ifdef CONFIG_COMPILER_OPTIMIZATION_DEFAULT
OPTIMIZATION_FLAGS = -Og
endif
ifdef CONFIG_COMPILER_OPTIMIZATION_NONE
OPTIMIZATION_FLAGS = -O0
endif
ifdef CONFIG_COMPILER_OPTIMIZATION_PERF
OPTIMIZATION_FLAGS = -O2
endif
ifdef CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE
CPPFLAGS += -DNDEBUG
endif
else # IS_BOOTLOADER_BUILD
ifdef CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE
OPTIMIZATION_FLAGS = -Os -freorder-blocks
endif
ifdef CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG
OPTIMIZATION_FLAGS = -Og
endif
ifdef CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE
OPTIMIZATION_FLAGS = -O0
endif
ifdef CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF
OPTIMIZATION_FLAGS = -O2
endif
endif # IS_BOOTLOADER_BUILD
# IDF uses some GNU extension from libc
CPPFLAGS += -D_GNU_SOURCE
# Enable generation of debugging symbols
# (we generate even in Release mode, as this has no impact on final binary size.)
DEBUG_FLAGS ?= -ggdb
# List of flags to pass to C compiler
# If any flags are defined in application Makefile, add them at the end.
CFLAGS ?=
EXTRA_CFLAGS ?=
CFLAGS := $(strip \
-std=gnu99 \
$(OPTIMIZATION_FLAGS) $(DEBUG_FLAGS) \
$(COMMON_FLAGS) \
$(COMMON_WARNING_FLAGS) -Wno-old-style-declaration \
$(CFLAGS) \
$(EXTRA_CFLAGS))
# List of flags to pass to C++ compiler
# If any flags are defined in application Makefile, add them at the end.
CXXFLAGS ?=
EXTRA_CXXFLAGS ?=
CXXFLAGS := $(strip \
-std=gnu++11 \
$(OPTIMIZATION_FLAGS) $(DEBUG_FLAGS) \
$(COMMON_FLAGS) \
$(COMMON_WARNING_FLAGS) \
$(CXXFLAGS) \
$(EXTRA_CXXFLAGS))
ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
CXXFLAGS += -fexceptions
else
CXXFLAGS += -fno-exceptions
endif
ifdef CONFIG_COMPILER_CXX_RTTI
CXXFLAGS += -frtti
else
CXXFLAGS += -fno-rtti
LDFLAGS += -fno-rtti
endif
ARFLAGS := cr
export CFLAGS CPPFLAGS CXXFLAGS ARFLAGS
# Set target compiler. Defaults to whatever the user has
# configured as prefix + ye olde gcc commands
CC := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))gcc
CXX := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))c++
LD := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))ld
AR := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))ar
OBJCOPY := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))objcopy
OBJDUMP := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))objdump
SIZE := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))size
export CC CXX LD AR OBJCOPY OBJDUMP SIZE
COMPILER_VERSION_STR := $(shell $(CC) -dumpversion)
COMPILER_VERSION_NUM := $(subst .,,$(COMPILER_VERSION_STR))
# the app is the main executable built by the project
APP_ELF:=$(BUILD_DIR_BASE)/$(PROJECT_NAME).elf
APP_MAP:=$(APP_ELF:.elf=.map)
APP_BIN:=$(APP_ELF:.elf=.bin)
# include linker script generation utils makefile
include $(IDF_PATH)/make/ldgen.mk
$(eval $(call ldgen_create_commands))
# Include any Makefile.projbuild file letting components add
# configuration at the project level
define includeProjBuildMakefile
ifeq ("$(V)","1")
$$(info including $(1)/Makefile.projbuild...)
endif
COMPONENT_PATH := $(1)
include $(1)/Makefile.projbuild
endef
$(foreach componentpath,$(COMPONENT_PATHS), \
$(if $(wildcard $(componentpath)/Makefile.projbuild), \
$(eval $(call includeProjBuildMakefile,$(componentpath)))))
# ELF depends on the library archive files for COMPONENT_LIBRARIES
# the rules to build these are emitted as part of GenerateComponentTarget below
#
# also depends on additional dependencies (linker scripts & binary libraries)
# stored in COMPONENT_LINKER_DEPS, built via component.mk files' COMPONENT_ADD_LINKER_DEPS variable
COMPONENT_LINKER_DEPS ?=
$(APP_ELF): $(foreach libcomp,$(COMPONENT_LIBRARIES),$(BUILD_DIR_BASE)/$(libcomp)/lib$(libcomp).a) $(COMPONENT_LINKER_DEPS) $(COMPONENT_PROJECT_VARS)
$(summary) LD $(patsubst $(PWD)/%,%,$@)
$(CC) $(LDFLAGS) -o $@ -Wl,-Map=$(APP_MAP)
ifdef CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME
SECURE_APPS_SIGNING_SCHEME = "1"
else ifdef CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
SECURE_APPS_SIGNING_SCHEME = "2"
endif
app: $(APP_BIN) partition_table_get_info
ifeq ("$(CONFIG_APP_BUILD_GENERATE_BINARIES)","y")
ifeq ("$(CONFIG_SECURE_BOOT)$(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)","y") # secure boot enabled, but remote sign app image
@echo "App built but not signed. Signing step via espsecure.py:"
@echo "espsecure.py sign_data --version $(SECURE_APPS_SIGNING_SCHEME) --keyfile KEYFILE $(APP_BIN)"
@echo "Then flash app command is:"
@echo $(ESPTOOLPY_WRITE_FLASH) $(APP_OFFSET) $(APP_BIN)
else
@echo "App built. Default flash app command is:"
@echo $(ESPTOOLPY_WRITE_FLASH) $(APP_OFFSET) $(APP_BIN)
endif
else
@echo "Application in not built and cannot be flashed."
endif
all_binaries: $(APP_BIN)
$(BUILD_DIR_BASE):
mkdir -p $(BUILD_DIR_BASE)
# Macro for the recursive sub-make for each component
# $(1) - component directory
# $(2) - component name only
#
# Is recursively expanded by the GenerateComponentTargets macro
define ComponentMake
+$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(IDF_PATH)/make/component_wrapper.mk COMPONENT_MAKEFILE=$(1)/component.mk COMPONENT_NAME=$(2)
endef
# Generate top-level component-specific targets for each component
# $(1) - path to component dir
# $(2) - name of component
#
define GenerateComponentTargets
.PHONY: component-$(2)-build component-$(2)-clean
COMPONENT_$(2)_BUILDTARGET ?= build
COMPONENT_$(2)_CLEANTARGET ?= clean
component-$(2)-build: check-submodules $(call prereq_if_explicit, component-$(2)-clean) | $(BUILD_DIR_BASE)/$(2)
$(call ComponentMake,$(1),$(2)) $$(COMPONENT_$(2)_BUILDTARGET)
component-$(2)-clean: | $(BUILD_DIR_BASE)/$(2) $(BUILD_DIR_BASE)/$(2)/component_project_vars.mk
$(call ComponentMake,$(1),$(2)) $$(COMPONENT_$(2)_CLEANTARGET)
$(BUILD_DIR_BASE)/$(2):
@mkdir -p $(BUILD_DIR_BASE)/$(2)
# tell make it can build any component's library by invoking the -build target
# (this target exists for all components even ones which don't build libraries, but it's
# only invoked for the targets whose libraries appear in COMPONENT_LIBRARIES and hence the
# APP_ELF dependencies.)
$(BUILD_DIR_BASE)/$(2)/lib$(2).a: component-$(2)-build
$(details) "Target '$$^' responsible for '$$@'" # echo which build target built this file
# add a target to generate the component_project_vars.mk files that
# are used to inject variables into project make pass (see matching
# component_project_vars.mk target in component_wrapper.mk).
#
# If any component_project_vars.mk file is out of date, the make
# process will call this target to rebuild it and then restart.
#
$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(SDKCONFIG_MAKEFILE) | $(BUILD_DIR_BASE)/$(2)
$(call ComponentMake,$(1),$(2)) component_project_vars.mk
endef
$(foreach component,$(COMPONENT_PATHS),$(eval $(call GenerateComponentTargets,$(component),$(notdir $(component)))))
$(foreach component,$(TEST_COMPONENT_PATHS),$(eval $(call GenerateComponentTargets,$(component),$(lastword $(subst /, ,$(dir $(component))))_test)))
app-clean: $(addprefix component-,$(addsuffix -clean,$(notdir $(COMPONENT_PATHS))))
$(summary) RM $(APP_ELF)
rm -f $(APP_ELF) $(APP_BIN) $(APP_MAP)
size: $(APP_ELF) | check_python_dependencies
$(PYTHON) $(IDF_PATH)/tools/idf_size.py $(APP_MAP)
size-files: $(APP_ELF) | check_python_dependencies
$(PYTHON) $(IDF_PATH)/tools/idf_size.py --files $(APP_MAP)
size-components: $(APP_ELF) | check_python_dependencies
$(PYTHON) $(IDF_PATH)/tools/idf_size.py --archives $(APP_MAP)
size-symbols: $(APP_ELF) | check_python_dependencies
ifndef COMPONENT
$(error "ERROR: Please enter the component to look symbols for, e.g. COMPONENT=heap")
else
$(PYTHON) $(IDF_PATH)/tools/idf_size.py --archive_details lib$(COMPONENT).a $(APP_MAP)
endif
# NB: this ordering is deliberate (app-clean & bootloader-clean before
# _config-clean), so config remains valid during all component clean
# targets
config-clean: app-clean bootloader-clean
clean: app-clean bootloader-clean config-clean ldgen-clean
# phony target to check if any git submodule listed in COMPONENT_SUBMODULES are missing
# or out of date, and exit if so. Components can add paths to this variable.
#
# This only works for components inside IDF_PATH
#
# For internal use:
# IDF_SKIP_CHECK_SUBMODULES may be set in the environment to skip the submodule check.
# This can be used e.g. in CI when submodules are checked out by different means.
IDF_SKIP_CHECK_SUBMODULES ?= 0
check-submodules:
ifeq ($(IDF_SKIP_CHECK_SUBMODULES),1)
@echo "skip submodule check on internal CI"
else
# Check if .gitmodules exists, otherwise skip submodule check, assuming flattened structure
ifneq ("$(wildcard ${IDF_PATH}/.gitmodules)","")
# Dump the git status for the whole working copy once, then grep it for each submodule. This saves a lot of time on Windows.
GIT_STATUS := $(shell cd ${IDF_PATH} && git status --porcelain --ignore-submodules=dirty)
# Generate a target to check this submodule
# $(1) - submodule directory, relative to IDF_PATH
define GenerateSubmoduleCheckTarget
check-submodules: $(IDF_PATH)/$(1)/.git
$(IDF_PATH)/$(1)/.git:
@echo "WARNING: Missing submodule $(1)..."
[ -e ${IDF_PATH}/.git ] || { echo "ERROR: esp-idf must be cloned from git to work."; exit 1; }
[ -x "$(shell which git)" ] || { echo "ERROR: Need to run 'git submodule init $(1)' in esp-idf root directory."; exit 1; }
@echo "Attempting 'git submodule update --init $(1)' in esp-idf root directory..."
cd ${IDF_PATH} && git submodule update --init $(1)
# Parse 'git status' output to check if the submodule commit is different to expected
ifneq ("$(filter $(1),$(GIT_STATUS))","")
$$(info WARNING: esp-idf git submodule $(1) may be out of date. Run 'git submodule update' in IDF_PATH dir to update.)
endif
endef
# filter/subst in expression ensures all submodule paths begin with $(IDF_PATH), and then strips that prefix
# so the argument is suitable for use with 'git submodule' commands
$(foreach submodule,$(subst $(IDF_PATH)/,,$(filter $(IDF_PATH)/%,$(COMPONENT_SUBMODULES))),$(eval $(call GenerateSubmoduleCheckTarget,$(submodule))))
endif # End check for .gitmodules existence
endif # End check for IDF_SKIP_CHECK_SUBMODULES
# PHONY target to list components in the build and their paths
list-components:
$(info $(call dequote,$(SEPARATOR)))
$(info COMPONENT_DIRS (components searched for here))
$(foreach cd,$(COMPONENT_DIRS),$(info $(cd)))
$(info $(call dequote,$(SEPARATOR)))
$(info TEST_COMPONENTS (list of test component names))
$(info $(TEST_COMPONENTS_LIST))
$(info $(call dequote,$(SEPARATOR)))
$(info TEST_EXCLUDE_COMPONENTS (list of test excluded names))
$(info $(if $(EXCLUDE_COMPONENTS) || $(TEST_EXCLUDE_COMPONENTS),$(EXCLUDE_COMPONENTS) $(TEST_EXCLUDE_COMPONENTS),(none provided)))
$(info $(call dequote,$(SEPARATOR)))
$(info COMPONENT_PATHS (paths to all components):)
$(foreach cp,$(COMPONENT_PATHS),$(info $(cp)))
# print flash command, so users can dump this to config files and download somewhere without idf
print_flash_cmd: partition_table_get_info blank_ota_data
echo $(ESPTOOL_WRITE_FLASH_OPTIONS) $(ESPTOOL_ALL_FLASH_ARGS) | sed -e 's:'$(PWD)/build/'::g'
# Check toolchain version using the output of xtensa-esp32-elf-gcc --version command.
# The output normally looks as follows
# xtensa-esp32-elf-gcc (crosstool-NG crosstool-ng-1.22.0-80-g6c4433a) 5.2.0
# The part in brackets is extracted into TOOLCHAIN_COMMIT_DESC variable
ifdef CONFIG_SDK_TOOLPREFIX
ifndef MAKE_RESTARTS
TOOLCHAIN_HEADER := $(shell $(CC) --version | head -1)
TOOLCHAIN_PATH := $(shell which $(CC))
TOOLCHAIN_COMMIT_DESC := $(shell $(CC) --version | sed -E -n 's|.*\(crosstool-NG (.*)\).*|\1|gp')
TOOLCHAIN_GCC_VER := $(COMPILER_VERSION_STR)
# Officially supported version(s)
include $(IDF_PATH)/tools/toolchain_versions.mk
ifndef IS_BOOTLOADER_BUILD
$(info Toolchain path: $(TOOLCHAIN_PATH))
endif
ifdef TOOLCHAIN_COMMIT_DESC
ifeq (,$(findstring $(SUPPORTED_TOOLCHAIN_COMMIT_DESC),$(TOOLCHAIN_COMMIT_DESC)))
$(info WARNING: Toolchain version is not supported: $(TOOLCHAIN_COMMIT_DESC))
$(info Expected to see version: $(SUPPORTED_TOOLCHAIN_COMMIT_DESC))
$(info Please check ESP-IDF setup instructions and update the toolchain, or proceed at your own risk.)
else
ifndef IS_BOOTLOADER_BUILD
$(info Toolchain version: $(TOOLCHAIN_COMMIT_DESC))
endif
endif
ifeq (,$(findstring $(TOOLCHAIN_GCC_VER), $(SUPPORTED_TOOLCHAIN_GCC_VERSIONS)))
$(info WARNING: Compiler version is not supported: $(TOOLCHAIN_GCC_VER))
$(info Expected to see version(s): $(SUPPORTED_TOOLCHAIN_GCC_VERSIONS))
$(info Please check ESP-IDF setup instructions and update the toolchain, or proceed at your own risk.)
else
ifndef IS_BOOTLOADER_BUILD
$(info Compiler version: $(TOOLCHAIN_GCC_VER))
endif
endif
else
$(info WARNING: Failed to find Xtensa toolchain, may need to alter PATH or set one in the configuration menu)
endif # TOOLCHAIN_COMMIT_DESC
endif #MAKE_RESTARTS
endif #CONFIG_SDK_TOOLPREFIX
#####################################################################
endif #CONFIG_IDF_TARGET

View File

@ -1,182 +0,0 @@
# Makefile support for the menuconfig system
#Find all Kconfig files for all components
COMPONENT_KCONFIGS := $(foreach component,$(COMPONENT_PATHS),$(wildcard $(component)/Kconfig))
COMPONENT_KCONFIGS_PROJBUILD := $(foreach component,$(COMPONENT_PATHS),$(wildcard $(component)/Kconfig.projbuild))
COMPONENT_SDKCONFIG_RENAMES := $(foreach component,$(COMPONENT_PATHS),$(wildcard $(component)/sdkconfig.rename))
COMPONENT_KCONFIGS_SOURCE_FILE:=$(BUILD_DIR_BASE)/kconfigs.in
COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE:=$(BUILD_DIR_BASE)/kconfigs_projbuild.in
ifeq ($(OS),Windows_NT)
# kconfiglib requires Windows-style paths for kconfig files
COMPONENT_KCONFIGS := $(shell cygpath -m $(COMPONENT_KCONFIGS))
COMPONENT_KCONFIGS_PROJBUILD := $(shell cygpath -m $(COMPONENT_KCONFIGS_PROJBUILD))
COMPONENT_SDKCONFIG_RENAMES := $(shell cygpath -m $(COMPONENT_SDKCONFIG_RENAMES))
COMPONENT_KCONFIGS_SOURCE_FILE := $(shell cygpath -m $(COMPONENT_KCONFIGS_SOURCE_FILE))
COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE := $(shell cygpath -m $(COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE))
endif
#For doing make menuconfig etc
KCONFIG_TOOL_DIR=$(IDF_PATH)/tools/kconfig
# set SDKCONFIG to the project's sdkconfig,
# unless it's overriden (happens for bootloader)
SDKCONFIG ?= $(PROJECT_PATH)/sdkconfig
SDKCONFIG_RENAME ?= $(IDF_PATH)/sdkconfig.rename
# SDKCONFIG_DEFAULTS is an optional file containing default
# overrides (usually used for esp-idf examples)
SDKCONFIG_DEFAULTS ?= $(PROJECT_PATH)/sdkconfig.defaults
# Workaround to run make parallel (-j). mconf-idf and conf-idf cannot be made simultaneously
$(KCONFIG_TOOL_DIR)/mconf-idf: $(KCONFIG_TOOL_DIR)/conf-idf
# reset MAKEFLAGS as the menuconfig makefile uses implicit compile rules
$(KCONFIG_TOOL_DIR)/mconf-idf $(KCONFIG_TOOL_DIR)/conf-idf: $(wildcard $(KCONFIG_TOOL_DIR)/*.c) $(wildcard $(KCONFIG_TOOL_DIR)/*.y)
ifeq ($(OS),Windows_NT)
# mconf-idf is used only in MSYS
MAKEFLAGS="" CC=$(HOSTCC) LD=$(HOSTLD) \
$(MAKE) -C $(KCONFIG_TOOL_DIR)
else
@echo "mconf-idf is not required on this platform"
endif
ifeq ("$(wildcard $(SDKCONFIG))","")
# if no configuration file is present we need a rule for it
ifeq ("$(filter $(NON_INTERACTIVE_TARGET), $(MAKECMDGOALS))","")
# if special non-interactive item is not a named target (eg. 'defconfig', 'clean')
# run defconfig then menuconfig to get the initial config
$(SDKCONFIG): menuconfig
menuconfig: defconfig
else
# otherwise, just run defconfig
$(SDKCONFIG): defconfig
endif
endif
ifeq ("$(PYTHON)","")
# fallback value when menuconfig is called without a build directory and sdkconfig file
PYTHON=python
endif
SDKCONFIG_DEFAULTS_FILES := $(foreach f,$(SDKCONFIG_DEFAULTS),$(wildcard $(f)))
# for each sdkconfig.defaults file, also add sdkconfig.defaults.IDF_TARGET, if it exists
SDKCONFIG_DEFAULTS_FILES += $(foreach f,$(SDKCONFIG_DEFAULTS_FILES),$(wildcard $(f).$(IDF_TARGET)))
ifeq ($(OS),Windows_NT)
# -i is for ignore missing arguments in case SDKCONFIG_DEFAULTS_FILES is empty
SDKCONFIG_DEFAULTS_FILES := $(shell cygpath -i -m $(SDKCONFIG_DEFAULTS_FILES))
endif
DEFAULTS_ARG := $(foreach f,$(SDKCONFIG_DEFAULTS_FILES),--defaults $(f))
prepare_kconfig_files:
mkdir -p $(BUILD_DIR_BASE)
$(PYTHON) $(IDF_PATH)/tools/kconfig_new/prepare_kconfig_files.py \
--env "COMPONENT_KCONFIGS=$(strip $(COMPONENT_KCONFIGS))" \
--env "COMPONENT_KCONFIGS_PROJBUILD=$(strip $(COMPONENT_KCONFIGS_PROJBUILD))" \
--env "COMPONENT_KCONFIGS_SOURCE_FILE=$(COMPONENT_KCONFIGS_SOURCE_FILE)" \
--env "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE=$(COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE)"
# macro for running confgen.py
define RunConfGen
mkdir -p $(BUILD_DIR_BASE)/include/config
$(PYTHON) $(IDF_PATH)/tools/kconfig_new/confgen.py \
--kconfig $(IDF_PATH)/Kconfig \
--config $(SDKCONFIG) \
--sdkconfig-rename $(SDKCONFIG_RENAME) \
--env "COMPONENT_KCONFIGS=$(strip $(COMPONENT_KCONFIGS))" \
--env "COMPONENT_KCONFIGS_PROJBUILD=$(strip $(COMPONENT_KCONFIGS_PROJBUILD))" \
--env "COMPONENT_KCONFIGS_SOURCE_FILE=$(COMPONENT_KCONFIGS_SOURCE_FILE)" \
--env "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE=$(COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE)" \
--env "COMPONENT_SDKCONFIG_RENAMES=$(strip $(COMPONENT_SDKCONFIG_RENAMES))" \
--env "IDF_CMAKE=n" \
--env "IDF_ENV_FPGA=n" \
$(DEFAULTS_ARG) \
--output config ${SDKCONFIG} \
--output makefile $(SDKCONFIG_MAKEFILE) \
--output header $(BUILD_DIR_BASE)/include/sdkconfig.h \
$1
endef
export MENUCONFIG_STYLE ?= aquatic
ifeq ($(OS),Windows_NT)
MENUCONFIG_CMD := $(KCONFIG_TOOL_DIR)/mconf-idf
else
MENUCONFIG_CMD := $(PYTHON) -m menuconfig
endif
.PHONY: term_check
term_check:
ifneq ($(OS),Windows_NT)
${PYTHON} ${IDF_PATH}/tools/check_term.py
endif
# macro for running menuconfig
define RunMenuConf
mkdir -p $(BUILD_DIR_BASE)/include/config
cd $(BUILD_DIR_BASE); KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfig.h) \
KCONFIG_CONFIG=$(SDKCONFIG) \
COMPONENT_KCONFIGS_SOURCE_FILE="$(COMPONENT_KCONFIGS_SOURCE_FILE)" \
COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE="$(COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE)" \
IDF_CMAKE=n \
IDF_ENV_FPGA=n \
$(MENUCONFIG_CMD) $(IDF_PATH)/Kconfig
endef
ifndef MAKE_RESTARTS
# menuconfig, defconfig and "GENCONFIG" configuration generation only
# ever run on the first make pass, subsequent passes don't run these
# (make often wants to re-run them as the conf tool can regenerate the
# sdkconfig input file as an output file, but this is not what the
# user wants - a single config pass is enough to produce all output
# files.)
#
# To prevent problems missing genconfig, ensure none of these targets
# depend on any prerequisite that may cause a make restart as part of
# the prerequisite's own recipe.
menuconfig: $(KCONFIG_TOOL_DIR)/mconf-idf | check_python_dependencies term_check prepare_kconfig_files
$(summary) MENUCONFIG
ifdef BATCH_BUILD
@echo "Can't run interactive configuration inside non-interactive build process."
@echo ""
@echo "Open a command line terminal and run 'make menuconfig' from there."
@echo "See esp-idf documentation for more details."
@exit 1
else
$(call RunConfGen,--dont-write-deprecated)
# RunConfGen before menuconfig ensures that deprecated options won't be ignored (they've got renamed)
$(call RunMenuConf)
# RunConfGen after menuconfig ensures that deprecated options are appended to $(SDKCONFIG) for backward compatibility
$(call RunConfGen,)
endif
# defconfig creates a default config, based on SDKCONFIG_DEFAULTS if present
defconfig: | check_python_dependencies prepare_kconfig_files
$(summary) DEFCONFIG
$(call RunConfGen,)
# if neither defconfig or menuconfig are requested, use the GENCONFIG rule to
# ensure generated config files are up to date
$(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) | check_python_dependencies prepare_kconfig_files $(call prereq_if_explicit,defconfig) $(call prereq_if_explicit,menuconfig)
$(summary) GENCONFIG
$(call RunConfGen,)
touch $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h # ensure newer than sdkconfig
else # "$(MAKE_RESTARTS)" != ""
# on subsequent make passes, skip config generation entirely
defconfig:
menuconfig:
endif
.PHONY: config-clean defconfig menuconfig
config-clean:
$(summary) RM CONFIG
ifeq ($(OS),Windows_NT)
MAKEFLAGS="" $(MAKE) -C $(KCONFIG_TOOL_DIR) clean
endif
rm -rf $(BUILD_DIR_BASE)/include/config $(BUILD_DIR_BASE)/include/sdkconfig.h \
$(COMPONENT_KCONFIGS_SOURCE_FILE) $(COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE)

View File

@ -1,3 +0,0 @@
IDF_VERSION_MAJOR := 5
IDF_VERSION_MINOR := 0
IDF_VERSION_PATCH := 0

Some files were not shown because too many files have changed in this diff Show More