Merge remote-tracking branch 'origin/master' into feature/github-7022

This commit is contained in:
Zim Kalinowski
2021-10-03 12:25:39 +08:00
3914 changed files with 690484 additions and 137878 deletions

View File

@@ -12,8 +12,9 @@ def test_examples_app_trace_to_host(env, extra_data):
dut = env.get_dut('app_trace_to_host', rel_project_path)
idf_path = dut.app.get_sdk_path()
proj_path = os.path.join(idf_path, rel_project_path)
oocd_log_path = os.path.join(proj_path, 'openocd.log')
with ttfw_idf.OCDBackend(os.path.join(proj_path, 'openocd.log'), dut.app.target) as ocd:
with ttfw_idf.OCDBackend(oocd_log_path, dut.app.target) as ocd:
dut.start_app()
dut.expect_all('example: Enabling ADC1 on channel 6 / GPIO34.',
'example: Enabling CW generator on DAC channel 1',
@@ -27,6 +28,15 @@ def test_examples_app_trace_to_host(env, extra_data):
ocd.apptrace_start('file://adc.log 0 9000 5 0 0')
ocd.apptrace_wait_stop(tmo=30)
with open(oocd_log_path) as oocd_log:
cores = 1 if dut.app.get_sdkconfig().get('CONFIG_FREERTOS_UNICORE', '').replace('"','') == 'y' else 2
params_str = 'App trace params: from {} cores'.format(cores)
for line in oocd_log:
if params_str in line:
break
else:
raise RuntimeError('"{}" could not be found in {}'.format(params_str, oocd_log_path))
with ttfw_idf.CustomProcess(' '.join([os.path.join(idf_path, 'tools/esp_app_trace/logtrace_proc.py'),
'adc.log',
os.path.join(dut.app.binary_path, 'app_trace_to_host.elf')]),

View File

@@ -1,5 +1,5 @@
# Enable application tracing by default
CONFIG_APPTRACE_DEST_TRAX=y
CONFIG_APPTRACE_DEST_JTAG=y
CONFIG_APPTRACE_ENABLE=y
# Disable WiFi stack by default
CONFIG_WIFI_ENABLED=n

View File

@@ -1,3 +0,0 @@
# IDF-3090
CONFIG_ESP32C3_REV_MIN_0=y
CONFIG_ESP32C3_REV_MIN=0

View File

@@ -0,0 +1,22 @@
# type: ignore
from __future__ import print_function
import ttfw_idf
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3'])
def test_examples_system_console_advanced(env, _):
dut = env.get_dut('console_example', 'examples/system/console/advanced', app_config_name='history')
print('Using binary path: {}'.format(dut.app.binary_path))
dut.start_app()
dut.expect('Command history enabled')
env.close_dut(dut.name)
dut = env.get_dut('console_example', 'examples/system/console/advanced', app_config_name='nohistory')
print('Using binary path: {}'.format(dut.app.binary_path))
dut.start_app()
dut.expect('Command history disabled')
if __name__ == '__main__':
test_examples_system_console_advanced()

View File

@@ -121,6 +121,9 @@ static void initialize_console(void)
/* Set command history size */
linenoiseHistorySetMaxLen(100);
/* Set command maximum length */
linenoiseSetMaxLineLen(console_config.max_cmdline_length);
/* Don't return empty lines */
linenoiseAllowEmpty(false);

View File

@@ -0,0 +1 @@
CONFIG_STORE_HISTORY=y

View File

@@ -0,0 +1 @@
CONFIG_STORE_HISTORY=n

View File

@@ -0,0 +1,8 @@
# 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)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/system/console/advanced/components)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(console)

View File

@@ -0,0 +1,10 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := console
EXTRA_COMPONENT_DIRS := $(IDF_PATH)/examples/system/console/advanced/components
include $(IDF_PATH)/make/project.mk

View File

@@ -0,0 +1,151 @@
# Console Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example illustrates the usage of the [Console Component](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/console.html#console) to create an interactive shell on the ESP chip. The interactive shell running on the ESP chip can then be controlled/interacted with over a serial port (UART).
The interactive shell implemented in this example contains a wide variety of commands, and can act as a basis for applications that require a command-line interface (CLI).
## How to use example
### Hardware Required
This example should be able to run on any commonly available Espressif development board.
### Configure the project
```
idf.py menuconfig
```
* Enable/disable `Example Configuration > Store command history in flash` as necessary
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT flash monitor
```
(Replace PORT with the name of the serial port to use.)
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Example Output
Enter the `help` command get a full list of all available commands. The following is a sample session of the Console Example where a variety of commands provided by the Console Example are used. Note that GPIO15 is connected to GND to remove the boot log output.
```
This is an example of ESP-IDF console component.
Type 'help' to get the list of commands.
Use UP/DOWN arrows to navigate through command history.
Press TAB when typing command name to auto-complete.
[esp32]> help
help
Print the list of registered commands
free
Get the total size of heap memory available
restart
Restart the program
deep_sleep [-t <t>] [--io=<n>] [--io_level=<0|1>]
Enter deep sleep mode. Two wakeup modes are supported: timer and GPIO. If no
wakeup option is specified, will sleep indefinitely.
-t, --time=<t> Wake up time, ms
--io=<n> If specified, wakeup using GPIO with given number
--io_level=<0|1> GPIO level to trigger wakeup
join [--timeout=<t>] <ssid> [<pass>]
Join WiFi AP as a station
--timeout=<t> Connection timeout, ms
<ssid> SSID of AP
<pass> PSK of AP
[esp32]> free
257200
[esp32]> deep_sleep -t 1000
I (146929) deep_sleep: Enabling timer wakeup, timeout=1000000us
I (619) heap_init: Initializing. RAM available for dynamic allocation:
I (620) heap_init: At 3FFAE2A0 len 00001D60 (7 KiB): DRAM
I (626) heap_init: At 3FFB7EA0 len 00028160 (160 KiB): DRAM
I (645) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
I (664) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (684) heap_init: At 40093EA8 len 0000C158 (48 KiB): IRAM
This is an example of ESP-IDF console component.
Type 'help' to get the list of commands.
Use UP/DOWN arrows to navigate through command history.
Press TAB when typing command name to auto-complete.
[esp32]> join --timeout 10000 test_ap test_password
I (182639) connect: Connecting to 'test_ap'
I (184619) connect: Connected
[esp32]> free
212328
[esp32]> restart
I (205639) restart: Restarting
I (616) heap_init: Initializing. RAM available for dynamic allocation:
I (617) heap_init: At 3FFAE2A0 len 00001D60 (7 KiB): DRAM
I (623) heap_init: At 3FFB7EA0 len 00028160 (160 KiB): DRAM
I (642) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
I (661) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (681) heap_init: At 40093EA8 len 0000C158 (48 KiB): IRAM
This is an example of ESP-IDF console component.
Type 'help' to get the list of commands.
Use UP/DOWN arrows to navigate through command history.
Press TAB when typing command name to auto-complete.
[esp32]>
```
## Troubleshooting
### Line Endings
The line endings in the Console Example are configured to match particular serial monitors. Therefore, if the following log output appears, consider using a different serial monitor (e.g. Putty for Windows) or modify the example's [UART configuration](#Configuring-UART-and-VFS).
```
This is an example of ESP-IDF console component.
Type 'help' to get the list of commands.
Use UP/DOWN arrows to navigate through command history.
Press TAB when typing command name to auto-complete.
Your terminal application does not support escape sequences.
Line editing and history features are disabled.
On Windows, try using Putty instead.
esp32>
```
## Example Breakdown
### Configuring UART
The ``initialize_console()`` function in the example configures some aspects of UART relevant to the operation of the console.
- **Line Endings**: The default line endings are configured to match those expected/generated by common serial monitor programs, such as `screen`, `minicom`, and the `idf_monitor.py` included in the SDK. The default behavior for these commands are:
- When 'enter' key is pressed on the keyboard, `CR` (0x13) code is sent to the serial device.
- To move the cursor to the beginning of the next line, serial device needs to send `CR LF` (0x13 0x10) sequence.
### Line editing
The main source file of the example illustrates how to use `linenoise` library, including line completion, hints, and history.
### Commands
Several commands are registered using `esp_console_cmd_register()` function. See the `register_wifi()` and `register_system()` functions in `cmd_wifi.c` and `cmd_system.c` files.
### Command handling
Main loop inside `app_main()` function illustrates how to use `linenoise` and `esp_console_run()` to implement read/eval loop.
### Argument parsing
Several commands implemented in `cmd_wifi.c` and `cmd_system.c` use the Argtable3 library to parse and check the arguments.
### Command history
Each time a new command line is obtained from `linenoise`, it is written into history and the history is saved into a file in flash memory. On reset, history is initialized from that file.

View File

@@ -1,21 +1,22 @@
# type: ignore
from __future__ import print_function
import ttfw_idf
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3'])
def test_examples_system_console(env, extra_data):
dut = env.get_dut('console_example', 'examples/system/console', app_config_name='history')
def test_examples_system_console_basic(env, _):
dut = env.get_dut('console_example', 'examples/system/console/basic', app_config_name='history')
print('Using binary path: {}'.format(dut.app.binary_path))
dut.start_app()
dut.expect('Command history enabled')
env.close_dut(dut.name)
dut = env.get_dut('console_example', 'examples/system/console', app_config_name='nohistory')
dut = env.get_dut('console_example', 'examples/system/console/basic', app_config_name='nohistory')
print('Using binary path: {}'.format(dut.app.binary_path))
dut.start_app()
dut.expect('Command history disabled')
if __name__ == '__main__':
test_examples_system_console()
test_examples_system_console_basic()

View File

@@ -0,0 +1,3 @@
idf_component_register(SRCS "cmd_wifi.c"
"console_example_main.c"
INCLUDE_DIRS ".")

View File

@@ -0,0 +1,18 @@
menu "Example Configuration"
config CONSOLE_STORE_HISTORY
bool "Store command history in flash"
default y
help
Linenoise line editing library provides functions to save and load
command history. If this option is enabled, initalizes a FAT filesystem
and uses it to store command history.
config CONSOLE_MAX_COMMAND_LINE_LENGTH
int "Maximum command line length"
default 1024
help
This value marks the maximum length of a single command line. Once it is
reached, no more characters will be accepted by the console.
endmenu

View File

@@ -0,0 +1,21 @@
/* Console example — declarations of command registration functions.
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.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "cmd_system.h"
#include "cmd_wifi.h"
#include "cmd_nvs.h"
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,132 @@
/* Console example — WiFi commands
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 <string.h>
#include "esp_log.h"
#include "esp_console.h"
#include "argtable3/argtable3.h"
#include "cmd_decl.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "cmd_wifi.h"
#define JOIN_TIMEOUT_MS (10000)
static EventGroupHandle_t wifi_event_group;
const int CONNECTED_BIT = BIT0;
static void event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
}
}
static void initialise_wifi(void)
{
esp_log_level_set("wifi", ESP_LOG_WARN);
static bool initialized = false;
if (initialized) {
return;
}
ESP_ERROR_CHECK(esp_netif_init());
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap();
assert(ap_netif);
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &event_handler, NULL) );
ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_NULL) );
ESP_ERROR_CHECK( esp_wifi_start() );
initialized = true;
}
static bool wifi_join(const char *ssid, const char *pass, int timeout_ms)
{
initialise_wifi();
wifi_config_t wifi_config = { 0 };
strlcpy((char *) wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid));
if (pass) {
strlcpy((char *) wifi_config.sta.password, pass, sizeof(wifi_config.sta.password));
}
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
esp_wifi_connect();
int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
pdFALSE, pdTRUE, timeout_ms / portTICK_PERIOD_MS);
return (bits & CONNECTED_BIT) != 0;
}
/** Arguments used by 'join' function */
static struct {
struct arg_int *timeout;
struct arg_str *ssid;
struct arg_str *password;
struct arg_end *end;
} join_args;
static int connect(int argc, char **argv)
{
int nerrors = arg_parse(argc, argv, (void **) &join_args);
if (nerrors != 0) {
arg_print_errors(stderr, join_args.end, argv[0]);
return 1;
}
ESP_LOGI(__func__, "Connecting to '%s'",
join_args.ssid->sval[0]);
/* set default value*/
if (join_args.timeout->count == 0) {
join_args.timeout->ival[0] = JOIN_TIMEOUT_MS;
}
bool connected = wifi_join(join_args.ssid->sval[0],
join_args.password->sval[0],
join_args.timeout->ival[0]);
if (!connected) {
ESP_LOGW(__func__, "Connection timed out");
return 1;
}
ESP_LOGI(__func__, "Connected");
return 0;
}
void register_wifi(void)
{
join_args.timeout = arg_int0(NULL, "timeout", "<t>", "Connection timeout, ms");
join_args.ssid = arg_str1(NULL, NULL, "<ssid>", "SSID of AP");
join_args.password = arg_str0(NULL, NULL, "<pass>", "PSK of AP");
join_args.end = arg_end(2);
const esp_console_cmd_t join_cmd = {
.command = "join",
.help = "Join WiFi AP as a station",
.hint = NULL,
.func = &connect,
.argtable = &join_args
};
ESP_ERROR_CHECK( esp_console_cmd_register(&join_cmd) );
}

View File

@@ -0,0 +1,20 @@
/* Console example — declarations of command registration functions.
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.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
// Register WiFi functions
void register_wifi(void);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View File

@@ -0,0 +1,95 @@
/* Console 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 <string.h>
#include "esp_system.h"
#include "esp_log.h"
#include "esp_console.h"
#include "esp_vfs_dev.h"
#include "driver/uart.h"
#include "linenoise/linenoise.h"
#include "argtable3/argtable3.h"
#include "cmd_decl.h"
#include "esp_vfs_fat.h"
#include "nvs.h"
#include "nvs_flash.h"
#ifdef CONFIG_ESP_CONSOLE_USB_CDC
#error This example is incompatible with USB CDC console. Please try "console_usb" example instead.
#endif // CONFIG_ESP_CONSOLE_USB_CDC
static const char* TAG = "example";
#define PROMPT_STR CONFIG_IDF_TARGET
/* Console command history can be stored to and loaded from a file.
* The easiest way to do this is to use FATFS filesystem on top of
* wear_levelling library.
*/
#if CONFIG_CONSOLE_STORE_HISTORY
#define MOUNT_PATH "/data"
#define HISTORY_PATH MOUNT_PATH "/history.txt"
static void initialize_filesystem(void)
{
static wl_handle_t wl_handle;
const esp_vfs_fat_mount_config_t mount_config = {
.max_files = 4,
.format_if_mount_failed = true
};
esp_err_t err = esp_vfs_fat_spiflash_mount(MOUNT_PATH, "storage", &mount_config, &wl_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
return;
}
}
#endif // CONFIG_STORE_HISTORY
static void initialize_nvs(void)
{
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK( nvs_flash_erase() );
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
}
void app_main(void)
{
esp_console_repl_t *repl = NULL;
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
/* Prompt to be printed before each line.
* This can be customized, made dynamic, etc.
*/
repl_config.prompt = PROMPT_STR ">";
repl_config.max_cmdline_length = CONFIG_CONSOLE_MAX_COMMAND_LINE_LENGTH;
initialize_nvs();
#if CONFIG_CONSOLE_STORE_HISTORY
initialize_filesystem();
repl_config.history_save_path = HISTORY_PATH;
ESP_LOGI(TAG, "Command history enabled");
#else
ESP_LOGI(TAG, "Command history disabled");
#endif
/* Register commands */
esp_console_register_help_command();
register_system();
register_wifi();
register_nvs();
ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl));
ESP_ERROR_CHECK(esp_console_start_repl(repl));
}

View File

@@ -0,0 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M,
storage, data, fat, , 1M,
1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
3 nvs, data, nvs, 0x9000, 0x6000,
4 phy_init, data, phy, 0xf000, 0x1000,
5 factory, app, factory, 0x10000, 1M,
6 storage, data, fat, , 1M,

View File

@@ -0,0 +1 @@
CONFIG_CONSOLE_STORE_HISTORY=y

View File

@@ -0,0 +1 @@
CONFIG_CONSOLE_STORE_HISTORY=n

View File

@@ -0,0 +1,17 @@
# Reduce bootloader log verbosity
CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
CONFIG_BOOTLOADER_LOG_LEVEL=2
# Increase main task stack size
CONFIG_ESP_MAIN_TASK_STACK_SIZE=7168
# Enable filesystem
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv"
# Enable FreeRTOS stats formatting functions, needed for 'tasks' command
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y

View File

@@ -1,4 +0,0 @@
CONFIG_STORE_HISTORY=y
# IDF-3090
CONFIG_ESP32C3_REV_MIN_0=y
CONFIG_ESP32C3_REV_MIN=0

View File

@@ -1,4 +0,0 @@
CONFIG_STORE_HISTORY=n
# IDF-3090
CONFIG_ESP32C3_REV_MIN_0=y
CONFIG_ESP32C3_REV_MIN=0

View File

@@ -2,7 +2,7 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/system/console/components)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/system/console/advanced/components)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(console_usb)

View File

@@ -5,7 +5,7 @@
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example is similar to the [console example](../console/README.md), but instead of the UART it uses USB CDC for console output.
This example is similar to the [console example](../console/advanced/README.md), but instead of the UART it uses USB CDC for console output.
The example uses the [Console Component](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/console.html#console) to create an interactive shell.
The interactive shell implemented in this example contains a wide variety of commands, and can act as a basis for applications that require a command-line interface (CLI).
@@ -71,7 +71,7 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
## Example Output
Enter the `help` command get a full list of all available commands. The following is a sample session of the Console Example where a variety of commands provided by the Console Example are used. Note that GPIO15 is connected to GND to remove the boot log output.
Enter the `help` command get a full list of all available commands. The following is a sample session of the Console Example where a variety of commands provided by the Console Example are used. Note that GPIO15 is connected to GND to remove the boot log output.
```
This is an example of ESP-IDF console component.
@@ -79,22 +79,22 @@ Type 'help' to get the list of commands.
Use UP/DOWN arrows to navigate through command history.
Press TAB when typing command name to auto-complete.
esp32s2> help
help
help
Print the list of registered commands
free
free
Get the current size of free heap memory
heap
heap
Get minimum size of free heap memory that was available during program execution
version
version
Get version of chip and SDK
restart
restart
Software reset of the chip
tasks
tasks
Get information about running tasks
(remaining output of the help command skipped here)

View File

@@ -21,6 +21,3 @@ CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC=y
# ESP32C3-specific config
CONFIG_ESP32C3_DEFAULT_CPU_FREQ_80=y
CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ=80
# IDF-3090
CONFIG_ESP32C3_REV_MIN_0=y
CONFIG_ESP32C3_REV_MIN=0

View File

@@ -7,7 +7,7 @@ This example shows how to use the eFuse API. It demonstrates read and write oper
The eFuse is a single bit of non-volatile memory with the restriction that once an eFuse bit is programmed to 1, it can not be reverted to 0.
The eFuse fields can be useful to store: device types, serial numbers, some system variables, etc.
Note that the bits already written cannot be reset to the original state. For debugging purposes, the `CONFIG_EFUSE_VIRTUAL` option is provided. This option will block physical burning. All work happens with an array in RAM.
Note that the bits already written cannot be reset to the original state. For debugging purposes, the `CONFIG_EFUSE_VIRTUAL` option is provided. This option will block physical burning. All work happens with an array in RAM. Use `CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH` to keep eFuse changes after reboots.
In this example, all write operations are wrapped in `#ifdef CONFIG_EFUSE_VIRTUAL ... # endif` to prevent accidental burn while testing the features.
## How to use example

View File

@@ -1,16 +1,32 @@
from __future__ import unicode_literals
import os
import re
import ttfw_idf
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3'])
def test_examples_efuse(env, extra_data):
def erase_field_on_emul_efuse(dut, bit_pos): # type: (ttfw_idf.TinyFW.Env, int) -> None
emul_efuse_bin_path = os.path.join(dut.app.binary_path, 'emul_efuse.bin')
dut.dump_flash(emul_efuse_bin_path, partition='emul_efuse')
nbytes, nbits = divmod(bit_pos, 8)
with open(emul_efuse_bin_path, 'r+b') as f:
f.seek(nbytes, 0)
c = f.read(1)
toggled = bytes([ord(c) ^ (1 << nbits)])
f.seek(-1, 1) # or absolute: f.seek(nbytes, 0)
f.write(toggled)
offs = dut.app.partition_table['emul_efuse']['offset']
flash_files = [(offs, emul_efuse_bin_path)]
dut.write_flash(flash_files)
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3'])
def test_examples_efuse(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
dut = env.get_dut('efuse', 'examples/system/efuse')
dut.start_app()
dut.expect_all(re.compile(r'example: Coding Scheme (3/4)|(NONE)|(REPEAT)|(RS \(Reed-Solomon coding\))'),
'example: read efuse fields',
re.compile(r'example: 1. read MAC address: {}'.format(r':'.join((r'[0-9a-f]{2}',) * 6))),
@@ -34,5 +50,751 @@ def test_examples_efuse(env, extra_data):
timeout=30)
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3'])
def test_examples_efuse_with_virt_flash_enc(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_flash_enc')
# check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file)
ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
print(' - Erase flash')
dut.erase_flash()
print(' - Start app (flash partition_table and app)')
dut.start_app_no_enc()
dut.expect('Loading virtual efuse blocks from real efuses')
dut.expect('Checking flash encryption...')
dut.expect('Generating new flash encryption key...')
if dut.TARGET == 'esp32':
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 2')
dut.expect('Setting CRYPT_CONFIG efuse to 0xF')
dut.expect('Not disabling UART bootloader encryption')
dut.expect('Disable UART bootloader decryption...')
dut.expect('Disable UART bootloader MMU cache...')
dut.expect('Disable JTAG...')
dut.expect('Disable ROM BASIC interpreter fallback...')
else:
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 4')
dut.expect('Not disabling UART bootloader encryption')
dut.expect('Disable UART bootloader cache...')
dut.expect('Disable JTAG...')
dut.expect('bootloader encrypted successfully')
dut.expect('partition table encrypted and loaded successfully')
dut.expect('Flash encryption completed', timeout=90)
dut.expect('Resetting with flash encryption enabled...')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Checking flash encryption...')
if dut.TARGET == 'esp32':
dut.expect('flash encryption is enabled (3 plaintext flashes left)')
else:
dut.expect('flash encryption is enabled (1 plaintext flashes left)')
dut.expect('Flash encryption mode is DEVELOPMENT (not secure)')
dut.expect('Start eFuse example')
dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2'])
def test_examples_efuse_with_virt_flash_enc_aes_256(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
# Only ESP32-S2 has support AES-256 FLASH_ENCRYPTION key
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_flash_enc_aes_256')
# check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file)
ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
print(' - Erase flash')
dut.erase_flash()
print(' - Start app (flash partition_table and app)')
dut.start_app_no_enc()
dut.expect('Loading virtual efuse blocks from real efuses')
dut.expect('Checking flash encryption...')
dut.expect('Generating new flash encryption key...')
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 2')
dut.expect('Writing EFUSE_BLK_KEY1 with purpose 3')
dut.expect('Not disabling UART bootloader encryption')
dut.expect('Disable UART bootloader cache...')
dut.expect('Disable JTAG...')
dut.expect('bootloader encrypted successfully')
dut.expect('partition table encrypted and loaded successfully')
dut.expect('Flash encryption completed', timeout=90)
dut.expect('Resetting with flash encryption enabled...')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Checking flash encryption...')
dut.expect('flash encryption is enabled (1 plaintext flashes left)')
dut.expect('Flash encryption mode is DEVELOPMENT (not secure)')
dut.expect('Start eFuse example')
dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3'])
def test_examples_efuse_with_virt_flash_enc_pre_loaded(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_flash_enc')
print(' - Erase flash')
dut.erase_flash()
print(' - Start app (flash partition_table and app)')
dut.start_app_no_enc()
dut.expect('Loading virtual efuse blocks from real efuses')
dut.expect('Flash encryption completed', timeout=90)
dut.expect('Resetting with flash encryption enabled...')
dut.expect('Flash encryption mode is DEVELOPMENT (not secure)')
dut.expect('Start eFuse example')
dut.expect('example: Done')
if dut.TARGET == 'esp32':
print(' - Flash emul_efuse with pre-loaded efuses (FLASH_CRYPT_CNT 1 -> 0)')
erase_field_on_emul_efuse(dut, 0 * 32 + 20)
else:
print(' - Flash emul_efuse with pre-loaded efuses (SPI_BOOT_CRYPT_CNT 1 -> 0)')
erase_field_on_emul_efuse(dut, 2 * 32 + 18)
print(' - Start app (flash partition_table and app)')
dut.start_app_no_enc()
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Checking flash encryption...')
dut.expect('Using pre-loaded flash encryption key in efuse')
if dut.TARGET == 'esp32':
dut.expect('Setting CRYPT_CONFIG efuse to 0xF')
dut.expect('Not disabling UART bootloader encryption')
dut.expect('Disable UART bootloader decryption...')
dut.expect('Disable UART bootloader MMU cache...')
dut.expect('Disable JTAG...')
dut.expect('Disable ROM BASIC interpreter fallback...')
else:
dut.expect('Not disabling UART bootloader encryption')
dut.expect('Disable UART bootloader cache...')
dut.expect('Disable JTAG...')
dut.expect('bootloader encrypted successfully')
dut.expect('partition table encrypted and loaded successfully')
dut.expect('Flash encryption completed', timeout=90)
dut.expect('Resetting with flash encryption enabled...')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Checking flash encryption...')
if dut.TARGET == 'esp32':
dut.expect('flash encryption is enabled (3 plaintext flashes left)')
else:
dut.expect('flash encryption is enabled (1 plaintext flashes left)')
dut.expect('Flash encryption mode is DEVELOPMENT (not secure)')
dut.expect('Start eFuse example')
dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3'])
def test_examples_efuse_with_virt_flash_enc_release(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_flash_enc_release')
# check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file)
ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
print(' - Erase flash')
dut.erase_flash()
print(' - Start app (flash partition_table and app)')
dut.start_app_no_enc()
dut.expect('Loading virtual efuse blocks from real efuses')
dut.expect('Checking flash encryption...')
dut.expect('Generating new flash encryption key...')
if dut.TARGET == 'esp32':
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 2')
dut.expect('Setting CRYPT_CONFIG efuse to 0xF')
dut.expect('Disable UART bootloader encryption...')
dut.expect('Disable UART bootloader decryption...')
dut.expect('Disable UART bootloader MMU cache...')
dut.expect('Disable JTAG...')
dut.expect('Disable ROM BASIC interpreter fallback...')
else:
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 4')
dut.expect('Disable UART bootloader encryption')
dut.expect('Disable UART bootloader cache...')
dut.expect('Disable JTAG...')
dut.expect('bootloader encrypted successfully')
dut.expect('partition table encrypted and loaded successfully')
dut.expect('Setting CRYPT_CNT for permanent encryption', timeout=90)
dut.expect('Flash encryption completed')
dut.expect('Resetting with flash encryption enabled...')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Checking flash encryption...')
dut.expect('flash encryption is enabled (0 plaintext flashes left)')
dut.expect('Flash encryption mode is RELEASE')
dut.expect('Start eFuse example')
dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32'])
def test_examples_efuse_with_virt_secure_boot_v1(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
# only for ESP32
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v1')
# check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file)
ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
print(' - Erase flash')
dut.erase_flash()
print(' - Flash bootloader')
dut.bootloader_flash()
print(' - Start app (flash partition_table and app)')
dut.start_app()
dut.expect('Loading virtual efuse blocks from real efuses')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v1: Generating new secure boot key...')
dut.expect('secure_boot_v1: Generating secure boot digest...')
dut.expect('secure_boot_v1: Digest generation complete')
dut.expect('Checking secure boot...')
dut.expect('secure_boot_v1: blowing secure boot efuse...')
dut.expect('Read & write protecting new key...')
dut.expect('Disable JTAG...')
dut.expect('Disable ROM BASIC interpreter fallback...')
dut.expect('secure_boot_v1: secure boot is now enabled for bootloader image')
dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Start eFuse example')
dut.expect('example: Done')
dut.reset()
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v1: bootloader secure boot is already enabled. No need to generate digest. continuing..')
dut.expect('boot: Checking secure boot...')
dut.expect('secure_boot_v1: bootloader secure boot is already enabled, continuing..')
dut.expect('Start eFuse example')
dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32'])
def test_examples_efuse_with_virt_secure_boot_v1_pre_loaded(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
# only for ESP32
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v1')
print(' - Erase flash')
dut.erase_flash()
dut.bootloader_flash()
dut.start_app()
dut.expect('Loading virtual efuse blocks from real efuses')
dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Start eFuse example')
dut.expect('example: Done')
print(' - Flash emul_efuse with pre-loaded efuses (ABS_DONE_0 1 -> 0)')
erase_field_on_emul_efuse(dut, 6 * 32 + 4)
print(' - Start app (flash partition_table and app)')
dut.start_app()
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v1: Using pre-loaded secure boot key in EFUSE block 2')
dut.expect('secure_boot_v1: Generating secure boot digest...')
dut.expect('secure_boot_v1: Digest generation complete')
dut.expect('Checking secure boot...')
dut.expect('secure_boot_v1: blowing secure boot efuse...')
dut.expect('Read & write protecting new key...')
dut.expect('Disable JTAG...')
dut.expect('Disable ROM BASIC interpreter fallback...')
dut.expect('secure_boot_v1: secure boot is now enabled for bootloader image')
dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Start eFuse example')
dut.expect('example: Done')
dut.reset()
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v1: bootloader secure boot is already enabled. No need to generate digest. continuing..')
dut.expect('Checking secure boot...')
dut.expect('secure_boot_v1: bootloader secure boot is already enabled, continuing..')
dut.expect('Start eFuse example')
dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_EthKitV12', target=['esp32'])
def test_examples_efuse_with_virt_secure_boot_v2(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
# only for ESP32 ECO3
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v2')
# check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file)
ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
print(' - Erase flash')
dut.erase_flash()
print(' - Flash bootloader')
dut.bootloader_flash()
print(' - Start app (flash partition_table and app)')
dut.start_app()
dut.expect('Loading virtual efuse blocks from real efuses')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: enabling secure boot v2...')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: Secure boot digests absent, generating..')
dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
dut.expect('secure_boot_v2: 1 signature block(s) found appended to the bootloader')
dut.expect('Writing EFUSE_BLK_KEY1 with purpose 3')
dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app')
dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)')
dut.expect('secure_boot_v2: blowing secure boot efuse...')
dut.expect('Disable JTAG...')
dut.expect('Disable ROM BASIC interpreter fallback...')
dut.expect('Not disabling ROM Download mode - SECURITY COMPROMISED')
dut.expect('Prevent read disabling of additional efuses...')
dut.expect('secure_boot_v2: Secure boot permanently enabled')
dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Start eFuse example')
dut.expect('example: Done')
dut.reset()
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: enabling secure boot v2...')
dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..')
dut.expect('Start eFuse example')
dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_EthKitV12', target=['esp32'])
def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
# only for ESP32 ECO3
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v2')
print(' - Erase flash')
dut.erase_flash()
print(' - Flash bootloader and app')
dut.bootloader_flash()
dut.start_app()
dut.expect('Loading virtual efuse blocks from real efuses')
dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Start eFuse example')
dut.expect('example: Done')
print(' - Flash emul_efuse with pre-loaded efuses (ABS_DONE_1 1 -> 0)')
erase_field_on_emul_efuse(dut, 6 * 32 + 5)
print(' - Start app (flash partition_table and app)')
dut.start_app()
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: enabling secure boot v2...')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: Secure boot digests already present')
dut.expect('secure_boot_v2: Using pre-loaded public key digest in eFuse')
dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app')
dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)')
dut.expect('secure_boot_v2: blowing secure boot efuse...')
dut.expect('Disable JTAG...')
dut.expect('Disable ROM BASIC interpreter fallback...')
dut.expect('Not disabling ROM Download mode - SECURITY COMPROMISED')
dut.expect('Prevent read disabling of additional efuses...')
dut.expect('secure_boot_v2: Secure boot permanently enabled')
dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Start eFuse example')
dut.expect('example: Done')
dut.reset()
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: enabling secure boot v2...')
dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..')
dut.expect('Start eFuse example')
dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2'])
def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v2')
# check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file)
ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
print(' - Erase flash')
dut.erase_flash()
print(' - Flash bootloader')
dut.bootloader_flash()
print(' - Start app (flash partition_table and app)')
dut.start_app()
dut.expect('Loading virtual efuse blocks from real efuses')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: enabling secure boot v2...')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: Secure boot digests absent, generating..')
dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
dut.expect('secure_boot_v2: 1 signature block(s) found appended to the bootloader')
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 9')
dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app')
dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)')
dut.expect('secure_boot_v2: Revoking empty key digest slot (1)...')
dut.expect('secure_boot_v2: Revoking empty key digest slot (2)...')
dut.expect('secure_boot_v2: blowing secure boot efuse...')
dut.expect('Not enabling Security download mode - SECURITY COMPROMISED')
dut.expect('Disable hardware & software JTAG...')
dut.expect('secure_boot_v2: Secure boot permanently enabled')
dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Start eFuse example')
dut.expect('example: Done')
dut.reset()
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: enabling secure boot v2...')
dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..')
dut.expect('Start eFuse example')
dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2'])
def test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v2')
print(' - Erase flash')
dut.erase_flash()
print(' - Flash bootloader and app')
dut.bootloader_flash()
dut.start_app()
dut.expect('Loading virtual efuse blocks from real efuses')
dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Start eFuse example')
dut.expect('example: Done')
print(' - Flash emul_efuse with pre-loaded efuses (SECURE_BOOT_EN 1 -> 0)')
erase_field_on_emul_efuse(dut, 3 * 32 + 20)
print(' - Start app (flash partition_table and app)')
dut.start_app()
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: Secure boot digests already present')
dut.expect('secure_boot_v2: Using pre-loaded public key digest in eFuse')
dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app')
dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)')
dut.expect('secure_boot_v2: Revoking empty key digest slot (1)...')
dut.expect('secure_boot_v2: Revoking empty key digest slot (2)...')
dut.expect('secure_boot_v2: blowing secure boot efuse...')
dut.expect('Not enabling Security download mode - SECURITY COMPROMISED')
dut.expect('Disable hardware & software JTAG...')
dut.expect('secure_boot_v2: Secure boot permanently enabled')
dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Start eFuse example')
dut.expect('example: Done')
dut.reset()
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: enabling secure boot v2...')
dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..')
dut.expect('Start eFuse example')
dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32'])
def test_examples_efuse_with_virt_sb_v1_and_fe(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_sb_v1_and_fe')
# check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file)
ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
print(' - Erase flash')
dut.erase_flash()
print(' - Flash bootloader')
dut.bootloader_flash()
print(' - Start app (flash partition_table and app)')
dut.start_app_no_enc()
dut.expect('Loading virtual efuse blocks from real efuses')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v1: Generating new secure boot key...')
dut.expect('secure_boot_v1: Generating secure boot digest...')
dut.expect('secure_boot_v1: Digest generation complete')
dut.expect('Checking flash encryption...')
dut.expect('flash_encrypt: Generating new flash encryption key...')
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 2')
dut.expect('flash_encrypt: Setting CRYPT_CONFIG efuse to 0xF')
dut.expect('flash_encrypt: Not disabling UART bootloader encryption')
dut.expect('flash_encrypt: Disable UART bootloader decryption...')
dut.expect('flash_encrypt: Disable UART bootloader MMU cache...')
dut.expect('flash_encrypt: Disable JTAG...')
dut.expect('flash_encrypt: Disable ROM BASIC interpreter fallback...')
dut.expect('flash_encrypt: bootloader encrypted successfully')
dut.expect('flash_encrypt: partition table encrypted and loaded successfully')
dut.expect('Verifying image signature...')
dut.expect('flash_encrypt: Flash encryption completed', timeout=90)
dut.expect('Checking secure boot...')
dut.expect('secure_boot_v1: blowing secure boot efuse...')
dut.expect('Read & write protecting new key...')
dut.expect('Disable JTAG...')
dut.expect('Disable ROM BASIC interpreter fallback...')
dut.expect('secure_boot_v1: secure boot is now enabled for bootloader image')
dut.expect('Resetting with flash encryption enabled...')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v1: bootloader secure boot is already enabled. No need to generate digest. continuing..')
dut.expect('Checking flash encryption...')
dut.expect('flash_encrypt: flash encryption is enabled (3 plaintext flashes left)')
dut.expect('Checking secure boot...')
dut.expect('secure_boot_v1: bootloader secure boot is already enabled, continuing..')
dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)')
dut.expect('Start eFuse example')
dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_EthKitV12', target=['esp32'])
def test_examples_efuse_with_virt_sb_v2_and_fe(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
# only for ESP32 ECO3
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_sb_v2_and_fe')
# check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file)
ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
print(' - Erase flash')
dut.erase_flash()
print(' - Flash bootloader')
dut.bootloader_flash()
print(' - Start app (flash partition_table and app)')
dut.start_app_no_enc()
dut.expect('Loading virtual efuse blocks from real efuses')
dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: enabling secure boot v2...')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully')
dut.expect('secure_boot_v2: Secure boot digests absent, generating..')
dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
dut.expect('secure_boot_v2: 1 signature block(s) found appended to the bootloader')
dut.expect('Writing EFUSE_BLK_KEY1 with purpose 3')
dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app')
dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)')
dut.expect('secure_boot_v2: blowing secure boot efuse...')
dut.expect('Disable JTAG...')
dut.expect('Disable ROM BASIC interpreter fallback...')
dut.expect('Not disabling ROM Download mode - SECURITY COMPROMISED')
dut.expect('secure_boot_v2: Secure boot permanently enabled')
dut.expect('Checking flash encryption...')
dut.expect('flash_encrypt: Generating new flash encryption key...')
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 2')
dut.expect('flash_encrypt: Setting CRYPT_CONFIG efuse to 0xF')
dut.expect('flash_encrypt: Not disabling UART bootloader encryption')
dut.expect('flash_encrypt: Disable UART bootloader decryption...')
dut.expect('flash_encrypt: Disable UART bootloader MMU cache...')
dut.expect('flash_encrypt: Disable JTAG...')
dut.expect('flash_encrypt: Disable ROM BASIC interpreter fallback...')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('flash_encrypt: bootloader encrypted successfully')
dut.expect('flash_encrypt: partition table encrypted and loaded successfully')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('flash_encrypt: Flash encryption completed', timeout=90)
dut.expect('Resetting with flash encryption enabled...')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: enabling secure boot v2...')
dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..')
dut.expect('flash_encrypt: flash encryption is enabled (3 plaintext flashes left)')
dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)')
dut.expect('Start eFuse example')
dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2'])
def test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_sb_v2_and_fe')
# check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file)
ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
print(' - Erase flash')
dut.erase_flash()
print(' - Flash bootloader')
dut.bootloader_flash()
print(' - Start app (flash partition_table and app)')
dut.start_app_no_enc()
dut.expect('Loading virtual efuse blocks from real efuses')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: enabling secure boot v2...')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: Secure boot digests absent, generating..')
dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
dut.expect('secure_boot_v2: 1 signature block(s) found appended to the bootloader')
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 9')
dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app')
dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)')
dut.expect('secure_boot_v2: Revoking empty key digest slot (1)...')
dut.expect('secure_boot_v2: Revoking empty key digest slot (2)...')
dut.expect('secure_boot_v2: blowing secure boot efuse...')
dut.expect('Not enabling Security download mode - SECURITY COMPROMISED')
dut.expect('Disable hardware & software JTAG...')
dut.expect('secure_boot_v2: Secure boot permanently enabled')
dut.expect('Checking flash encryption...')
dut.expect('flash_encrypt: Generating new flash encryption key...')
dut.expect('Writing EFUSE_BLK_KEY1 with purpose 4')
dut.expect('Not disabling UART bootloader encryption')
dut.expect('Disable UART bootloader cache...')
dut.expect('Disable JTAG...')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('flash_encrypt: bootloader encrypted successfully')
dut.expect('flash_encrypt: partition table encrypted and loaded successfully')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('flash_encrypt: Flash encryption completed', timeout=90)
dut.expect('Resetting with flash encryption enabled...')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: enabling secure boot v2...')
dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..')
dut.expect('flash_encrypt: flash encryption is enabled (1 plaintext flashes left)')
dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash')
dut.expect('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)')
dut.expect('Start eFuse example')
dut.expect('example: Done')
if __name__ == '__main__':
test_examples_efuse()
test_examples_efuse_with_virt_flash_enc()
test_examples_efuse_with_virt_flash_enc_pre_loaded()
test_examples_efuse_with_virt_flash_enc_aes_256()
test_examples_efuse_with_virt_flash_enc_release()
test_examples_efuse_with_virt_secure_boot_v1()
test_examples_efuse_with_virt_secure_boot_v1_pre_loaded()
test_examples_efuse_with_virt_secure_boot_v2()
test_examples_efuse_with_virt_secure_boot_v2_pre_loaded()
test_examples_efuse_with_virt_secure_boot_v2_esp32xx()
test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded()
test_examples_efuse_with_virt_sb_v1_and_fe()
test_examples_efuse_with_virt_sb_v2_and_fe()
test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx()

