[submodule "components/protobuf-c/protobuf-c"]
path = components/protobuf-c/protobuf-c
url = https://github.com/protobuf-c/protobuf-c
+
[submodule "components/unity/unity"]
path = components/unity/unity
url = https://github.com/ThrowTheSwitch/Unity
+
+[submodule "examples/build_system/cmake/import_lib/main/lib/tinyxml2"]
+ path = examples/build_system/cmake/import_lib/main/lib/tinyxml2
+ url = https://github.com/leethomason/tinyxml2
* `storage` contains examples showing data storage methods using SPI flash or external storage like the SD/MMC interface.
* `system` contains examples which demonstrate some internal chip features, or debugging & development tools.
* `wifi` contains examples of advanced Wi-Fi features. (For network protocol examples, see `protocols` instead.)
+* `build_system` contains examples of build system features
# Using Examples
--- /dev/null
+cmake_minimum_required(VERSION 3.5)
+project(idf_as_lib C)
+
+# The source file main.c contains app_main() definition
+add_executable(${CMAKE_PROJECT_NAME}.elf main.c)
+
+# Provides idf_import_components() and idf_link_components()
+include($ENV{IDF_PATH}/tools/cmake/idf_functions.cmake)
+
+# Create artifacts used for flashing the project to target chip
+set(IDF_BUILD_ARTIFACTS ON)
+set(IDF_PROJECT_EXECUTABLE ${CMAKE_PROJECT_NAME}.elf)
+set(IDF_BUILD_ARTIFACTS_DIR ${CMAKE_BINARY_DIR})
+
+# Trim down components included in the build. Although freertos and spi_flash are the ones needed by the application
+# itself, the bootloader and esptool_py components are also needed in order to create the artifacts to be used
+# for flashing to the target chip
+set(IDF_COMPONENTS freertos spi_flash bootloader esptool_py)
+
+# Wraps add_subdirectory() to create library targets for components, and then return them using the specified variable
+idf_import_components(components $ENV{IDF_PATH} esp-idf)
+
+# Wraps target_link_libraries() to link processed components by idf_import_components to target
+idf_link_components(${CMAKE_PROJECT_NAME}.elf "${components}")
\ No newline at end of file
--- /dev/null
+# Using ESP-IDF in Custom CMake Projects
+
+This example illustrates using ESP-IDF components as libraries in custom CMake projects. This builds
+an equivalent application to the `hello_world` example under `examples/get-started/hello_world`.
+
+## Example Flow
+
+Users looking at this example should focus on the [top-level CMakeLists.txt file](./CMakeLists.txt). This builds an
+application that can run on targets without relying on the typical ESP-IDF application template. The application itself
+follows a similar code flow to the aforementioned `hello_world` example.
+
+### Output
+
+```
+Hello world!
+This is ESP32 chip with 2 CPU cores, WiFi/BT/BLE, silicon revision 0, 4MB external flash
+Restarting in 10 seconds...
+Restarting in 9 seconds...
+Restarting in 8 seconds...
+Restarting in 7 seconds...
+Restarting in 6 seconds...
+Restarting in 5 seconds...
+Restarting in 4 seconds...
+Restarting in 3 seconds...
+Restarting in 2 seconds...
+Restarting in 1 seconds...
+Restarting in 0 seconds...
+```
+
+## Building this Example
+
+To build this example, run the following commands from this directory:
+
+```bash
+# Create a build directory, and change location to that directory.
+mkdir build; cd build
+# Invoke CMake, specifying the top-level CMakeLists.txt directory and toolchain file to use. This will generate
+# the build system files.
+cmake .. -DCMAKE_TOOLCHAIN_FILE=$IDF_PATH/tools/cmake/toolchain-esp32.cmake -DIDF_TARGET=esp32
+# Build using the generated build system files.
+cmake --build .
+```
+
+Or, execute `build.sh` script, which contains the same commands mentioned above.
+
+## Flashing and Running this Example
+
+To flash this example, we will have to invoke `esptool.py` and `idf_monitor.py` manually. While still in the build directory:
+
+### Flashing to target
+
+```bash
+# Write project binaries to flash.
+esptool.py --port /dev/ttyUSB0 write_flash @flash_project_args
+```
+
+### Running on target
+
+```bash
+# Monitor the output of the flashed firmware.
+idf_monitor.py --port /dev/ttyUSB0 idf_as_lib.elf
+```
+
+Of course, you should replace the specified ports in the commands specified above to the proper one where your device
+is connected.
+
+---
+
+There is a discussion on using ESP-IDF in custom CMake projects in the programming guide under `API Guides` -> `Build System (CMake)` -> `Using ESP-IDF in Custom CMake Projects`
--- /dev/null
+#!/bin/bash
+#
+# Build this example, which does not use that standard IDF app template. See README.md for
+# more information about the build and how to run this example on the target once built.
+
+mkdir build; cd build
+cmake .. -DCMAKE_TOOLCHAIN_FILE=$IDF_PATH/tools/cmake/toolchain-esp32.cmake -DIDF_TARGET=esp32
+cmake --build .
\ No newline at end of file
--- /dev/null
+/* Hello World Example
+
+ This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+ Unless required by applicable law or agreed to in writing, this
+ software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, either express or implied.
+*/
+#include <stdio.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "esp_system.h"
+#include "esp_spi_flash.h"
+
+void app_main()
+{
+ printf("Hello world!\n");
+
+ /* Print chip information */
+ esp_chip_info_t chip_info;
+ esp_chip_info(&chip_info);
+ printf("This is ESP32 chip with %d CPU cores, WiFi%s%s, ",
+ chip_info.cores,
+ (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
+ (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
+
+ printf("silicon revision %d, ", chip_info.revision);
+
+ printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
+ (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
+
+ for (int i = 10; i >= 0; i--) {
+ printf("Restarting in %d seconds...\n", i);
+ vTaskDelay(1000 / portTICK_PERIOD_MS);
+ }
+ printf("Restarting now.\n");
+ fflush(stdout);
+ esp_restart();
+}
--- /dev/null
+# The following lines of boilerplate have to be in your project's
+# CMakeLists in this exact order for cmake to work correctly
+cmake_minimum_required(VERSION 3.5)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(import_cmake_lib)
--- /dev/null
+# Import Third-Party CMake Library Example
+
+This example demonstrates how to import third-party CMake libraries.
+
+## Example Flow
+
+[tinyxml2](https://github.com/leethomason/tinyxml2) is a
+a small C++ XML parser. It is imported, without modification, for use in the project's `main` component (see the `main` component's [CMakeLists.txt](main/CMakeLists.txt)). To demonstrate the library being used, a sample XML is embedded into the project.
+This sample XML is then read and parsed later on using `tinyxml2`.
+
+### Output
+
+```
+I (317) example: Setting up...
+I (317) example: Copying sample XML to filesystem...
+I (647) example: Reading XML file
+I (657) example: Read XML data:
+<?xml version="1.0" encoding="UTF-8"?>
+<note>
+ <to>Tove</to>
+ <from>Jani</from>
+ <heading>Reminder</heading>
+ <body>Don't forget me this weekend!</body>
+</note>
+
+I (667) example: Parsed XML data:
+
+To: Tove
+From: Jani
+Heading: Reminder
+Body: Don't forget me this weekend!
+I (677) example: Example end
+```
+---
+
+There is a discussion on importing third-party CMake libraries in the programming guide under `API Guides` -> `Build System (CMake)` -> `Using Third-Party CMake Projects with Components`
--- /dev/null
+set(COMPONENT_SRCS "main.cpp")
+set(COMPONENT_ADD_INCLUDEDIRS ".")
+
+set(COMPONENT_EMBED_TXTFILES "sample.xml")
+
+register_component()
+
+# Build static library, do not build test executables
+option(BUILD_SHARED_LIBS OFF)
+option(BUILD_TESTING OFF)
+
+# Import tinyxml2 targets
+add_subdirectory(lib/tinyxml2)
+
+# Propagate compile settings to tinyxml2
+target_include_directories(tinyxml2 PRIVATE ${IDF_INCLUDE_DIRECTORIES})
+target_compile_options(tinyxml2 PRIVATE "${IDF_COMPILE_OPTIONS}")
+target_compile_options(tinyxml2 PRIVATE "${IDF_CXX_COMPILE_OPTIONS}")
+
+# Link tinyxml2 to main component
+target_link_libraries(${COMPONENT_TARGET} tinyxml2)
--- /dev/null
+Subproject commit 7e8e249990ec491ec15990cf95b6d871a66cf64a
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <sys/unistd.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+#include "esp_err.h"
+#include "esp_log.h"
+#include "esp_vfs_fat.h"
+#include "lib/tinyxml2/tinyxml2.h"
+
+using namespace tinyxml2;
+
+static const char *TAG = "example";
+
+// Handle of the wear levelling library instance
+static wl_handle_t s_wl_handle = WL_INVALID_HANDLE;
+
+// Mount path for the partition
+const char *base_path = "/spiflash";
+
+extern "C" void app_main(void)
+{
+ // Do example setup
+ ESP_LOGI(TAG, "Setting up...");
+ esp_vfs_fat_mount_config_t mount_config;
+ mount_config.max_files = 4;
+ mount_config.format_if_mount_failed = true;
+ mount_config.allocation_unit_size = CONFIG_WL_SECTOR_SIZE;
+
+ esp_err_t err = esp_vfs_fat_spiflash_mount(base_path, "storage", &mount_config, &s_wl_handle);
+ if (err != ESP_OK) {
+ ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
+ return;
+ }
+
+ // The sample XML is embedded binary data. Create a file first containing the embedded
+ // so it can be accessed.
+ ESP_LOGI(TAG, "Copying sample XML to filesystem...");
+
+ extern const char data_start[] asm("_binary_sample_xml_start");
+ extern const char data_end[] asm("_binary_sample_xml_end");
+ FILE *f = fopen("/spiflash/sample.xml", "wb");
+
+ if (f == NULL) {
+ ESP_LOGE(TAG, "Failed to open file for writing");
+ return;
+ }
+ fwrite(data_start, sizeof(char), data_end - data_start + 1, f);
+ fclose(f);
+
+ // Now that the file is created, load it using tinyxml2 and parse
+ ESP_LOGI(TAG, "Reading XML file");
+
+ XMLDocument data;
+ data.LoadFile("/spiflash/sample.xml");
+
+ XMLPrinter printer;
+ data.Print(&printer);
+
+ ESP_LOGI(TAG, "Read XML data:\n%s", printer.CStr());
+
+ const char* to_data = data.FirstChildElement("note")->FirstChildElement("to")->GetText();
+ const char* from_data = data.FirstChildElement("note")->FirstChildElement("from")->GetText();
+ const char* heading_data = data.FirstChildElement("note")->FirstChildElement("heading")->GetText();
+ const char* body_data = data.FirstChildElement("note")->FirstChildElement("body")->GetText();
+
+ ESP_LOGI(TAG, "Parsed XML data:\n\nTo: %s\nFrom: %s\nHeading: %s\nBody: %s",
+ to_data, from_data, heading_data, body_data);
+
+ ESP_LOGI(TAG, "Example end");
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<note>
+ <to>Tove</to>
+ <from>Jani</from>
+ <heading>Reminder</heading>
+ <body>Don't forget me this weekend!</body>
+</note>
\ No newline at end of file
--- /dev/null
+# Name, Type, SubType, Offset, Size, Flags
+# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
+nvs, data, nvs, 0x9000, 0x6000,
+phy_init, data, phy, 0xf000, 0x1000,
+factory, app, factory, 0x10000, 1M,
+storage, data, fat, , 528K,
--- /dev/null
+CONFIG_PARTITION_TABLE_CUSTOM=y
+CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv"
+CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET=0x10000
+CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv"
+CONFIG_APP_OFFSET=0x10000
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
-project(hello-world)
+project(hello-world)
\ No newline at end of file
set(COMPONENT_ADD_INCLUDEDIRS ".")
# Embed the server root certificate into the final binary
-set(COMPONENT_EMBED_TXTFILES ${PROJECT_PATH}/server_certs/ca_cert.pem)
+set(COMPONENT_EMBED_TXTFILES ${IDF_PROJECT_PATH}/server_certs/ca_cert.pem)
register_component()
# Embed the server root certificate into the final binary
-set(COMPONENT_EMBED_TXTFILES ${PROJECT_PATH}/server_certs/ca_cert.pem)
+set(COMPONENT_EMBED_TXTFILES ${IDF_PROJECT_PATH}/server_certs/ca_cert.pem)
register_component()