mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
examples: generic cmake support examples
This commit is contained in:
parent
0908fba1a3
commit
90f5432f2a
5
.gitmodules
vendored
5
.gitmodules
vendored
@ -61,6 +61,11 @@
|
||||
[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
|
||||
|
@ -15,6 +15,7 @@ The examples are grouped into subdirectories by category. Each category director
|
||||
* `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
|
||||
|
||||
|
24
examples/build_system/cmake/idf_as_lib/CMakeLists.txt
Normal file
24
examples/build_system/cmake/idf_as_lib/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
||||
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}")
|
69
examples/build_system/cmake/idf_as_lib/README.md
Normal file
69
examples/build_system/cmake/idf_as_lib/README.md
Normal file
@ -0,0 +1,69 @@
|
||||
# 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`
|
8
examples/build_system/cmake/idf_as_lib/build.sh
Executable file
8
examples/build_system/cmake/idf_as_lib/build.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/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 .
|
39
examples/build_system/cmake/idf_as_lib/main.c
Normal file
39
examples/build_system/cmake/idf_as_lib/main.c
Normal file
@ -0,0 +1,39 @@
|
||||
/* 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();
|
||||
}
|
6
examples/build_system/cmake/import_lib/CMakeLists.txt
Normal file
6
examples/build_system/cmake/import_lib/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
# 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)
|
36
examples/build_system/cmake/import_lib/README.md
Normal file
36
examples/build_system/cmake/import_lib/README.md
Normal file
@ -0,0 +1,36 @@
|
||||
# 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`
|
21
examples/build_system/cmake/import_lib/main/CMakeLists.txt
Normal file
21
examples/build_system/cmake/import_lib/main/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
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)
|
@ -0,0 +1 @@
|
||||
Subproject commit 7e8e249990ec491ec15990cf95b6d871a66cf64a
|
72
examples/build_system/cmake/import_lib/main/main.cpp
Normal file
72
examples/build_system/cmake/import_lib/main/main.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
#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");
|
||||
}
|
7
examples/build_system/cmake/import_lib/main/sample.xml
Normal file
7
examples/build_system/cmake/import_lib/main/sample.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?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>
|
@ -0,0 +1,6 @@
|
||||
# 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,
|
|
@ -0,0 +1,5 @@
|
||||
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
|
@ -3,4 +3,4 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(hello-world)
|
||||
project(hello-world)
|
@ -2,6 +2,6 @@ set(COMPONENT_SRCS "native_ota_example.c")
|
||||
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()
|
||||
|
@ -3,6 +3,6 @@ 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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user