View File

@@ -76,10 +76,9 @@ static void read_efuse_fields(device_desc_t *desc)
}
#ifdef CONFIG_EFUSE_VIRTUAL
static void write_efuse_fields(device_desc_t *desc, esp_efuse_coding_scheme_t coding_scheme)
{
#ifdef CONFIG_EFUSE_VIRTUAL
#if CONFIG_IDF_TARGET_ESP32
const esp_efuse_coding_scheme_t coding_scheme_for_batch_mode = EFUSE_CODING_SCHEME_3_4;
#else
@@ -102,8 +101,8 @@ static void write_efuse_fields(device_desc_t *desc, esp_efuse_coding_scheme_t co
if (coding_scheme == coding_scheme_for_batch_mode) {
ESP_ERROR_CHECK(esp_efuse_batch_write_commit());
}
#endif // CONFIG_EFUSE_VIRTUAL
}
#endif // CONFIG_EFUSE_VIRTUAL
static esp_efuse_coding_scheme_t get_coding_scheme(void)
@@ -130,7 +129,10 @@ static esp_efuse_coding_scheme_t get_coding_scheme(void)
void app_main(void)
{
ESP_LOGI(TAG, "Start eFuse example");
esp_efuse_coding_scheme_t coding_scheme = get_coding_scheme();
(void) coding_scheme;
device_desc_t device_desc = { 0 };
read_efuse_fields(&device_desc);

View File

@@ -1,5 +1,2 @@
CONFIG_EFUSE_CUSTOM_TABLE=y
CONFIG_EFUSE_VIRTUAL=y
# IDF-3090
CONFIG_ESP32C3_REV_MIN_0=y
CONFIG_ESP32C3_REV_MIN=0

View File

@@ -0,0 +1,11 @@
# FLASH_ENCRYPTION with EFUSE_VIRTUAL_KEEP_IN_FLASH
CONFIG_PARTITION_TABLE_OFFSET=0xC000
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="test/partitions_efuse_emul.csv"
CONFIG_SECURE_FLASH_ENC_ENABLED=y
# IMPORTANT: ONLY VIRTUAL eFuse MODE!
CONFIG_EFUSE_VIRTUAL=y
CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=y

View File

@@ -0,0 +1,15 @@
# FLASH_ENCRYPTION with EFUSE_VIRTUAL_KEEP_IN_FLASH
# FLASH_ENCRYPTION_AES256 is available only in ESP32-S2
CONFIG_IDF_TARGET="esp32s2"
CONFIG_PARTITION_TABLE_OFFSET=0xC000
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="test/partitions_efuse_emul.csv"
CONFIG_SECURE_FLASH_ENC_ENABLED=y
CONFIG_SECURE_FLASH_ENCRYPTION_AES256=y
# IMPORTANT: ONLY VIRTUAL eFuse MODE!
CONFIG_EFUSE_VIRTUAL=y
CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=y

View File

@@ -0,0 +1,12 @@
# FLASH_ENCRYPTION with EFUSE_VIRTUAL_KEEP_IN_FLASH
CONFIG_PARTITION_TABLE_OFFSET=0xC000
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="test/partitions_efuse_emul.csv"
CONFIG_SECURE_FLASH_ENC_ENABLED=y
CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=y
# IMPORTANT: ONLY VIRTUAL eFuse MODE!
CONFIG_EFUSE_VIRTUAL=y
CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=y

View File

@@ -0,0 +1,18 @@
# FLASH_ENCRYPTION & SECURE_BOOT_V1 with EFUSE_VIRTUAL_KEEP_IN_FLASH
# SECURE_BOOT_V1 is available only in ESP32
CONFIG_IDF_TARGET="esp32"
CONFIG_PARTITION_TABLE_OFFSET=0xD000
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="test/partitions_efuse_emul.csv"
CONFIG_SECURE_BOOT=y
CONFIG_SECURE_BOOT_V1_ENABLED=y
CONFIG_SECURE_BOOT_SIGNING_KEY="test/secure_boot_signing_key_ecdsa.pem"
CONFIG_SECURE_FLASH_ENC_ENABLED=y
# IMPORTANT: ONLY VIRTUAL eFuse MODE!
CONFIG_EFUSE_VIRTUAL=y
CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=y

View File

@@ -0,0 +1,22 @@
# FLASH_ENCRYPTION & SECURE_BOOT_V2 with EFUSE_VIRTUAL_KEEP_IN_FLASH
# ESP32 supports SECURE_BOOT_V2 only in ECO3
CONFIG_ESP32_REV_MIN_3=y
CONFIG_ESP32_REV_MIN=3
# ESP32C3 supports SECURE_BOOT_V2 only in ECO3
CONFIG_ESP32C3_REV_MIN_3=y
CONFIG_ESP32C3_REV_MIN=3
CONFIG_PARTITION_TABLE_OFFSET=0xD000
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="test/partitions_efuse_emul.csv"
CONFIG_SECURE_BOOT=y
CONFIG_SECURE_BOOT_V2_ENABLED=y
CONFIG_SECURE_BOOT_SIGNING_KEY="test/secure_boot_signing_key.pem"
CONFIG_SECURE_FLASH_ENC_ENABLED=y
# IMPORTANT: ONLY VIRTUAL eFuse MODE!
CONFIG_EFUSE_VIRTUAL=y
CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=y

View File

@@ -0,0 +1,16 @@
# SECURE_BOOT_V1 with EFUSE_VIRTUAL_KEEP_IN_FLASH
# SECURE_BOOT_V1 is available only in ESP32
CONFIG_IDF_TARGET="esp32"
CONFIG_PARTITION_TABLE_OFFSET=0xC000
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="test/partitions_efuse_emul.csv"
CONFIG_SECURE_BOOT=y
CONFIG_SECURE_BOOT_V1_ENABLED=y
CONFIG_SECURE_BOOT_SIGNING_KEY="test/secure_boot_signing_key_ecdsa.pem"
# IMPORTANT: ONLY VIRTUAL eFuse MODE!
CONFIG_EFUSE_VIRTUAL=y
CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=y

View File

@@ -0,0 +1,21 @@
# SECURE_BOOT_V2 with EFUSE_VIRTUAL_KEEP_IN_FLASH
# ESP32 supports SECURE_BOOT_V2 only in ECO3
CONFIG_ESP32_REV_MIN_3=y
CONFIG_ESP32_REV_MIN=3
# ESP32C3 supports SECURE_BOOT_V2 only in ECO3
CONFIG_ESP32C3_REV_MIN_3=y
CONFIG_ESP32C3_REV_MIN=3
CONFIG_PARTITION_TABLE_OFFSET=0xC000
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="test/partitions_efuse_emul.csv"
CONFIG_SECURE_BOOT=y
CONFIG_SECURE_BOOT_V2_ENABLED=y
CONFIG_SECURE_BOOT_SIGNING_KEY="test/secure_boot_signing_key.pem"
CONFIG_SECURE_INSECURE_ALLOW_DL_MODE=y
# IMPORTANT: ONLY VIRTUAL eFuse MODE!
CONFIG_EFUSE_VIRTUAL=y
CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=y

View File

@@ -0,0 +1,7 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, , 0x4000,
phy_init, data, phy, , 0x1000,
storage, data, 0xff, , 0x1000, encrypted
nvs_key, data, nvs_keys, , 0x1000, encrypted,
emul_efuse, data, efuse, , 0x2000,
factory, app, factory, , 1M,
1 # Name, Type, SubType, Offset, Size, Flags
2 nvs, data, nvs, , 0x4000,
3 phy_init, data, phy, , 0x1000,
4 storage, data, 0xff, , 0x1000, encrypted
5 nvs_key, data, nvs_keys, , 0x1000, encrypted,
6 emul_efuse, data, efuse, , 0x2000,
7 factory, app, factory, , 1M,

View File

@@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
MIIG4wIBAAKCAYEAzJUktQ+7wpPDfDGterxiMRx5w9n7PFaUSK3wnE+05ALsEF8F
rUOC7/q0GutYYdWopdRM1FUKX2XVaryMViC+DHof42fEbpWYnfrCkYrDn8MLuMyK
4uGunl8LUTIAZk3I3SZKJZy5FW9eb1XtkwfN1lAd6lEEGQKyoR6Bk/Rkisj0LP7R
dyV9NKbJhxavZ1ohZXiXU5FW873iGdPIsloZoUK3QGRE1KRIH2woUGHATfXBCf5a
+e41wJzz7YHl5tjyxAbJ9PET52N14G73WoZKHu3QPShALrZVfjsk1oYdFvNdOBDL
uU0vpyKl7mJHno11gM0UM0s9PrMxk9ffdAqMyS8YeLEk2Xl3AwPv7m9oeGIdSD/P
okcISYcm4YAl5veqIG3RlkfpWjf5G15UYyLbgmn4GOkgr6ksB/dCFOMi9V1LjPah
32A7gxqTlapQza+wNs30SYBIXrFde4bNnhFhj4Cbt34ADefWm26KLiZEHFHFN30Z
IownitXz3rT7rmzBAgMBAAECggGBAK6bBA88dGWnM4rF42gDbFK6GPqdCp3+zuQR
AHCIXrzT+aInV3L/Ubt730eyYWZusleGEGSQiB/PjAxjC+teWpXPjXPK1o4DQ5Rh
trn9EuVB1LlOaaMmNqCYQdJ0uH6YGL0WtuXPEvBGcvTXA8MfQACPtFiN+M9XzBlT
LgiW51DEHhJhEWl9J5VOXGXdaKru893kxFLgkrPI9jZQ2NPPrlxB0qE0csKBy8R1
zRp9s2FWRAFBg2gYdOwFiPLGkO8rbM+jhXM+IUV1GgVYdxAC6zS9AiIAWuACDEwp
Pzg3d3/5uyOFK1xTIPl/cG8CZyPQL1v/mUx0MZFaB1R1CVeDuMoFVz2YSbEaAVFv
QIcJGDN/WlJbt0jwj7/RJKKTx0ipFlUdNbodzdaSl3Yg4N+evzR1nS8DvLJpwl/e
ybu40IbavwYXWVzirH3wRg+P/NDsHLU5xASAyUwf1minsmObILayEZgfTA6TbrKL
fZbJCvy2/IuCM6iqKZwSvYy0bJdaAQKBwQDzDVa/M4/sJV0GEbwegeN6Xf+XKkl3
Gosjd+vQgv/0X1gbdMc0Ej9eYSU5/GYIHxDzDRkYIxtIfwaze1gGeNRHycMCmVkl
09DMi48jLGE7wzObPu6MtBCSAGHaS9zMTVCYDYtRlykPzG2/1QNrRUDNACnpzneK
MkWObzFYTIup1zh+JaD56vLIDdL7qM9apmEkq4O6y1BBPnCgRYJy5EU3BDZxz9fP
47JtCZ47uVguoh/NVYY5uibdvI5iJ4SA/VECgcEA13srpwJppfTTFPRWgD+g7PdU
Yg+ENBWygiJuwgGv6DyD4k73pxiyshNo7jxsdOLeGFA8hI3dvd/Ei6uUsGnWPy/a
OwuBcOZrJZjyawNSiC+mrCSP0LGQrC5VjmuE8IU1d2hFWyV/NzkSLaXJ52Zkg3ee
sSepBHtWEYpwH929u5FTKDKhL0qRH8E1EsULSjmkTa+cVDYgx8+2mb3vHRdJdvt3
FZU9erKyDb4II5GJhyNQo/cxBosDzj4yIMKM/dxxAoHAE1r1lIZjqLeU/927sGZB
mkYQC5a3gP+hIvLy2YkFHw3Us2MKVhA58ack0shRy8XFkMVzQSPSkWRkQTjKWsGW
jhz4JaXWnpeOoite+7sWBy9VVcCeOKBCTY4wPLUb4T0q9ODnPlkeUP7Doqow+oLq
VSj1LYReqqe0OFKMiG6YFK9p9UnD1wMp0FqheZ8I3DwxsjziYaa9PmTdjTXb3JBn
Hql8OHYHxqtoUxyX+EObTSNmCvELnl8/pxrT7+cbuzXxAoHAfmNYb1US8qxvQtMu
CXtIwLUxYXMIcCRp17qqjFDBBM657Hu09uWdqqWH3nTCiKyo6EnntTgg38XoWqQB
SphJejZvIkLVYYtFPYBAcFQ6jHampEGtuRLtcJCczjRyfUEk4yzdwWB1BccLyop7
qqZ8PkBjbDV/BYnyKcexjH9bUjEjPWi08jAifyWsI54/yQGWRZrDbwFwqMJEsFif
b8jA5nEIoDgxH07A8R6NV499wy4LlqDeuJ/BU69XZ6+1UxGBAoHAXfb9t5ivdf9N
ZbZj61GcrDLyYGDTotucy8HPNMr5P3ZmBR/5UzClpCbWVSaziK3CKzR0zURLw0W7
rF4CySTjuD9FHOFFWjjlkS4KwOyYiy8fuMMLg1RmsCS8H+0L3Pm25PmRQ9TLjEf4
0uFWf7fG4GQiciqGcvfaFH3w//d0Q7PSvIMNlM1Gc7JS1Qn4HoDF2Ux6drNb6nJL
l6tdXNMkUFHBMtaQy0l9D/ex5NZlAniePT3xfMrQf6m0rVAAaAY0
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIOvP45grF4dSM2fWbOAp4W8PgFm30HIZqtNEK13O5hVHoAoGCCqGSM49
AwEHoUQDQgAE1IL73BARrNpkHj1jG50eHoF2LERCwz1BfbshuAeLcsED5aT92Xgu
gJvq45LN9p6eBi62ZZwr6Z2ZfX3YB3/8KA==
-----END EC PRIVATE KEY-----

View File

@@ -1,3 +0,0 @@
# IDF-3090
CONFIG_ESP32C3_REV_MIN_0=y
CONFIG_ESP32C3_REV_MIN=0

View File

@@ -1,3 +0,0 @@
# IDF-3090
CONFIG_ESP32C3_REV_MIN_0=y
CONFIG_ESP32C3_REV_MIN=0

View File

@@ -63,7 +63,7 @@ static void eventfd_timer_init(int timer_idx, double timer_interval_sec)
.counter_dir = TIMER_COUNT_UP,
.counter_en = TIMER_PAUSE,
.alarm_en = TIMER_ALARM_EN,
.auto_reload = false,
.auto_reload = true,
};
ESP_ERROR_CHECK(timer_init(TIMER_GROUP_0, timer_idx, &config));

View File

@@ -1,5 +1,2 @@
# IDF-3090
CONFIG_ESP32C3_REV_MIN_0=y
CONFIG_ESP32C3_REV_MIN=0
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y

View File

@@ -1,5 +1,5 @@
| Supported Targets | ESP32 |
| ----------------- | ----- |
| Supported Targets | ESP32 | ESP32-S2 |
| ----------------- | ----- | -------- |
# Blink Example With Coverage Info (Gcov)
@@ -16,10 +16,10 @@ This example implements a simple blink application but with code coverage enable
### Hardware Required
To run this example, you need an ESP32 dev board connected to a JTAG adapter, which can come in the following forms:
To run this example, you need a supported dev board connected to a JTAG adapter, which can come in the following forms:
* [ESP-WROVER-KIT](https://docs.espressif.com/projects/esp-idf/en/latest/hw-reference/modules-and-boards.html#esp-wrover-kit-v4-1) which integrates an on-board JTAG adapter. Ensure that the [required jumpers to enable JTAG are connected](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/get-started-wrover-kit.html#setup-options) on the WROVER-KIT.
* ESP32 core board (e.g. ESP32-DevKitC) can also work as long as you connect it to an external JTAG adapter (e.g. FT2232H, J-LINK).
* ESP32 or ESP32-S2 core board (e.g. ESP32-DevKitC, [ESP32-S2-Saola-1](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html)) can also work as long as you connect it to an external JTAG adapter (e.g. FT2232H, J-LINK).
This example will assume that that an ESP-WROVER-KIT is used.

View File

@@ -0,0 +1 @@
CONFIG_FREERTOS_UNICORE=y

View File

@@ -1,4 +1,4 @@
CONFIG_APPTRACE_DEST_TRAX=y
CONFIG_APPTRACE_DEST_JTAG=y
# CONFIG_APPTRACE_DEST_NONE is not set
CONFIG_APPTRACE_ENABLE=y
CONFIG_APPTRACE_LOCK_ENABLE=y

View 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(gdbstub)

View File

@@ -3,6 +3,6 @@
# project subdirectory.
#
PROJECT_NAME := net_suite
PROJECT_NAME := gdbstub
include $(IDF_PATH)/make/project.mk

View File

@@ -0,0 +1,127 @@
# GDBstub example
This example shows how to use gdbstub and it's functionality at runtime to debug an application with GDB.
With the gdbstub component it is possible to run GDB from IDF Monitor by pressing Ctrl+C and debug
the application using GDB. It is also possible to read/modify memory values, interrupt and continue the application.
Upon exit from GDB, the application will continue to work in IDF Monitor as before.
## How to use example
### Hardware Required
he example can run on any commonly available ESP32 development board.
There are two possible ways to execute gdbstub with GDB: from IDF Monitor and as standalone application.
gdbstub support ESP32, ESP32-S2 and ESP32-S3 chips.
### Configure the project
By default, the example is already pre-configured, but the user can change configuration options with the following command:
```
idf.py menuconfig
```
Current example is pre-configured. The user can scroll through the system parameters and see the settings.
Most important one is:
-> Component Config -> ESP System Settings -> Panic handler behaviour -> GDBStub on runtime
This selection switches gdbstub to runtime mode.
Depending on the project, following settings could be used:
-> Component Config -> GDB Stub -> ...
The user can enable or disable task list handling and define a maximum amount of tasks.
Note that gdbstub can now only be used when FreeRTOS is run on the first core only.
This setting is located here:
-> Component Config -> FreeRTOS -> Run FreeRTOS only on first core.
### Build and Flash
Build the project and flash it to the board, then run IDF Monitor to view the serial output:
```
idf.py -p PORT flash monitor
```
Replace PORT with the name of the serial port to use, for example COM4 for Windows or /dev/ttyUSB0 for Linux.
To exit the serial monitor, type ``Ctrl-]``.
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
In addition, it is also possible to run GDB and connect to the Esp32 directly, without IDF Monitor.
```
xtensa-esp32-elf-gdb ./build/gdbstub.elf -ex "set serial baud 115200" -ex "target remote \\.\COM10"
```
This will execute GDB and GDB will connect to your Esp32 by serial port COM10 with baudrate 115200.
## Example Output
The example demonstrates how to switch to GDB, watch values, change values, continue to run, and exit from GDB to the application.
To switch to GDB, the user presses Ctrl+C. This will stop the application and run the GDB.
In GDB, the user can print values "print call_count" and "print update_log_level" and then
change them "set call_count 100" and "set update_log_level = ESP_LOG_WARN".
The user can continue running the application in GDB by entering "continue" and then interrupt the application by pressing Ctrl+C.
The user can check again that the application has worked by checking variable "print call_count".
The user can exit from GDB to continue seeing the trace from IDF Monitor by pressing "quit" and then "y".
The user will see in IDF Monitor that call_count and logging level have changed.
A typical console output for such a scenario is shown below:
```
I (300) cpu_start: Starting scheduler on PRO CPU.
Hello GDB example!
I (307) gdbstub_example: INFO mode enabled. Call - 0. To enter GDB please press "Ctrl+C"
W (317) gdbstub_example: WARN mode enabled. Call - 0. To enter GDB please press "Ctrl+C"
I (1317) gdbstub_example: INFO mode enabled. Call - 1. To enter GDB please press "Ctrl+C"
W (1317) gdbstub_example: WARN mode enabled. Call - 1. To enter GDB please press "Ctrl+C"
To exit from the idf.py please use "Ctrl+]"
$T02#b6GNU gdb (crosstool-NG esp-2020r3) 8.1.0.20180627-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-host_w64-mingw32 --target=xtensa-esp32-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from c:\esp-idf\examples\system\gdbstub\build\gdbstub.elf...done.
Remote debugging using \\.\COM15
0x400dff0a in esp_pm_impl_waiti () at C:/esp-idf/components/esp_pm/pm_impl.c:533
533 asm("waiti 0");
(gdb) print call_count
$1 = 2
(gdb) set call_count = 100
(gdb) print call_count
$2 = 100
(gdb) print update_log_level
$3 = ESP_LOG_DEBUG
(gdb) set update_log_level = ESP_LOG_WARN
(gdb) print update_log_level
$4 = ESP_LOG_WARN
(gdb) c
Continuing.
Thread 1 received signal SIGINT, Interrupt.
0x400dff0a in esp_pm_impl_waiti () at C:/esp-idf/components/esp_pm/pm_impl.c:533
533 asm("waiti 0");
(gdb) print call_count
$6 = 108
(gdb) quit
A debugging session is active.
Inferior 1 [Remote target] will be killed.
Quit anyway? (y or n) y
W (13977) gdbstub_example: WARN mode enabled. Call - 108. To enter GDB please press "Ctrl+C"
W (14977) gdbstub_example: WARN mode enabled. Call - 109. To enter GDB please press "Ctrl+C"
W (15977) gdbstub_example: WARN mode enabled. Call - 110. To enter GDB please press "Ctrl+C"
W (16977) gdbstub_example: WARN mode enabled. Call - 111. To enter GDB please press "Ctrl+C"
```
To reproduce this scenario run the application by: idf.py -P PORT flash monitor
Then:
1. Interrupt the application by pressing Ctrl+C
2. In GDB, print the application values by typing in GDB command line "print call_count" or "print update_log_level"
3. Modify the application values by typing in GDB command line "set call_count = 100" or "set update_log_level = ESP_LOG_WARN"
4. Continue the application by typing in GDB command line "continue"
5. Interrupt application by pressing Ctrl+C
6. Check the value by typing in GDB command line "print call_count" or "print update_log_level"
7. Exit GDB by typing "quit" and then "y"
To exit from monitor please use Ctrl+]

