mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-15 22:44:19 +00:00
Merge branch 'feature/esp32c6_light_sleep_support_ieee802154' into 'master'
ieee802154: esp32c6 light sleep support See merge request espressif/esp-idf!23629
This commit is contained in:
@@ -49,3 +49,12 @@ examples/openthread/ot_rcp:
|
||||
temporary: true
|
||||
reason: only test on esp32c6
|
||||
<<: *openthread_dependencies
|
||||
|
||||
examples/openthread/ot_sleepy_device:
|
||||
enable:
|
||||
- if: IDF_TARGET == "esp32c6"
|
||||
disable_test:
|
||||
- if: IDF_TARGET in ["esp32h2", "esp32c6"]
|
||||
temporary: true
|
||||
reason: No support # TO-DO: TZ-134
|
||||
<<: *openthread_dependencies
|
||||
|
@@ -11,3 +11,5 @@ In this folder, it contains following OpenThread examples:
|
||||
* [ot_rcp](ot_rcp) is an [OpenThread RCP](https://openthread.io/platforms/co-processor) example. It runs on an 802.15.4 SoC like ESP32-H2, to extend 802.15.4 radio.
|
||||
|
||||
* [ot_br](ot_br) is an [OpenThread Border Router](https://openthread.io/guides/border-router) example. It runs on a Wi-Fi SoC such as ESP32, ESP32-C3 and ESP32-S3. It needs an 802.15.4 SoC like ESP32-H2 running [ot_rcp](ot_rcp) example to provide 802.15.4 radio.
|
||||
|
||||
* [ot_sleepy_device](ot_sleepy_device) is an OpenThread sleepy device example, it supports 802.15.4 radio light sleep. It runs on an 802.15.4 SoC.
|
||||
|
6
examples/openthread/ot_sleepy_device/CMakeLists.txt
Normal file
6
examples/openthread/ot_sleepy_device/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(ot_sleepy_device)
|
40
examples/openthread/ot_sleepy_device/README.md
Normal file
40
examples/openthread/ot_sleepy_device/README.md
Normal file
@@ -0,0 +1,40 @@
|
||||
| Supported Targets | ESP32-C6 |
|
||||
| ----------------- | -------- |
|
||||
|
||||
# OpenThread Sleepy Device Example
|
||||
|
||||
The example demonstrates the Thread Sleepy End Device (SED), the device will enter [Light Sleep mode](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/api-reference/system/sleep_modes.html#sleep-modes) during idle state.
|
||||
## How to use example
|
||||
|
||||
### Hardware Required
|
||||
|
||||
* Prepare an 802.15.4 SoC development board as an OpenThread Sleepy End Device (SED).
|
||||
* Connect the board using a USB cable for power supply and programming.
|
||||
* Choose another 802.15.4 SoC as the OpenThread Leader.
|
||||
|
||||
## Configure the Openthread Dataset
|
||||
|
||||
* Run [ot_cli](../ot_cli/) on another 802.15.4 SoC device to create openthread dataset configuration and start an openthread network as the leader.
|
||||
* Configure the Openthread dataset using `idf.py menuconfig` in `Component config ---> Openthread ---> Thread Operation Dataset`, ensuring that the openthread sleepy device's dataset matches the dataset of the leader.
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Build the project and flash it to the board. Use the following command: `idf.py -p <PORT> erase-flash flash monitor`.
|
||||
|
||||
### Example Output
|
||||
|
||||
As the example runs, you will see the log output indicating the initialization and operation of OpenThread, including the device joining the OpenThread network as a Sleepy End Device (SED) and periodic polling of the leader.
|
||||
|
||||
```
|
||||
I (769) btbb_init: btbb sleep retention initialization
|
||||
I (769) ieee802154: ieee802154 mac sleep retention initialization
|
||||
I(769) OPENTHREAD:[I] ChildSupervsn-: Timeout: 0 -> 190
|
||||
I (699) main_task: Returned from app_main()
|
||||
I (799) OPENTHREAD: OpenThread attached to netif
|
||||
I(799) OPENTHREAD:[N] Mle-----------: Mode 0x0f -> 0x04 [rx-on:no ftd:no full-net:no]
|
||||
I(809) OPENTHREAD:[N] Mle-----------: Role disabled -> detached
|
||||
I (819) OPENTHREAD: netif up
|
||||
I(1519) OPENTHREAD:[N] Mle-----------: Attach attempt 1, AnyPartition reattaching with Active Dataset
|
||||
I(2479) OPENTHREAD:[N] Mle-----------: RLOC16 fffe -> 5023
|
||||
I(2529) OPENTHREAD:[N] Mle-----------: Role detached -> child
|
||||
```
|
2
examples/openthread/ot_sleepy_device/main/CMakeLists.txt
Normal file
2
examples/openthread/ot_sleepy_device/main/CMakeLists.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "esp_ot_sleepy_device.c"
|
||||
INCLUDE_DIRS ".")
|
140
examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c
Normal file
140
examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* OpenThread Command Line 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 <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_openthread.h"
|
||||
#include "esp_openthread_netif_glue.h"
|
||||
#include "esp_ot_sleepy_device_config.h"
|
||||
#include "esp_vfs_eventfd.h"
|
||||
#include "driver/uart.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "openthread/logging.h"
|
||||
#include "openthread/thread.h"
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
#include "esp_pm.h"
|
||||
#endif
|
||||
|
||||
#if !SOC_IEEE802154_SUPPORTED
|
||||
#error "Openthread sleepy device is only supported for the SoCs which have IEEE 802.15.4 module"
|
||||
#endif
|
||||
|
||||
#define TAG "ot_esp_power_save"
|
||||
|
||||
static void create_config_network(otInstance *instance)
|
||||
{
|
||||
otLinkModeConfig linkMode = { 0 };
|
||||
|
||||
linkMode.mRxOnWhenIdle = false;
|
||||
linkMode.mDeviceType = false;
|
||||
linkMode.mNetworkData = false;
|
||||
|
||||
if (otLinkSetPollPeriod(instance, CONFIG_OPENTHREAD_NETWORK_POLLPERIOD_TIME) != OT_ERROR_NONE) {
|
||||
ESP_LOGE(TAG, "Failed to set OpenThread pollperiod.");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (otThreadSetLinkMode(instance, linkMode) != OT_ERROR_NONE) {
|
||||
ESP_LOGE(TAG, "Failed to set OpenThread linkmode.");
|
||||
abort();
|
||||
}
|
||||
ESP_ERROR_CHECK(esp_openthread_auto_start(NULL));
|
||||
}
|
||||
|
||||
static esp_netif_t *init_openthread_netif(const esp_openthread_platform_config_t *config)
|
||||
{
|
||||
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_OPENTHREAD();
|
||||
esp_netif_t *netif = esp_netif_new(&cfg);
|
||||
assert(netif != NULL);
|
||||
ESP_ERROR_CHECK(esp_netif_attach(netif, esp_openthread_netif_glue_init(config)));
|
||||
|
||||
return netif;
|
||||
}
|
||||
|
||||
static void ot_task_worker(void *aContext)
|
||||
{
|
||||
esp_openthread_platform_config_t config = {
|
||||
.radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(),
|
||||
.host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(),
|
||||
.port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(),
|
||||
};
|
||||
|
||||
// Initialize the OpenThread stack
|
||||
ESP_ERROR_CHECK(esp_openthread_init(&config));
|
||||
|
||||
#if CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC
|
||||
// The OpenThread log level directly matches ESP log level
|
||||
(void)otLoggingSetLevel(CONFIG_LOG_DEFAULT_LEVEL);
|
||||
#endif
|
||||
esp_netif_t *openthread_netif;
|
||||
// Initialize the esp_netif bindings
|
||||
openthread_netif = init_openthread_netif(&config);
|
||||
esp_netif_set_default_netif(openthread_netif);
|
||||
|
||||
create_config_network(esp_openthread_get_instance());
|
||||
|
||||
// Run the main loop
|
||||
esp_openthread_launch_mainloop();
|
||||
|
||||
// Clean up
|
||||
esp_netif_destroy(openthread_netif);
|
||||
esp_openthread_netif_glue_deinit();
|
||||
|
||||
esp_vfs_eventfd_unregister();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static esp_err_t ot_power_save_init(void)
|
||||
{
|
||||
esp_err_t rc = ESP_OK;
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
int cur_cpu_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ;
|
||||
|
||||
esp_pm_config_t pm_config = {
|
||||
.max_freq_mhz = cur_cpu_freq_mhz,
|
||||
.min_freq_mhz = cur_cpu_freq_mhz,
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
.light_sleep_enable = true
|
||||
#endif
|
||||
};
|
||||
|
||||
rc = esp_pm_configure(&pm_config);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Used eventfds:
|
||||
// * netif
|
||||
// * ot task queue
|
||||
// * radio driver
|
||||
esp_vfs_eventfd_config_t eventfd_config = {
|
||||
.max_fds = 3,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_vfs_eventfd_register(&eventfd_config));
|
||||
ESP_ERROR_CHECK(ot_power_save_init());
|
||||
|
||||
xTaskCreate(ot_task_worker, "ot_power_save_main", 4096, NULL, 5, NULL);
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* OpenThread Command Line 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_openthread_types.h"
|
||||
|
||||
# define CONFIG_OPENTHREAD_NETWORK_POLLPERIOD_TIME 3000
|
||||
|
||||
#if SOC_IEEE802154_SUPPORTED
|
||||
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
|
||||
{ \
|
||||
.radio_mode = RADIO_MODE_NATIVE, \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \
|
||||
{ \
|
||||
.host_connection_mode = HOST_CONNECTION_MODE_CLI_UART, \
|
||||
.host_uart_config = { \
|
||||
.port = 0, \
|
||||
.uart_config = \
|
||||
{ \
|
||||
.baud_rate = 115200, \
|
||||
.data_bits = UART_DATA_8_BITS, \
|
||||
.parity = UART_PARITY_DISABLE, \
|
||||
.stop_bits = UART_STOP_BITS_1, \
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE, \
|
||||
.rx_flow_ctrl_thresh = 0, \
|
||||
.source_clk = UART_SCLK_DEFAULT, \
|
||||
}, \
|
||||
.rx_pin = UART_PIN_NO_CHANGE, \
|
||||
.tx_pin = UART_PIN_NO_CHANGE, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \
|
||||
{ \
|
||||
.storage_partition_name = "nvs", \
|
||||
.netif_queue_size = 10, \
|
||||
.task_queue_size = 10, \
|
||||
}
|
5
examples/openthread/ot_sleepy_device/partitions.csv
Normal file
5
examples/openthread/ot_sleepy_device/partitions.csv
Normal file
@@ -0,0 +1,5 @@
|
||||
# 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, 0x120000,
|
|
51
examples/openthread/ot_sleepy_device/sdkconfig.defaults
Normal file
51
examples/openthread/ot_sleepy_device/sdkconfig.defaults
Normal file
@@ -0,0 +1,51 @@
|
||||
#
|
||||
# Partition Table
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||
# end of Partition Table
|
||||
|
||||
#
|
||||
# mbedTLS
|
||||
#
|
||||
# TODO: Re-enable HW acceleration when HW AES support pm_lock (IDF-7704)
|
||||
CONFIG_MBEDTLS_HARDWARE_AES=n
|
||||
CONFIG_MBEDTLS_HARDWARE_MPI=n
|
||||
CONFIG_MBEDTLS_HARDWARE_SHA=n
|
||||
CONFIG_MBEDTLS_CMAC_C=y
|
||||
CONFIG_MBEDTLS_SSL_PROTO_DTLS=y
|
||||
CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y
|
||||
CONFIG_MBEDTLS_ECJPAKE_C=y
|
||||
# end of mbedTLS
|
||||
|
||||
#
|
||||
# OpenThread
|
||||
#
|
||||
CONFIG_OPENTHREAD_ENABLED=y
|
||||
CONFIG_OPENTHREAD_BORDER_ROUTER=n
|
||||
CONFIG_OPENTHREAD_DNS64_CLIENT=y
|
||||
# end of OpenThread
|
||||
|
||||
#
|
||||
# lwIP
|
||||
#
|
||||
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096
|
||||
CONFIG_LWIP_IPV6_NUM_ADDRESSES=8
|
||||
CONFIG_LWIP_MULTICAST_PING=y
|
||||
# end of lwIP
|
||||
|
||||
#
|
||||
# IEEE 802.15.4
|
||||
#
|
||||
CONFIG_IEEE802154_ENABLED=y
|
||||
# end of IEEE 802.15.4
|
||||
|
||||
#
|
||||
# light sleep
|
||||
#
|
||||
CONFIG_PM_ENABLE=y
|
||||
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
|
||||
CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y
|
||||
CONFIG_IEEE802154_SLEEP_ENABLE=y
|
||||
# end of light sleep
|
Reference in New Issue
Block a user