View File

@@ -0,0 +1,2 @@
idf_component_register(SRCS "gdbstub_main.c"
INCLUDE_DIRS "")

View File

@@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View 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 "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
int call_count = 0;
static const char *TAG = "gdbstub_example";
esp_log_level_t log_level = ESP_LOG_DEBUG;
esp_log_level_t update_log_level = ESP_LOG_DEBUG;
void app_main(void)
{
printf("Hello GDB example!\n");
call_count = 0;
for (;;) {
ESP_LOGD(TAG, "DEBUG mode enabled. Call - %i. To enter GDB please press \"Ctrl+C\"", call_count);
ESP_LOGI(TAG, "INFO mode enabled. Call - %i. To enter GDB please press \"Ctrl+C\"", call_count);
ESP_LOGW(TAG, "WARN mode enabled. Call - %i. To enter GDB please press \"Ctrl+C\"", call_count++);
if (update_log_level != log_level) {
log_level = update_log_level;
esp_log_level_set(TAG, log_level);
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}

View File

@@ -0,0 +1,22 @@
#
# GDB Stub
#
CONFIG_ESP_GDBSTUB_ENABLED=y
CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y
CONFIG_ESP_GDBSTUB_MAX_TASKS=32
# end of GDB Stub
#
# FreeRTOS
#
CONFIG_FREERTOS_UNICORE=y
#
# ESP System Settings
#
# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set
# CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT is not set
# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set
CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME=y
CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE=y
# end of ESP System Settings

View File

@@ -3,4 +3,4 @@
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(net_suite)
project(ipc_isr)

View File

@@ -0,0 +1,8 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := ipc_isr
include $(IDF_PATH)/make/project.mk

View File

@@ -0,0 +1,56 @@
| Supported Targets | ESP32 | ESP32-S3 |
| ----------------- | ----- | -------- |
# Hi-priority IPC example
This example demonstrates how to use Hi-priority IPC, it is based on Hi-priority interrupt (level 4). This feature can be useful in case when need quickly to get the state of the other CPU (consult the [Hi-priority IPC](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/ipc.html#hi-priority-ipc)).
In the `asm_funcs.S` file are functions that will be run on the other core. The function should be fairly simple that can be written in assembler.
The first asm function `get_ps_other_cpu()` demonstrates a simple way of usage, it returns the PS register of other core.
The second asm function `extended_ipc_isr_asm()` demonstrates way when need to do some complex operations on other core, for this, save registers to the buffer (regs[]) making them available for use. Then using passed arguments (in[]) do some work and write the result to out[]. At the end recover saved registers.
## How to use example
### Hardware Required
Example should be able to run on any commonly available ESP32 development board. The chip should have two cores.
### Configure the project
- `CONFIG_FREERTOS_UNICORE` - disabled,
- `CONFIG_ESP_IPC_ISR_ENABLE` - enabled.
```
idf.py menuconfig
```
### Build and Flash
```
idf.py build flash monitor
```
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
## Example output
```
I (304) example: Start
I (304) example: call get_ps_other_cpu
I (314) example: PS_INTLEVEL = 0x5
I (314) example: PS_EXCM = 0x0
I (324) example: PS_UM = 0x1
I (324) example: call extended_ipc_isr_asm
I (324) example: in[0] = 0x1
I (334) example: in[1] = 0x2
I (334) example: in[2] = 0x3
I (334) example: out[0] = (in[0] | in[1] | in[2]) = 0x3
I (344) example: out[1] = (in[0] & in[1] & in[2]) = 0x6
I (354) example: out[2] = in[2] = 0x3
I (354) example: out[3] = PS of other cpu = 0x25
I (364) example: End
```

View File

@@ -0,0 +1,28 @@
from __future__ import unicode_literals
import ttfw_idf
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32'])
def test_examples_ipc_isr(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
dut = env.get_dut('ipc_isr', 'examples/system/ipc/ipc_isr')
dut.start_app()
dut.expect_all('example: Start',
'example: PS_INTLEVEL = 0x5',
'example: PS_EXCM = 0x0',
'example: PS_UM = 0x1',
'example: in[0] = 0x1',
'example: in[1] = 0x2',
'example: in[2] = 0x3',
'example: out[0] = (in[0] | in[1] | in[2]) = 0x3',
'example: out[1] = (in[0] & in[1] & in[2]) = 0x6',
'example: out[2] = in[2] = 0x3',
'example: out[3] = PS of other cpu = 0x25',
'example: End',
timeout=10)
if __name__ == '__main__':
test_examples_ipc_isr()

View File

@@ -0,0 +1,3 @@
idf_component_register(SRCS "main.c"
"asm_funcs.S"
INCLUDE_DIRS ".")

View File

@@ -0,0 +1,89 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <xtensa/coreasm.h>
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
#include <xtensa/hal.h>
/* get_ps_other_cpu(void *arg)
*
* It should be called by the CALLX0 command from the handler of High-priority interrupt (4 lvl).
* Only these registers [a2, a3, a4] can be used here.
* Returns PS.
*/
.section .iram1, "ax"
.align 4
.global get_ps_other_cpu
.type get_ps_other_cpu, @function
// Args:
// a2 - void* arg
get_ps_other_cpu:
rsr a3, PS
s32i a3, a2, 0
ret
/* extended_ipc_isr_asm(void *arg)
*
* It should be called by the CALLX0 command from the handler of High-priority interrupt (4 lvl).
* Only these registers [a2, a3, a4] can be used here.
* This function receives a structure (arg) where can be saved some regs
* to get them available here, at the end of the function we recover the saved regs.
*/
.section .iram1, "ax"
.align 4
.global extended_ipc_isr_asm
.type extended_ipc_isr_asm, @function
// Args:
// a2 - arg_data_t* arg
extended_ipc_isr_asm:
/* save all registers (a5-a15 -> regs[11]) */
s32i a5, a2, 0
s32i a6, a2, 4
s32i a7, a2, 8
s32i a8, a2, 12
s32i a9, a2, 16
s32i a10, a2, 20
s32i a11, a2, 24
s32i a12, a2, 28
s32i a13, a2, 32
s32i a14, a2, 36
s32i a15, a2, 40
/* do some work with a2 - a15 */
l32i a5, a2, 44 /* a5 <- in[0] */
l32i a6, a2, 48 /* a6 <- in[1] */
l32i a7, a2, 52 /* a7 <- in[2] */
or a8, a5, a6
or a8, a8, a7
add a9, a5, a6
add a9, a9, a7
mov a10, a7
rsr a11, PS
s32i a8, a2, 56 /* a8 -> out[0] */
s32i a9, a2, 60 /* a9 -> out[1] */
s32i a10, a2, 64 /* a10 -> out[2] */
s32i a11, a2, 68 /* a11 -> out[3] */
/* restore all saved registers (regs[11] -> a5-a15) */
l32i a5, a2, 0
l32i a6, a2, 4
l32i a7, a2, 8
l32i a8, a2, 12
l32i a9, a2, 16
l32i a10, a2, 20
l32i a11, a2, 24
l32i a12, a2, 28
l32i a13, a2, 32
l32i a14, a2, 36
l32i a15, a2, 40
ret

View File

@@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View File

@@ -0,0 +1,61 @@
/* ipc_isr 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 <string.h>
#include "esp_timer.h"
#include "esp_log.h"
#include "esp_ipc_isr.h"
#include "sdkconfig.h"
#if __XTENSA__
#include "xtensa/config/core.h"
#else
#error "Doesn't support other architectures"
#endif
static const char* TAG = "example";
typedef struct {
uint32_t regs[11];
uint32_t in[3];
uint32_t out[4];
} arg_data_t;
void get_ps_other_cpu(void* arg);
void extended_ipc_isr_asm(void* arg);
void app_main(void)
{
ESP_LOGI(TAG, "Start");
uint32_t ps_other_cpu = 0;
ESP_LOGI(TAG, "call get_ps_other_cpu");
esp_ipc_isr_asm_call_blocking(get_ps_other_cpu, &ps_other_cpu);
ESP_LOGI(TAG, "PS_INTLEVEL = 0x%x", ps_other_cpu & XCHAL_PS_INTLEVEL_MASK);
ESP_LOGI(TAG, "PS_EXCM = 0x%x", (ps_other_cpu & XCHAL_PS_EXCM_MASK) >> XCHAL_PS_EXCM_SHIFT);
ESP_LOGI(TAG, "PS_UM = 0x%x", (ps_other_cpu & XCHAL_PS_UM_MASK) >> XCHAL_PS_UM_SHIFT);
ESP_LOGI(TAG, "call extended_ipc_isr_asm");
arg_data_t arg = { 0 };
arg.in[0] = 0x01;
arg.in[1] = 0x02;
arg.in[2] = 0x03;
ESP_LOGI(TAG, "in[0] = 0x%x", arg.in[0]);
ESP_LOGI(TAG, "in[1] = 0x%x", arg.in[1]);
ESP_LOGI(TAG, "in[2] = 0x%x", arg.in[2]);
esp_ipc_isr_asm_call_blocking(extended_ipc_isr_asm, (void*)&arg);
ESP_LOGI(TAG, "out[0] = (in[0] | in[1] | in[2]) = 0x%x", arg.out[0]);
assert(0x03 == arg.out[0]);
ESP_LOGI(TAG, "out[1] = (in[0] & in[1] & in[2]) = 0x%x", arg.out[1]);
assert(0x06 == arg.out[1]);
ESP_LOGI(TAG, "out[2] = in[2] = 0x%x", arg.out[2]);
assert(0x03 == arg.out[2]);
ESP_LOGI(TAG, "out[3] = PS of other cpu = 0x%x", arg.out[3]);
assert(ps_other_cpu == arg.out[3]);
ESP_LOGI(TAG, "End");
}

View File

@@ -1,4 +1 @@
# IDF-3090
CONFIG_ESP32C3_REV_MIN_0=y
CONFIG_ESP32C3_REV_MIN=0
CONFIG_ESP32_DEFAULT_CPU_FREQ_80=y

View File

@@ -1,65 +0,0 @@
# Intel net test suite for LwIP network stack
This project provides a test interface to esp32 network stack in order to execute standard set of
Intel network test suite defined in TTCN3 framework.
## Important notice
*This is an internal ESP-IDF test and not a user project example*
## Execute net test suite
These network tests could be executed in both manual or automated mode in CI.
Note: TTCN3 engine works reliably only on Linux and Windows.
## Setup TTCN3
* Clone a repository https://github.com/intel/net-test-suites.git and install titan core as described in the README.md
* Copy files `esp32_netsuite.cfg` and `esp32_netsuite.ttcn` (located in `$IDF_PATH/components/lwip/weekend_test`) to `src` subdir of the cloned repository `net-test-suites`
* Rebuild the netsuite tests (according to README.md in net-test-suite) by executing `source make.sh` in `src` subdir
## Build application
```
cd $IDF_PATH/examples/system/network_tests
idf.py build
idf.py -p PORT flash
```
## Run test
Open two terminals (1) and (2)
1) Start the test server which would pass packets from TTCN3 test suite into ESP32 board in `$IDF_PATH/components/lwip/weekend_test`
```
python net_suite_test.py
```
2) Start test suite in TTCN3 environment in `src` subdir of the cloned repository `net-test-suites.git`
```
ttcn3_start test_suite esp32_netsuite.cfg
```
## Internal connection
Purpose of this test is to execute standard network suite on a ESP32 network stack.
DUT, Device (Network stack in this case) under test, runs normally on target, but a specific interface with configured esp-netif for passing arbitrary data to
and from the network stack. Embedded code `net_suite.c` implements an application which serves stdin/stdout and propagates the data to/from this test interface.
Standard Intel net suite executed by TTCN3 engine uses udp ports for input/ouput of network packets. Python script `net_suite.py` translates this communication
from/to those udp ports to stdin/stdout, where after propagating over USB/UART to the ESP32 board are processed in the network stack (on the target).
Actual test execution, progress, evaluation and test reporting is done using standard net-test-suite scripts running on PC.
```
PC
+---------------------------------------------------------+ ESP32 board
| | +----------------------------------------+
| TTCN3 engine | | +----------------------------------+ |
| | | | net_suite.c | |
| +-----------------+ +--------------+ | | | +------------------------+ |
| | net-test-suite |--7777/udp--| net_suite.py |--stdout---------| -----> | esp_netif / lwip | |
| | |--7771/udp--| |--stdin----------| <----- | | |
| +-----------------+ +--------------+ | | +---------+------------------------+ |
+---------------------------------------------------------+ +----------------------------------------+
```

View File

@@ -1,2 +0,0 @@
idf_component_register(SRCS "net_suite.c" "stdinout.c"
INCLUDE_DIRS ".")

View File

@@ -1,8 +0,0 @@
#
# Main component makefile.
#
# This Makefile can be left empty. By default, it will take the sources in the
# src/ directory, compile them and link them into lib(subdirectory_name).a
# in the build directory. This behaviour is entirely configurable,
# please read the ESP-IDF documents if you need to do this.
#

View File

@@ -1,134 +0,0 @@
/* Net-suite test code
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 <string.h>
#include "esp_event.h"
#include "esp_log.h"
#include "stdinout.h"
#include "lwip/err.h"
#include "lwip/debug.h"
#include "lwip/tcp.h"
/* these test data are used to populate the ARP cache so the IPs are known */
static char arp1[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x01,
0x08, 0x00, 0x06, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x01
};
/* Test data (ICMP packet) for verification of tcp ip test netif
00-00-00-00-00-01-00-00-00-00-00-02-08-00-45-00-00-1c-00-00-00-00-ff-01-a7-de-0a-00-00-02-0a-00-00-01-08-00-f7-fd-00-01-00-01
*/
/* creating test pcb */
static struct tcp_pcb *test_pcb;
err_t test_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
return ERR_OK;
}
void test_error(void *arg, err_t err)
{
printf("Error CB from pcb %d\n", err);
}
err_t test_poll(void *arg, struct tcp_pcb *tpcb)
{
return ERR_OK;
}
err_t test_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(err);
tcp_setprio(newpcb, TCP_PRIO_MIN);
tcp_arg(newpcb, NULL);
tcp_recv(newpcb, test_recv);
tcp_err(newpcb, test_error);
tcp_poll(newpcb, test_poll, 0);
return ERR_OK;
}
void test_tcp_init(void)
{
test_pcb = tcp_new();
if (test_pcb != NULL) {
err_t err;
/* Binding this test_pcb to 4242 to accept connections on this port
* - this has to be configured as DUT endpoint
* - all network traffic from and to network stack is tracked in nettestif
*/
err = tcp_bind(test_pcb, IP_ADDR_ANY, 4242);
if (err == ERR_OK) {
test_pcb = tcp_listen(test_pcb);
tcp_accept(test_pcb, test_accept);
} else {
printf("cannot bind test_pcb\n");
abort();
}
} else {
printf("cannot create test_pcb\n");
abort();
}
}
void app_main(void)
{
char packet[128];
// Netif configs
//
esp_netif_ip_info_t ip_info;
uint8_t mac[] = { 0,0,0,0,0,1};
esp_netif_inherent_config_t netif_common_config = {
.flags = ESP_NETIF_FLAG_AUTOUP,
.ip_info = (esp_netif_ip_info_t*)&ip_info,
.if_key = "TEST",
.if_desc = "net_test_if"
};
esp_netif_set_ip4_addr(&ip_info.ip, 10, 0 , 0, 1);
esp_netif_set_ip4_addr(&ip_info.gw, 10, 0 , 0, 1);
esp_netif_set_ip4_addr(&ip_info.netmask, 255, 255 , 255, 0);
esp_netif_config_t config = {
.base = &netif_common_config, // use specific behaviour configuration
.stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA, // use default WIFI-like network stack configuration
};
// Netif creation and configuration
//
ESP_ERROR_CHECK(esp_netif_init());
esp_netif_t* netif = esp_netif_new(&config);
assert(netif);
esp_netif_attach(netif, netsuite_io_new());
// Start the netif in a manual way, no need for events
//
esp_netif_set_mac(netif, mac);
esp_netif_action_start(netif, NULL, 0, NULL);
// initializes TCP endpoint on DUT per https://github.com/intel/net-test-suites#21-endpoints
test_tcp_init();
// Inject ARP packet to let the network stack know about IP/MAC of the counterpart
esp_netif_receive(netif, arp1, sizeof(arp1), NULL);
/* Now read from stdin and pass the data to test netif */
while (1) {
/* read one packet from the I/O object */
ssize_t len = netsuite_io_get_packet(packet, sizeof(packet));
if (len > 0) {
/* input the packet to esp-netif */
esp_netif_receive(netif, packet, len, NULL);
}
}
}

View File

@@ -1,181 +0,0 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_netif.h"
#include "esp_log.h"
#include "driver/uart.h"
#include "esp_console.h"
#include "esp_vfs_dev.h"
#include "linenoise/linenoise.h"
//
// Internal functions declaration referenced in io object
//
static esp_err_t netsuite_io_transmit(void *h, void *buffer, size_t len);
static esp_err_t netsuite_io_transmit_wrap(void *h, void *buffer, size_t len, void *netstack_buf);
static esp_err_t netsuite_io_attach(esp_netif_t * esp_netif, void * args);
/**
* @brief IO object netif related configuration with data-path function callbacks
* and pointer to the IO object instance (unused as this is a singleton)
*/
const esp_netif_driver_ifconfig_t c_driver_ifconfig = {
.driver_free_rx_buffer = NULL,
.transmit = netsuite_io_transmit,
.transmit_wrap = netsuite_io_transmit_wrap,
.handle = "netsuite-io-object" // this IO object is a singleton, its handle uses as a name
};
/**
* @brief IO object base structure used to point to internal attach function
*/
const esp_netif_driver_base_t s_driver_base = {
.post_attach = netsuite_io_attach
};
/**
* @brief Transmit function called from esp_netif to output network stack data
*
* Note: This API has to conform to esp-netif transmit prototype
*
* @param h Opaque pointer representing the io driver (unused, const string in this case)
* @param data data buffer
* @param length length of data to send
*
* @return ESP_OK on success
*/
static esp_err_t netsuite_io_transmit(void *h, void *buffer, size_t len)
{
/* output the packet to stdout */
char *data = buffer;
printf("\nPacketOut:[");
for (size_t i=0; i<len; i++) {
printf("%02x", *data++);
}
printf("]\n");
return ESP_OK;
}
/**
* @brief Transmit wrapper that is typically used for buffer handling and optimization.
* Here just wraps the netsuite_io_transmit().
*
* @note The netstack_buf could be a ref-counted network stack buffer and might be used
* by the lower layers directly if an additional handling is practical.
* See docs on `esp_wifi_internal_tx_by_ref()` in components/esp_wifi/include/esp_private/wifi.h
*/
static esp_err_t netsuite_io_transmit_wrap(void *h, void *buffer, size_t len, void *netstack_buf)
{
return netsuite_io_transmit(h, buffer, len);
}
/**
* @brief Post attach adapter for netsuite i/o
*
* Used to exchange internal callbacks and context between esp-netif and the I/O object.
* In case of netsuite I/O, it only updates the driver config with internal callbacks and
* its instance pointer (const string in this case)
*
* @param esp_netif handle to esp-netif object
* @param args pointer to netsuite IO
*
* @return ESP_OK on success
*/
static esp_err_t netsuite_io_attach(esp_netif_t * esp_netif, void * args)
{
ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &c_driver_ifconfig));
return ESP_OK;
}
/**
* @brief Process line read from serial input, character by character
*
* Converts from hex string to byte stream, so it can be processed
* in test network interface
*
* @param line
* @param packet
*
* @return size of packet
*/
static size_t process_line(char* line, char* packet)
{
size_t count = 0;
size_t i;
for (i=0; i< strlen(line); i++) {
char c = line[i];
// accept both separators between bytes
if (c == '-' || c == ' ') {
++count;
// Processing numeric characters
} else if (c >= '0' && c <= '9') {
packet[count] *= 16;
packet[count] += c - '0';
// Processing alpha-numeric hex characters
} else if (c >= 'a' && c <= 'f') {
packet[count] *= 16;
packet[count] += c - 'a' + 10;
}
}
if (i>0 && strlen(line)>0) {
count++;
}
return count;
}
/**
* Created (initializes) the i/o object and returns handle ready to be attached to the esp-netif
*/
void * netsuite_io_new(void)
{
// Initialize VFS & UART so we can use std::cout/cin
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
/* Install UART driver for interrupt-driven reads and writes */
ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM,
256, 0, 0, NULL, 0) );
/* Tell VFS to use UART driver */
esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
/* Move the caret to the beginning of the next line on '\n' */
esp_vfs_dev_uart_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
linenoiseSetDumbMode(1);
return (void *)&s_driver_base;
}
/**
* I/O receive function
*/
ssize_t netsuite_io_get_packet(char *packet, size_t max_len)
{
size_t size;
/* read packet from stdin */
char* line = linenoise("");
if (!line) {
return -1;
}
/* convert to binary */
size = process_line(line, packet);
if (size > max_len) {
return -1;
}
linenoiseFree(line);
return size;
}

View File

@@ -1,36 +0,0 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _NET_SUITE_STDINOUT_H
#define _NET_SUITE_STDINOUT_H
/**
* @brief Gets one packet from stdin
*
* @param packet ptr to the packet buffer
* @param max_len maximum size of allocated data buffer
*
* @return actual size of received packet (-1 in case of error)
*/
ssize_t netsuite_io_get_packet(char *packet, size_t max_len);
/**
* @brief Initializes the I/O object handle to be attached to esp-netif instance
*
* @return I/O object pointer
*/
void * netsuite_io_new(void);
#endif //_NET_SUITE_STDINOUT_H

View File

@@ -1,23 +1,29 @@
# OTA Example
**Notes:** *This guide is common for all ota examples*
---
**NOTES**
- This guide applies to all OTA update examples
- "ESP-Dev-Board" refers to any Espressif chipset development board (e.g., ESP32/ESP32-S2/ESP32-C3 etc.)
---
## Overview
ESP32 application can do upgrading at runtime by downloading new image from specific server through Wi-Fi or Ethernet and then flash it into some partitions. Therere two ways in ESP-IDF to perform Over The Air (OTA) upgrading:
An application on "ESP-Dev-Board" may be upgraded at runtime by downloading a new image via Wi-Fi or Ethernet and flashing it to an OTA partition. The ESP-IDF offers two methods to perform Over The Air (OTA) upgrades:
- Using the native APIs provided by `app_update` component.
- Using simplified APIs provided by `esp_https_ota` component, which adds an abstraction layer over the native OTA APIs in order to upgrading with HTTPS protocol.
- Using the native APIs provided by the [`app_update`](../../../components/app_update) component.
- Using simplified APIs provided by the [`esp_https_ota`](../../../components/esp_https_ota) component, which provides functionality to upgrade over HTTPS.
Use of native APIs is demonstrated under `native_ota_example` while use of APIs provided by `esp_https_ota` component is demonstrated under `simple_ota_example` and `advanced_https_ota`.
Use of the native API is demonstrated in the `native_ota_example` directory while the API provided by the `esp_https_ota` component is demonstrated under `simple_ota_example` and `advanced_https_ota`.
For information regarding APIs provided by `esp_https_ota` component, please refer to [ESP HTTPS OTA](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/esp_https_ota.html).
For information regarding the `esp_https_ota` component, please refer to [ESP HTTPS OTA](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/esp_https_ota.html).
For simplicity, the OTA examples choose the pre-defined partition table by enabling `CONFIG_PARTITION_TABLE_TWO_OTA` option in menuconfig, which supports three app partitions: factory, OTA_0 and OTA_1. For more information about partition table, please refer to [Partition Tables](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/partition-tables.html).
For simplicity, the OTA examples use a pre-defined partition table created by enabling the `CONFIG_PARTITION_TABLE_TWO_OTA` option in menuconfig, which supports three app partitions: `factory`, `OTA_0` and `OTA_1`. Please refer to [Partition Tables](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/partition-tables.html) for more information.
On first boot, the bootloader will load the factory app image (i.e. the example image) and then triggers an OTA upgrading. It will download a new image from HTTPS server and save it into the OTA_0 partition. It will update the ota_data partition automatically as well to indicate which app should boot from in the next reset. The bootloader will read the content in ota_data partition and run the selected application.
On first boot, the bootloader will load the image contained on the `factory` partition (i.e. the example image). This firmware triggers an OTA upgrade. It will download a new image from an HTTPS server and save it into the `OTA_0` partition. Next, it updates the `ota_data` partition to indicate which app should boot after the next reset. Upon reset, the bootloader reads the contents of the `ota_data` partition to determine which application is selected to run.
The OTA workflow can be demonstrated as in the following diagram:
The OTA workflow is illustrated in the following diagram:
![OTA Workflow](ota_workflow.png)
@@ -25,32 +31,30 @@ The OTA workflow can be demonstrated as in the following diagram:
### Hardware Required
To run the OTA examples, you need an ESP32 dev board (e.g. ESP32-WROVER Kit) or ESP32 core board (e.g. ESP32-DevKitC). If you want to test the OTA with Ethernet, make sure your board has set up the Ethernet correctly. For extra information about setting up Ethernet, please refer to Ethernet examples.
"ESP-Dev-Board" is necessary to run the OTA examples. Make sure Ethernet is configured correctly if testing OTA with Ethernet. For further information about setting up Ethernet, please refer to the Ethernet [examples](../../ethernet).
### Configure the project
Open the project configuration menu (`idf.py menuconfig`).
Open the project configuration menu (`idf.py menuconfig`).
In the `Example Connection Configuration` menu:
* Choose the network interface in `Connect using` option based on your board. Currently we support both Wi-Fi and Ethernet.
* If you have selected the Wi-Fi interface, you also have to set:
* Wi-Fi SSID and Wi-Fi password that your ESP32 will connect to
* If you have selected the Ethernet interface, you also have to:
* Set PHY model under `Ethernet PHY Device` option, e.g. IP101.
* Choose the network interface in the `Connect using` option based on your board. Currently both Wi-Fi and Ethernet are supported
* If the Wi-Fi interface is used, provide the Wi-Fi SSID and password of the AP you wish to connect to
* If using the Ethernet interface, set the PHY model under `Ethernet PHY Device` option, e.g. `IP101`
In the `Example Configuration` menu:
* Set the URL of the new firmware that you will download from in the `Firmware Upgrade URL` option, whose format should be `https://<host-ip-address>:<host-port>/<firmware-image-filename>`, e.g. `https://192.168.2.106:8070/hello-world.bin`
* **Notes:** The server part of this URL (e.g. `192.168.2.106`) must match the **CN** field used when [generating the certificate and key](#run-https-server).
* Set the URL of the firmware to download in the `Firmware Upgrade URL` option. The format should be `https://<host-ip-address>:<host-port>/<firmware-image-filename>`, e.g. `https://192.168.2.106:8070/hello-world.bin`
* **Note:** The server part of this URL (e.g. `192.168.2.106`) must match the **CN** field used when [generating the certificate and key](#run-https-server)
### Build and Flash
Run `idf.py -p PORT flash monitor` to build and flash the project.. This command will find if partition table has ota_data partition (as in our case) then ota_data will erase to initial. It allows to run the newly loaded app from a factory partition.
Run `idf.py -p PORT flash monitor` to build and flash the project. This command checks if the partition table contains the `ota_data` partition and restores it to an initial state. This allows the newly loaded app to run from the `factory` partition.
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for all steps required to configure and use the ESP-IDF to build projects.
## Example Output
@@ -60,21 +64,21 @@ After a successful build, we need to create a self-signed certificate and run a
![create_self_signed_certificate](https://dl.espressif.com/dl/esp-idf/docs/_static/ota_self_signature.gif)
* Enter a directory where holds the root of the HTTPS server, e.g. `cd build`.
* To create a new self-signed certificate and key, you can simply run command `openssl req -x509 -newkey rsa:2048 -keyout ca_key.pem -out ca_cert.pem -days 365 -nodes`.
* When prompted for the `Common Name (CN)`, enter the name of the server that the ESP32 will connect to. Regarding this example, it is probably the IP address. The HTTPS client will make sure that the `CN` matches the address given in the HTTPS URL.
* To start the HTTPS server, you can simply run command `openssl s_server -WWW -key ca_key.pem -cert ca_cert.pem -port 8070`.
* In the same directory, there should be the firmware (e.g. hello-world.bin) that ESP32 will download later. It can be any other ESP-IDF application as well, as long as you also update the `Firmware Upgrade URL` in the menuconfig. The only difference is that when flashed via serial the binary is flashed to the "factory" app partition, and an OTA update flashes to an OTA app partition.
* **Notes:** If you have any firewall software running that will block incoming access to port *8070*, configure it to allow access while running the example.
* **Notes:** Windows users may encounter certain issues while running `openssl s_server -WWW`, due to CR/LF translation and/or closing the connection prematurely
(Some windows builds of openssl translate CR/LF sequences to LF in the served files, leading to corrupted image received by the OTA client; Others might interpret `0x1a`/`SUB` character in the binary as an escape sequence, i.e. end of file, thus closing the connection, failing the OTA client to receive the entire image).
* It's recommended to use `openssl` bundled in `Git For Windows` from the [ESP-IDF Tool installer](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/windows-setup.html):
Open the ESP-IDF command prompt and add the internal openssl binary to your path: `set PATH=%LocalAppData%\Git\usr\bin;%PATH%` and run the openssl's http server command as above.
* Alternatively, you can use any windows based openssl of version at least `v1.1.1i` build on `Msys-x86_64` platform, or a simple python https server -- see start_https_server in the [example_test](simple_ota_example/example_test.py) script.
* Enter the directory containing build artifact/s of project, that will be hosted by HTTPS server, e.g. `cd build`.
* To create a new self-signed certificate and key, run the command `openssl req -x509 -newkey rsa:2048 -keyout ca_key.pem -out ca_cert.pem -days 365 -nodes`.
* When prompted for the `Common Name (CN)`, enter the name of the server that the "ESP-Dev-Board" will connect to. When running this example from a development machine, this is probably the IP address. The HTTPS client will check that the `CN` matches the address given in the HTTPS URL.
* To start the HTTPS server, run the command `openssl s_server -WWW -key ca_key.pem -cert ca_cert.pem -port 8070`.
* This directory should contain the firmware (e.g. `hello-world.bin`) to be used in the update process. This can be any valid ESP-IDF application, as long as its filename corresponds to the name configured using `Firmware Upgrade URL` in menuconfig. The only difference to flashing a firmware via the serial interface is that the binary is flashed to the `factory` partition, while OTA update use one of the OTA partitions.
* **Note:** Make sure incoming access to port *8070* is not prevented by firewall rules.
* **Note:** Windows users may encounter issues while running `openssl s_server -WWW`, due to CR/LF translation and/or closing the connection prematurely
(Some windows builds of openssl translate CR/LF sequences to LF in the served files, leading to corrupted images received by the OTA client; others interpret the `0x1a`/`SUB` character in a binary as an escape sequence, i.e. end of file, and close the connection prematurely thus preventing the OTA client from receiving a complete image).
* We recommend using the `openssl` binary bundled in `Git For Windows` from the [ESP-IDF Tool installer](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/windows-setup.html):
Open the ESP-IDF command prompt and add the internal openssl binary to your path: `set PATH=%LocalAppData%\Git\usr\bin;%PATH%` and run openssl's http server command as above.
* Alternatively, use any windows based openssl with version `v1.1.1i` or greater built on the `Msys-x86_64` platform, or a simple python https server -- see `start_https_server` in the [example_test](simple_ota_example/example_test.py) script.
### Flash Certificate to ESP32
### Flash Certificate to "ESP-Dev-Board"
Before you flash the example, make sure to copy the generated certificate to `server_certs` directory inside OTA example directory so that it can be flashed into ESP32 together with the firmware, e.g. `cp ca_cert.pem ../server_certs/`.
Finally, copy the generated certificate to the `server_certs` directory contained in the example directory so it can be flashed onto your device along with the firmware, e.g. `cp ca_cert.pem ../server_certs/`.
```
cp ca_cert.pem /path/to/ota/example/server_certs/
@@ -82,18 +86,18 @@ cp ca_cert.pem /path/to/ota/example/server_certs/
### Internal workflow of the OTA Example
When the example starts up, it will print "Starting OTA example" to the console and then:
After booting, the firmware prints "Starting OTA example" to the console and:
1. Connect to the AP with configured SSID and Password (Wi-Fi case) or just by Ethernet.
2. Connect to the HTTPS server and download the new image.
3. Write the image to flash, and configure the next boot from this image.
4. Reboot
1. Connects via Ethernet or to the AP using the provided SSID and password (Wi-Fi case)
2. Connects to the HTTPS server and downloads the new image
3. Writes the image to flash, and instructs the bootloader to boot from this image after the next reset
4. Reboots
If you want to rollback to factory app (or the first OTA partition when the factory partition do not exist) after the upgrade, then run the command `idf.py erase_otadata`. It can erase the ota_data partition to initial state.
If you want to rollback to the `factory` app after the upgrade (or to the first OTA partition in case the `factory` partition does not exist), run the command `idf.py erase_otadata`. This restores the `ota_data` partition to its initial state.
**Notes:** This assumes that the partition table of this project is the one that is on the device.
**Note:** This assumes that the partition table of this project is the one present on the device.
### Output from HTTPS server
### Output from the HTTPS server
```bash
FILE:hello-world.bin
@@ -101,48 +105,50 @@ ACCEPT
```
## Support rollback
## Supporting Rollback
This feature allows you to roll back to the previous firmware if the app is not operable. Option `CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` allows you to track the first boot of the application (see the ``Over The Air Updates (OTA)`` article).
For ``native_ota_example``, added a bit of code to demonstrate how a rollback works. To use it, you need enable the `CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option in menuconfig and under the "Example Configuration" submenu to set "Number of the GPIO input for diagnostic" to manage the rollback process.
This feature allows you to roll back to a previous firmware if new image is not useable. The menuconfig option `CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` allows you to track the first boot of the application (see the ``Over The Air Updates (OTA)`` article).
To trigger a rollback, this GPIO must be pulled low while the message `Diagnostics (5 sec)...` which will be on first boot.
If GPIO is not pulled low then the operable of the app will be confirmed.
The ``native_ota_example`` contains code to demonstrate how a rollback works. To use it, enable the `CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option in the `Example Configuration` submenu of menuconfig to set `Number of the GPIO input for diagnostic` to manipulate the rollback process.
## Support the version of application
To trigger a rollback, this GPIO must be pulled low while the message `Diagnostics (5 sec)...` is displayed during the first boot.
For ``native_ota_example``, code has been added to demonstrate how to check the version of the application and prevent infinite firmware updates. Only the application with the new version can be downloaded. Version checking is performed after the very first firmware image package has been received, which contains data about the firmware version. The application version can be taken from three places:
If GPIO is not pulled low, the app is confirmed as operable.
1. If `CONFIG_APP_PROJECT_VER_FROM_CONFIG` option is set, the value of `CONFIG_APP_PROJECT_VER` will be used.
2. Else, if ``PROJECT_VER`` variable set in project Cmake/Makefile file, its value will be used.
3. Else, if the ``$PROJECT_PATH/version.txt`` exists, its contents will be used as ``PROJECT_VER``.
4. Else, if the project is located inside a Git repository, the output of ``git describe`` will be used.
5. Otherwise, ``PROJECT_VER`` will be "1".
## Support for Versioning of Applications
In ``native_ota_example``, ``$PROJECT_PATH/version.txt`` is used to define the version of app. Change the version in the file to compile the new firmware.
The ``native_ota_example`` contains code to demonstrate how to check the version of the application and prevent infinite firmware update loops. Only newer applications are downloaded. Version checking is performed after the first firmware image package containing version data is received. The application version is obtained from one of three places:
1. If the `CONFIG_APP_PROJECT_VER_FROM_CONFIG` option is set, the value of `CONFIG_APP_PROJECT_VER` is used
2. Else, if the ``PROJECT_VER`` variable is set in the project `CMakeLists.txt` file, this value is used
3. Else, if the file ``$PROJECT_PATH/version.txt`` exists, its contents are used as ``PROJECT_VER``
4. Else, if the project is located in a Git repository, the output of ``git describe`` is used
5. Otherwise, ``PROJECT_VER`` will be "1"
In ``native_ota_example``, ``$PROJECT_PATH/version.txt`` is used to define the app version. Change the version in the file to compile the new firmware.
## Troubleshooting
* Check your PC can ping the ESP32 at its IP, and that the IP, AP and other configuration settings are correct in menuconfig.
* Check if any firewall software is preventing incoming connections on the PC.
* Check whether you can see the configured file (default hello-world.bin), by checking the output of the command `curl -v https://<host-ip-address>:<host-port>/<firmware-image-filename>`
* If you have another PC or a phone, try viewing the file listing from the separate host.
* Check that your PC can ping the "ESP-Dev-Board" using its IP, and that the IP, AP and other configuration settings are correctly configured in menuconfig
* Check if any firewall software is preventing incoming connections on the PC
* Check whether you can see the configured file (default `hello-world.bin`), by running the command `curl -v https://<host-ip-address>:<host-port>/<firmware-image-filename>`
* Try viewing the file listing from a separate host or phone
### Error "ota_begin error err=0x104"
If you see this error then check that the configured (and actual) flash size is large enough for the partitions in the partition table. The default "two OTA slots" partition table only works with 4MB flash size. To use OTA with smaller flash sizes, create a custom partition table CSV (look in components/partition_table) and configure it in menuconfig.
If you see this error, check that the configured (and actual) flash size is large enough for the partitions in the partition table. The default "two OTA slots" partition table requires at least 4MB flash size. To use OTA with smaller flash sizes, create a custom partition table CSV (for details see [Partition Tables](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/partition-tables.html)) and configure it in menuconfig.
If changing partition layout, it is usually wise to run "idf.py erase_flash" between steps.
Make sure to run "idf.py erase_flash" after making changes to the partition table.
### Local https server
Running a local https server might be tricky in some cases (due to self signed certificates, or potential issues with `openssl s_server` on Windows). Here are some tips of using other means of running http(s) server:
* Run a non secure HTTP server to test the connection. (Note that using a plain http is **not secure** and should be used for testing purpose only)
- Execute `python -m http.server 8070` in the directory with the firmware image.
- Use http://<host-ip>:8070/<firmware-name> as firmware upgrade URL.
- Enable *Allow HTTP for OTA* (`CONFIG_OTA_ALLOW_HTTP`) in `Component config -> ESP HTTPS OTA` so the URI with no certificate is accepted.
* Start the https server using [example_test](simple_ota_example/example_test.py) with two or more parameters: `example_test.py <BIN_DIR> <PORT> [CERT_DIR]`, where
- `<BIN_DIR>` is a directory containing the image and by default also the certificate and key files:`ca_cert.pem` and `ca_key.pem`.
Running a local https server might be tricky in some cases (due to self signed certificates, or potential issues with `openssl s_server` on Windows). Here are some suggestions for alternatives:
* Run a plain HTTP server to test the connection. (Note that using a plain http is **not secure** and should only be used for testing)
- Execute `python -m http.server 8070` in the directory with the firmware image
- Use http://<host-ip>:8070/<firmware-name> as the firmware upgrade URL
- Enable *Allow HTTP for OTA* (`CONFIG_OTA_ALLOW_HTTP`) in `Component config -> ESP HTTPS OTA` so the URI without TLS is accepted
* Start the https server using [example_test](simple_ota_example/example_test.py) with two or more parameters: `example_test.py <BIN_DIR> <PORT> [CERT_DIR]`, where:
- `<BIN_DIR>` is a directory containing the image and by default also the certificate and key files:`ca_cert.pem` and `ca_key.pem`
- `<PORT>` is the server's port, here `8070`
- `[CERT_DIR]` is an optional argument pointing to a specific directory with the certificate and key file.
- example of the script output:
@@ -152,4 +158,4 @@ $ python example_test.py build 8070
Starting HTTPS server at "https://:8070"
192.168.10.106 - - [02/Mar/2021 14:32:26] "GET /simple_ota.bin HTTP/1.1" 200 -
```
* Post the firmware image to some public server (e.g. github.com) and copy it's root certificate to the `server_certs` dir as `ca_cert.pem`. (The certificate could be downloaded using the `s_client` openssl command, if the host includes the root certificate in the chain, for example `openssl s_client -showcerts -connect github.com:443 </dev/null`)
* Publish the firmware image on a public server (e.g. github.com) and copy its root certificate to the `server_certs` directory as `ca_cert.pem`. (The certificate can be downloaded using the `s_client` openssl command if the host includes the root certificate in the chain, e.g. `openssl s_client -showcerts -connect github.com:443 </dev/null`)

View File

@@ -1,3 +1,6 @@
| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 |
| ----------------- | ----- | -------- | -------- |
# Advanced HTTPS OTA example
This example is based on `esp_https_ota` component's APIs.

View File

@@ -3,6 +3,6 @@
nvs, data, nvs, , 0x4000,
otadata, data, ota, , 0x2000,
phy_init, data, phy, , 0x1000,
emul_efuse,data,efuse, , 0x2000,
ota_0, app, ota_0, , 3584K,
ota_1, app, ota_1, , 3584K,
emul_efuse, data, 5, , 0x2000
1 # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, , 0x4000,
4 otadata, data, ota, , 0x2000,
5 phy_init, data, phy, , 0x1000,
6 emul_efuse,data,efuse, , 0x2000,
7 ota_0, app, ota_0, , 3584K,
8 ota_1, app, ota_1, , 3584K,
emul_efuse, data, 5, , 0x2000

View File

@@ -13,54 +13,53 @@ from RangeHTTPServer import RangeRequestHandler
from tiny_test_fw import DUT, Utility
server_cert = '-----BEGIN CERTIFICATE-----\n' \
'MIIDXTCCAkWgAwIBAgIJAP4LF7E72HakMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV\n'\
'BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n'\
'aWRnaXRzIFB0eSBMdGQwHhcNMTkwNjA3MDk1OTE2WhcNMjAwNjA2MDk1OTE2WjBF\n'\
'MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n'\
'ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n'\
'CgKCAQEAlzfCyv3mIv7TlLkObxunKfCdrJ/zgdANrsx0RBtpEPhV560hWJ0fEin0\n'\
'nIOMpJSiF9E6QsPdr6Q+eogH4XnOMU9JE+iG743N1dPfGEzJvRlyct/Ck8SswKPC\n'\
'9+VXsnOdZmUw9y/xtANbURA/TspvPzz3Avv382ffffrJGh7ooOmaZSCZFlSYHLZA\n'\
'w/XlRr0sSRbLpFGY0gXjaAV8iHHiPDYLy4kZOepjV9U51xi+IGsL4w75zuMgsHyF\n'\
'3nJeGYHgtGVBrkL0ZKG5udY0wcBjysjubDJC4iSlNiq2HD3fhs7j6CZddV2v845M\n'\
'lVKNxP0kO4Uj4D8r+5USWC8JKfAwxQIDAQABo1AwTjAdBgNVHQ4EFgQU6OE7ssfY\n'\
'IIPTDThiUoofUpsD5NwwHwYDVR0jBBgwFoAU6OE7ssfYIIPTDThiUoofUpsD5Nww\n'\
'DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAXIlHS/FJWfmcinUAxyBd\n'\
'/xd5Lu8ykeru6oaUCci+Vk9lyoMMES7lQ+b/00d5x7AcTawkTil9EWpBTPTOTraA\n'\
'lzJMQhNKmSLk0iIoTtAJtSZgUSpIIozqK6lenxQQDsHbXKU6h+u9H6KZE8YcjsFl\n'\
'6vL7sw9BVotw/VxfgjQ5OSGLgoLrdVT0z5C2qOuwOgz1c7jNiJhtMdwN+cOtnJp2\n'\
'fuBgEYyE3eeuWogvkWoDcIA8r17Ixzkpq2oJsdvZcHZPIZShPKW2SHUsl98KDemu\n'\
'y0pQyExmQUbwKE4vbFb9XuWCcL9XaOHQytyszt2DeD67AipvoBwVU7/LBOvqnsmy\n'\
'hA==\n'\
'MIIDWDCCAkACCQCbF4+gVh/MLjANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJJ\n'\
'TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD\n'\
'VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j\n'\
'b20wHhcNMjEwNzEyMTIzNjI3WhcNNDEwNzA3MTIzNjI3WjBuMQswCQYDVQQGEwJJ\n'\
'TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD\n'\
'VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j\n'\
'b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhxF/y7bygndxPwiWL\n'\
'SwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQuc32W\n'\
'ukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2mKRbQ\n'\
'S5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO2fEz\n'\
'YaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnvL6Oz\n'\
'3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdOAoap\n'\
'rFTRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAItw24y565k3C/zENZlxyzto44ud\n'\
'IYPQXN8Fa2pBlLe1zlSIyuaA/rWQ+i1daS8nPotkCbWZyf5N8DYaTE4B0OfvoUPk\n'\
'B5uGDmbuk6akvlB5BGiYLfQjWHRsK9/4xjtIqN1H58yf3QNROuKsPAeywWS3Fn32\n'\
'3//OpbWaClQePx6udRYMqAitKR+QxL7/BKZQsX+UyShuq8hjphvXvk0BW8ONzuw9\n'\
'RcoORxM0FzySYjeQvm4LhzC/P3ZBhEq0xs55aL2a76SJhq5hJy7T/Xz6NFByvlrN\n'\
'lFJJey33KFrAf5vnV9qcyWFIo7PYy2VsaaEjFeefr7q3sTFSMlJeadexW2Y=\n'\
'-----END CERTIFICATE-----\n'
server_key = '-----BEGIN PRIVATE KEY-----\n'\
'MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCXN8LK/eYi/tOU\n'\
'uQ5vG6cp8J2sn/OB0A2uzHREG2kQ+FXnrSFYnR8SKfScg4yklKIX0TpCw92vpD56\n'\
'iAfhec4xT0kT6Ibvjc3V098YTMm9GXJy38KTxKzAo8L35Veyc51mZTD3L/G0A1tR\n'\
'ED9Oym8/PPcC+/fzZ999+skaHuig6ZplIJkWVJgctkDD9eVGvSxJFsukUZjSBeNo\n'\
'BXyIceI8NgvLiRk56mNX1TnXGL4gawvjDvnO4yCwfIXecl4ZgeC0ZUGuQvRkobm5\n'\
'1jTBwGPKyO5sMkLiJKU2KrYcPd+GzuPoJl11Xa/zjkyVUo3E/SQ7hSPgPyv7lRJY\n'\
'Lwkp8DDFAgMBAAECggEAfBhAfQE7mUByNbxgAgI5fot9eaqR1Nf+QpJ6X2H3KPwC\n'\
'02sa0HOwieFwYfj6tB1doBoNq7i89mTc+QUlIn4pHgIowHO0OGawomeKz5BEhjCZ\n'\
'4XeLYGSoODary2+kNkf2xY8JTfFEcyvGBpJEwc4S2VyYgRRx+IgnumTSH+N5mIKZ\n'\
'SXWNdZIuHEmkwod+rPRXs6/r+PH0eVW6WfpINEbr4zVAGXJx2zXQwd2cuV1GTJWh\n'\
'cPVOXLu+XJ9im9B370cYN6GqUnR3fui13urYbnWnEf3syvoH/zuZkyrVChauoFf8\n'\
'8EGb74/HhXK7Q2s8NRakx2c7OxQifCbcy03liUMmyQKBgQDFAob5B/66N4Q2cq/N\n'\
'MWPf98kYBYoLaeEOhEJhLQlKk0pIFCTmtpmUbpoEes2kCUbH7RwczpYko8tlKyoB\n'\
'6Fn6RY4zQQ64KZJI6kQVsjkYpcP/ihnOY6rbds+3yyv+4uPX7Eh9sYZwZMggE19M\n'\
'CkFHkwAjiwqhiiSlUxe20sWmowKBgQDEfx4lxuFzA1PBPeZKGVBTxYPQf+DSLCre\n'\
'ZFg3ZmrxbCjRq1O7Lra4FXWD3dmRq7NDk79JofoW50yD8wD7I0B7opdDfXD2idO8\n'\
'0dBnWUKDr2CAXyoLEINce9kJPbx4kFBQRN9PiGF7VkDQxeQ3kfS8CvcErpTKCOdy\n'\
'5wOwBTwJdwKBgDiTFTeGeDv5nVoVbS67tDao7XKchJvqd9q3WGiXikeELJyuTDqE\n'\
'zW22pTwMF+m3UEAxcxVCrhMvhkUzNAkANHaOatuFHzj7lyqhO5QPbh4J3FMR0X9X\n'\
'V8VWRSg+jA/SECP9koOl6zlzd5Tee0tW1pA7QpryXscs6IEhb3ns5R2JAoGAIkzO\n'\
'RmnhEOKTzDex611f2D+yMsMfy5BKK2f4vjLymBH5TiBKDXKqEpgsW0huoi8Gq9Uu\n'\
'nvvXXAgkIyRYF36f0vUe0nkjLuYAQAWgC2pZYgNLJR13iVbol0xHJoXQUHtgiaJ8\n'\
'GLYFzjHQPqFMpSalQe3oELko39uOC1CoJCHFySECgYBeycUnRBikCO2n8DNhY4Eg\n'\
'9Y3oxcssRt6ea5BZwgW2eAYi7/XqKkmxoSoOykUt3MJx9+EkkrL17bxFSpkj1tvL\n'\
'qvxn7egtsKjjgGNAxwXC4MwCvhveyUQQxtQb8AqGrGqo4jEEN0L15cnP38i2x1Uo\n'\
'muhfskWf4MABV0yTUaKcGg==\n'\
'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDhxF/y7bygndxP\n'\
'wiWLSwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQu\n'\
'c32WukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2m\n'\
'KRbQS5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO\n'\
'2fEzYaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnv\n'\
'L6Oz3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdO\n'\
'AoaprFTRAgMBAAECggEAE0HCxV/N1Q1h+1OeDDGL5+74yjKSFKyb/vTVcaPCrmaH\n'\
'fPvp0ddOvMZJ4FDMAsiQS6/n4gQ7EKKEnYmwTqj4eUYW8yxGUn3f0YbPHbZT+Mkj\n'\
'z5woi3nMKi/MxCGDQZX4Ow3xUQlITUqibsfWcFHis8c4mTqdh4qj7xJzehD2PVYF\n'\
'gNHZsvVj6MltjBDAVwV1IlGoHjuElm6vuzkfX7phxcA1B4ZqdYY17yCXUnvui46z\n'\
'Xn2kUTOOUCEgfgvGa9E+l4OtdXi5IxjaSraU+dlg2KsE4TpCuN2MEVkeR5Ms3Y7Q\n'\
'jgJl8vlNFJDQpbFukLcYwG7rO5N5dQ6WWfVia/5XgQKBgQD74at/bXAPrh9NxPmz\n'\
'i1oqCHMDoM9sz8xIMZLF9YVu3Jf8ux4xVpRSnNy5RU1gl7ZXbpdgeIQ4v04zy5aw\n'\
'8T4tu9K3XnR3UXOy25AK0q+cnnxZg3kFQm+PhtOCKEFjPHrgo2MUfnj+EDddod7N\n'\
'JQr9q5rEFbqHupFPpWlqCa3QmQKBgQDldWUGokNaEpmgHDMnHxiibXV5LQhzf8Rq\n'\
'gJIQXb7R9EsTSXEvsDyqTBb7PHp2Ko7rZ5YQfyf8OogGGjGElnPoU/a+Jij1gVFv\n'\
'kZ064uXAAISBkwHdcuobqc5EbG3ceyH46F+FBFhqM8KcbxJxx08objmh58+83InN\n'\
'P9Qr25Xw+QKBgEGXMHuMWgQbSZeM1aFFhoMvlBO7yogBTKb4Ecpu9wI5e3Kan3Al\n'\
'pZYltuyf+VhP6XG3IMBEYdoNJyYhu+nzyEdMg8CwXg+8LC7FMis/Ve+o7aS5scgG\n'\
'1to/N9DK/swCsdTRdzmc/ZDbVC+TuVsebFBGYZTyO5KgqLpezqaIQrTxAoGALFCU\n'\
'10glO9MVyl9H3clap5v+MQ3qcOv/EhaMnw6L2N6WVT481tnxjW4ujgzrFcE4YuxZ\n'\
'hgwYu9TOCmeqopGwBvGYWLbj+C4mfSahOAs0FfXDoYazuIIGBpuv03UhbpB1Si4O\n'\
'rJDfRnuCnVWyOTkl54gKJ2OusinhjztBjcrV1XkCgYEA3qNi4uBsPdyz9BZGb/3G\n'\
'rOMSw0CaT4pEMTLZqURmDP/0hxvTk1polP7O/FYwxVuJnBb6mzDa0xpLFPTpIAnJ\n'\
'YXB8xpXU69QVh+EBbemdJWOd+zp5UCfXvb2shAeG3Tn/Dz4cBBMEUutbzP+or0nG\n'\
'vSXnRLaxQhooWm+IuX9SuBQ=\n'\
'-----END PRIVATE KEY-----\n'
@@ -461,6 +460,9 @@ def test_examples_protocol_advanced_https_ota_example_anti_rollback(env, extra_d
4. Check working of anti_rollback feature
"""
dut1 = env.get_dut('advanced_https_ota_example', 'examples/system/ota/advanced_https_ota', dut_class=ttfw_idf.ESP32DUT, app_config_name='anti_rollback')
Utility.console_log('Erasing the flash on the chip')
# erase the flash
dut1.erase_flash()
server_port = 8001
# Original binary file generated after compilation
bin_name = 'advanced_https_ota.bin'
@@ -523,13 +525,15 @@ def test_examples_protocol_advanced_https_ota_example_partial_request(env, extra
"""
dut1 = env.get_dut('advanced_https_ota_example', 'examples/system/ota/advanced_https_ota', dut_class=ttfw_idf.ESP32DUT, app_config_name='partial_download')
server_port = 8001
# Size of partial HTTP request
request_size = 16384
# File to be downloaded. This file is generated after compilation
bin_name = 'advanced_https_ota.bin'
# check and log bin size
binary_file = os.path.join(dut1.app.binary_path, bin_name)
bin_size = os.path.getsize(binary_file)
ttfw_idf.log_performance('advanced_https_ota_bin_size', '{}KB'.format(bin_size // 1024))
http_requests = int((bin_size / 50000) + 1)
http_requests = int((bin_size / request_size) - 1)
# start test
host_ip = get_my_ip()
if (get_server_status(host_ip, server_port) is False):

View File

@@ -197,7 +197,7 @@ void app_main(void)
*/
ESP_ERROR_CHECK(example_connect());
#if defined(CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE) && defined(CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK)
#if defined(CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE)
/**
* We are treating successful WiFi connection as a checkpoint to cancel rollback
* process and mark newly updated firmware image as active. For production cases,

View File

@@ -5,6 +5,7 @@ CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=3000
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="anti_rollback_partition.csv"
CONFIG_PARTITION_TABLE_FILENAME="anti_rollback_partition.csv"
CONFIG_PARTITION_TABLE_OFFSET=0xd000
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
CONFIG_ESPTOOLPY_FLASHSIZE="16MB"
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y

View File

@@ -3,3 +3,5 @@ CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
CONFIG_EXAMPLE_SKIP_VERSION_CHECK=y
CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=3000
CONFIG_EXAMPLE_ENABLE_PARTIAL_HTTP_DOWNLOAD=y
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y

View File

@@ -1,21 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAP4LF7E72HakMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTkwNjA3MDk1OTE2WhcNMjAwNjA2MDk1OTE2WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAlzfCyv3mIv7TlLkObxunKfCdrJ/zgdANrsx0RBtpEPhV560hWJ0fEin0
nIOMpJSiF9E6QsPdr6Q+eogH4XnOMU9JE+iG743N1dPfGEzJvRlyct/Ck8SswKPC
9+VXsnOdZmUw9y/xtANbURA/TspvPzz3Avv382ffffrJGh7ooOmaZSCZFlSYHLZA
w/XlRr0sSRbLpFGY0gXjaAV8iHHiPDYLy4kZOepjV9U51xi+IGsL4w75zuMgsHyF
3nJeGYHgtGVBrkL0ZKG5udY0wcBjysjubDJC4iSlNiq2HD3fhs7j6CZddV2v845M
lVKNxP0kO4Uj4D8r+5USWC8JKfAwxQIDAQABo1AwTjAdBgNVHQ4EFgQU6OE7ssfY
IIPTDThiUoofUpsD5NwwHwYDVR0jBBgwFoAU6OE7ssfYIIPTDThiUoofUpsD5Nww
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAXIlHS/FJWfmcinUAxyBd
/xd5Lu8ykeru6oaUCci+Vk9lyoMMES7lQ+b/00d5x7AcTawkTil9EWpBTPTOTraA
lzJMQhNKmSLk0iIoTtAJtSZgUSpIIozqK6lenxQQDsHbXKU6h+u9H6KZE8YcjsFl
6vL7sw9BVotw/VxfgjQ5OSGLgoLrdVT0z5C2qOuwOgz1c7jNiJhtMdwN+cOtnJp2
fuBgEYyE3eeuWogvkWoDcIA8r17Ixzkpq2oJsdvZcHZPIZShPKW2SHUsl98KDemu
y0pQyExmQUbwKE4vbFb9XuWCcL9XaOHQytyszt2DeD67AipvoBwVU7/LBOvqnsmy
hA==
MIIDWDCCAkACCQCbF4+gVh/MLjANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJJ
TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD
VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j
b20wHhcNMjEwNzEyMTIzNjI3WhcNNDEwNzA3MTIzNjI3WjBuMQswCQYDVQQGEwJJ
TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD
VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j
b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhxF/y7bygndxPwiWL
SwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQuc32W
ukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2mKRbQ
S5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO2fEz
YaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnvL6Oz
3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdOAoap
rFTRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAItw24y565k3C/zENZlxyzto44ud
IYPQXN8Fa2pBlLe1zlSIyuaA/rWQ+i1daS8nPotkCbWZyf5N8DYaTE4B0OfvoUPk
B5uGDmbuk6akvlB5BGiYLfQjWHRsK9/4xjtIqN1H58yf3QNROuKsPAeywWS3Fn32
3//OpbWaClQePx6udRYMqAitKR+QxL7/BKZQsX+UyShuq8hjphvXvk0BW8ONzuw9
RcoORxM0FzySYjeQvm4LhzC/P3ZBhEq0xs55aL2a76SJhq5hJy7T/Xz6NFByvlrN
lFJJey33KFrAf5vnV9qcyWFIo7PYy2VsaaEjFeefr7q3sTFSMlJeadexW2Y=
-----END CERTIFICATE-----

View File

@@ -12,54 +12,53 @@ import ttfw_idf
from tiny_test_fw import DUT
server_cert = '-----BEGIN CERTIFICATE-----\n' \
'MIIDXTCCAkWgAwIBAgIJAP4LF7E72HakMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV\n'\
'BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n'\
'aWRnaXRzIFB0eSBMdGQwHhcNMTkwNjA3MDk1OTE2WhcNMjAwNjA2MDk1OTE2WjBF\n'\
'MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n'\
'ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n'\
'CgKCAQEAlzfCyv3mIv7TlLkObxunKfCdrJ/zgdANrsx0RBtpEPhV560hWJ0fEin0\n'\
'nIOMpJSiF9E6QsPdr6Q+eogH4XnOMU9JE+iG743N1dPfGEzJvRlyct/Ck8SswKPC\n'\
'9+VXsnOdZmUw9y/xtANbURA/TspvPzz3Avv382ffffrJGh7ooOmaZSCZFlSYHLZA\n'\
'w/XlRr0sSRbLpFGY0gXjaAV8iHHiPDYLy4kZOepjV9U51xi+IGsL4w75zuMgsHyF\n'\
'3nJeGYHgtGVBrkL0ZKG5udY0wcBjysjubDJC4iSlNiq2HD3fhs7j6CZddV2v845M\n'\
'lVKNxP0kO4Uj4D8r+5USWC8JKfAwxQIDAQABo1AwTjAdBgNVHQ4EFgQU6OE7ssfY\n'\
'IIPTDThiUoofUpsD5NwwHwYDVR0jBBgwFoAU6OE7ssfYIIPTDThiUoofUpsD5Nww\n'\
'DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAXIlHS/FJWfmcinUAxyBd\n'\
'/xd5Lu8ykeru6oaUCci+Vk9lyoMMES7lQ+b/00d5x7AcTawkTil9EWpBTPTOTraA\n'\
'lzJMQhNKmSLk0iIoTtAJtSZgUSpIIozqK6lenxQQDsHbXKU6h+u9H6KZE8YcjsFl\n'\
'6vL7sw9BVotw/VxfgjQ5OSGLgoLrdVT0z5C2qOuwOgz1c7jNiJhtMdwN+cOtnJp2\n'\
'fuBgEYyE3eeuWogvkWoDcIA8r17Ixzkpq2oJsdvZcHZPIZShPKW2SHUsl98KDemu\n'\
'y0pQyExmQUbwKE4vbFb9XuWCcL9XaOHQytyszt2DeD67AipvoBwVU7/LBOvqnsmy\n'\
'hA==\n'\
'MIIDWDCCAkACCQCbF4+gVh/MLjANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJJ\n'\
'TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD\n'\
'VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j\n'\
'b20wHhcNMjEwNzEyMTIzNjI3WhcNNDEwNzA3MTIzNjI3WjBuMQswCQYDVQQGEwJJ\n'\
'TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD\n'\
'VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j\n'\
'b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhxF/y7bygndxPwiWL\n'\
'SwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQuc32W\n'\
'ukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2mKRbQ\n'\
'S5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO2fEz\n'\
'YaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnvL6Oz\n'\
'3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdOAoap\n'\
'rFTRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAItw24y565k3C/zENZlxyzto44ud\n'\
'IYPQXN8Fa2pBlLe1zlSIyuaA/rWQ+i1daS8nPotkCbWZyf5N8DYaTE4B0OfvoUPk\n'\
'B5uGDmbuk6akvlB5BGiYLfQjWHRsK9/4xjtIqN1H58yf3QNROuKsPAeywWS3Fn32\n'\
'3//OpbWaClQePx6udRYMqAitKR+QxL7/BKZQsX+UyShuq8hjphvXvk0BW8ONzuw9\n'\
'RcoORxM0FzySYjeQvm4LhzC/P3ZBhEq0xs55aL2a76SJhq5hJy7T/Xz6NFByvlrN\n'\
'lFJJey33KFrAf5vnV9qcyWFIo7PYy2VsaaEjFeefr7q3sTFSMlJeadexW2Y=\n'\
'-----END CERTIFICATE-----\n'
server_key = '-----BEGIN PRIVATE KEY-----\n'\
'MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCXN8LK/eYi/tOU\n'\
'uQ5vG6cp8J2sn/OB0A2uzHREG2kQ+FXnrSFYnR8SKfScg4yklKIX0TpCw92vpD56\n'\
'iAfhec4xT0kT6Ibvjc3V098YTMm9GXJy38KTxKzAo8L35Veyc51mZTD3L/G0A1tR\n'\
'ED9Oym8/PPcC+/fzZ999+skaHuig6ZplIJkWVJgctkDD9eVGvSxJFsukUZjSBeNo\n'\
'BXyIceI8NgvLiRk56mNX1TnXGL4gawvjDvnO4yCwfIXecl4ZgeC0ZUGuQvRkobm5\n'\
'1jTBwGPKyO5sMkLiJKU2KrYcPd+GzuPoJl11Xa/zjkyVUo3E/SQ7hSPgPyv7lRJY\n'\
'Lwkp8DDFAgMBAAECggEAfBhAfQE7mUByNbxgAgI5fot9eaqR1Nf+QpJ6X2H3KPwC\n'\
'02sa0HOwieFwYfj6tB1doBoNq7i89mTc+QUlIn4pHgIowHO0OGawomeKz5BEhjCZ\n'\
'4XeLYGSoODary2+kNkf2xY8JTfFEcyvGBpJEwc4S2VyYgRRx+IgnumTSH+N5mIKZ\n'\
'SXWNdZIuHEmkwod+rPRXs6/r+PH0eVW6WfpINEbr4zVAGXJx2zXQwd2cuV1GTJWh\n'\
'cPVOXLu+XJ9im9B370cYN6GqUnR3fui13urYbnWnEf3syvoH/zuZkyrVChauoFf8\n'\
'8EGb74/HhXK7Q2s8NRakx2c7OxQifCbcy03liUMmyQKBgQDFAob5B/66N4Q2cq/N\n'\
'MWPf98kYBYoLaeEOhEJhLQlKk0pIFCTmtpmUbpoEes2kCUbH7RwczpYko8tlKyoB\n'\
'6Fn6RY4zQQ64KZJI6kQVsjkYpcP/ihnOY6rbds+3yyv+4uPX7Eh9sYZwZMggE19M\n'\
'CkFHkwAjiwqhiiSlUxe20sWmowKBgQDEfx4lxuFzA1PBPeZKGVBTxYPQf+DSLCre\n'\
'ZFg3ZmrxbCjRq1O7Lra4FXWD3dmRq7NDk79JofoW50yD8wD7I0B7opdDfXD2idO8\n'\
'0dBnWUKDr2CAXyoLEINce9kJPbx4kFBQRN9PiGF7VkDQxeQ3kfS8CvcErpTKCOdy\n'\
'5wOwBTwJdwKBgDiTFTeGeDv5nVoVbS67tDao7XKchJvqd9q3WGiXikeELJyuTDqE\n'\
'zW22pTwMF+m3UEAxcxVCrhMvhkUzNAkANHaOatuFHzj7lyqhO5QPbh4J3FMR0X9X\n'\
'V8VWRSg+jA/SECP9koOl6zlzd5Tee0tW1pA7QpryXscs6IEhb3ns5R2JAoGAIkzO\n'\
'RmnhEOKTzDex611f2D+yMsMfy5BKK2f4vjLymBH5TiBKDXKqEpgsW0huoi8Gq9Uu\n'\
'nvvXXAgkIyRYF36f0vUe0nkjLuYAQAWgC2pZYgNLJR13iVbol0xHJoXQUHtgiaJ8\n'\
'GLYFzjHQPqFMpSalQe3oELko39uOC1CoJCHFySECgYBeycUnRBikCO2n8DNhY4Eg\n'\
'9Y3oxcssRt6ea5BZwgW2eAYi7/XqKkmxoSoOykUt3MJx9+EkkrL17bxFSpkj1tvL\n'\
'qvxn7egtsKjjgGNAxwXC4MwCvhveyUQQxtQb8AqGrGqo4jEEN0L15cnP38i2x1Uo\n'\
'muhfskWf4MABV0yTUaKcGg==\n'\
'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDhxF/y7bygndxP\n'\
'wiWLSwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQu\n'\
'c32WukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2m\n'\
'KRbQS5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO\n'\
'2fEzYaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnv\n'\
'L6Oz3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdO\n'\
'AoaprFTRAgMBAAECggEAE0HCxV/N1Q1h+1OeDDGL5+74yjKSFKyb/vTVcaPCrmaH\n'\
'fPvp0ddOvMZJ4FDMAsiQS6/n4gQ7EKKEnYmwTqj4eUYW8yxGUn3f0YbPHbZT+Mkj\n'\
'z5woi3nMKi/MxCGDQZX4Ow3xUQlITUqibsfWcFHis8c4mTqdh4qj7xJzehD2PVYF\n'\
'gNHZsvVj6MltjBDAVwV1IlGoHjuElm6vuzkfX7phxcA1B4ZqdYY17yCXUnvui46z\n'\
'Xn2kUTOOUCEgfgvGa9E+l4OtdXi5IxjaSraU+dlg2KsE4TpCuN2MEVkeR5Ms3Y7Q\n'\
'jgJl8vlNFJDQpbFukLcYwG7rO5N5dQ6WWfVia/5XgQKBgQD74at/bXAPrh9NxPmz\n'\
'i1oqCHMDoM9sz8xIMZLF9YVu3Jf8ux4xVpRSnNy5RU1gl7ZXbpdgeIQ4v04zy5aw\n'\
'8T4tu9K3XnR3UXOy25AK0q+cnnxZg3kFQm+PhtOCKEFjPHrgo2MUfnj+EDddod7N\n'\
'JQr9q5rEFbqHupFPpWlqCa3QmQKBgQDldWUGokNaEpmgHDMnHxiibXV5LQhzf8Rq\n'\
'gJIQXb7R9EsTSXEvsDyqTBb7PHp2Ko7rZ5YQfyf8OogGGjGElnPoU/a+Jij1gVFv\n'\
'kZ064uXAAISBkwHdcuobqc5EbG3ceyH46F+FBFhqM8KcbxJxx08objmh58+83InN\n'\
'P9Qr25Xw+QKBgEGXMHuMWgQbSZeM1aFFhoMvlBO7yogBTKb4Ecpu9wI5e3Kan3Al\n'\
'pZYltuyf+VhP6XG3IMBEYdoNJyYhu+nzyEdMg8CwXg+8LC7FMis/Ve+o7aS5scgG\n'\
'1to/N9DK/swCsdTRdzmc/ZDbVC+TuVsebFBGYZTyO5KgqLpezqaIQrTxAoGALFCU\n'\
'10glO9MVyl9H3clap5v+MQ3qcOv/EhaMnw6L2N6WVT481tnxjW4ujgzrFcE4YuxZ\n'\
'hgwYu9TOCmeqopGwBvGYWLbj+C4mfSahOAs0FfXDoYazuIIGBpuv03UhbpB1Si4O\n'\
'rJDfRnuCnVWyOTkl54gKJ2OusinhjztBjcrV1XkCgYEA3qNi4uBsPdyz9BZGb/3G\n'\
'rOMSw0CaT4pEMTLZqURmDP/0hxvTk1polP7O/FYwxVuJnBb6mzDa0xpLFPTpIAnJ\n'\
'YXB8xpXU69QVh+EBbemdJWOd+zp5UCfXvb2shAeG3Tn/Dz4cBBMEUutbzP+or0nG\n'\
'vSXnRLaxQhooWm+IuX9SuBQ=\n'\
'-----END PRIVATE KEY-----\n'

View File

@@ -1,21 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAP4LF7E72HakMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTkwNjA3MDk1OTE2WhcNMjAwNjA2MDk1OTE2WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAlzfCyv3mIv7TlLkObxunKfCdrJ/zgdANrsx0RBtpEPhV560hWJ0fEin0
nIOMpJSiF9E6QsPdr6Q+eogH4XnOMU9JE+iG743N1dPfGEzJvRlyct/Ck8SswKPC
9+VXsnOdZmUw9y/xtANbURA/TspvPzz3Avv382ffffrJGh7ooOmaZSCZFlSYHLZA
w/XlRr0sSRbLpFGY0gXjaAV8iHHiPDYLy4kZOepjV9U51xi+IGsL4w75zuMgsHyF
3nJeGYHgtGVBrkL0ZKG5udY0wcBjysjubDJC4iSlNiq2HD3fhs7j6CZddV2v845M
lVKNxP0kO4Uj4D8r+5USWC8JKfAwxQIDAQABo1AwTjAdBgNVHQ4EFgQU6OE7ssfY
IIPTDThiUoofUpsD5NwwHwYDVR0jBBgwFoAU6OE7ssfYIIPTDThiUoofUpsD5Nww
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAXIlHS/FJWfmcinUAxyBd
/xd5Lu8ykeru6oaUCci+Vk9lyoMMES7lQ+b/00d5x7AcTawkTil9EWpBTPTOTraA
lzJMQhNKmSLk0iIoTtAJtSZgUSpIIozqK6lenxQQDsHbXKU6h+u9H6KZE8YcjsFl
6vL7sw9BVotw/VxfgjQ5OSGLgoLrdVT0z5C2qOuwOgz1c7jNiJhtMdwN+cOtnJp2
fuBgEYyE3eeuWogvkWoDcIA8r17Ixzkpq2oJsdvZcHZPIZShPKW2SHUsl98KDemu
y0pQyExmQUbwKE4vbFb9XuWCcL9XaOHQytyszt2DeD67AipvoBwVU7/LBOvqnsmy
hA==
MIIDWDCCAkACCQCbF4+gVh/MLjANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJJ
TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD
VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j
b20wHhcNMjEwNzEyMTIzNjI3WhcNNDEwNzA3MTIzNjI3WjBuMQswCQYDVQQGEwJJ
TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD
VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j
b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhxF/y7bygndxPwiWL
SwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQuc32W
ukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2mKRbQ
S5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO2fEz
YaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnvL6Oz
3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdOAoap
rFTRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAItw24y565k3C/zENZlxyzto44ud
IYPQXN8Fa2pBlLe1zlSIyuaA/rWQ+i1daS8nPotkCbWZyf5N8DYaTE4B0OfvoUPk
B5uGDmbuk6akvlB5BGiYLfQjWHRsK9/4xjtIqN1H58yf3QNROuKsPAeywWS3Fn32
3//OpbWaClQePx6udRYMqAitKR+QxL7/BKZQsX+UyShuq8hjphvXvk0BW8ONzuw9
RcoORxM0FzySYjeQvm4LhzC/P3ZBhEq0xs55aL2a76SJhq5hJy7T/Xz6NFByvlrN
lFJJey33KFrAf5vnV9qcyWFIo7PYy2VsaaEjFeefr7q3sTFSMlJeadexW2Y=
-----END CERTIFICATE-----

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