mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(openthread): add openthread start stop APIs
This commit is contained in:
@@ -6,6 +6,28 @@ menu "OpenThread"
|
||||
help
|
||||
Select this option to enable OpenThread and show the submenu with OpenThread configuration choices.
|
||||
|
||||
menu "Thread Task Parameters"
|
||||
depends on OPENTHREAD_ENABLED
|
||||
|
||||
config OPENTHREAD_TASK_NAME
|
||||
string "OpenThread task name"
|
||||
default "ot_main"
|
||||
help
|
||||
The OpenThread task name.
|
||||
|
||||
config OPENTHREAD_TASK_SIZE
|
||||
int "Size of OpenThread task"
|
||||
default 8192
|
||||
help
|
||||
The size in bytes of OpenThread task.
|
||||
|
||||
config OPENTHREAD_TASK_PRIORITY
|
||||
int "Priority of OpenThread task"
|
||||
default 5
|
||||
help
|
||||
The priority of OpenThread task.
|
||||
endmenu
|
||||
|
||||
menu "Thread Version Message"
|
||||
depends on OPENTHREAD_ENABLED
|
||||
|
||||
@@ -23,10 +45,18 @@ menu "OpenThread"
|
||||
endmenu
|
||||
|
||||
menu "Thread Console"
|
||||
depends on OPENTHREAD_ENABLED
|
||||
config OPENTHREAD_CONSOLE_ENABLE
|
||||
bool "Enable OpenThread console"
|
||||
depends on OPENTHREAD_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable the OpenThread-specific console provided by the SDK. This only controls whether
|
||||
the SDK sets up a dedicated console for OpenThread. Even if disabled, the default
|
||||
ESP-IDF console (if initialized elsewhere) can still be used independently.
|
||||
|
||||
choice OPENTHREAD_CONSOLE_TYPE
|
||||
prompt "OpenThread console type"
|
||||
depends on OPENTHREAD_CONSOLE_ENABLE
|
||||
default OPENTHREAD_CONSOLE_TYPE_UART
|
||||
help
|
||||
Select OpenThread console type
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_openthread_types.h"
|
||||
#include "openthread/dataset.h"
|
||||
#include "openthread/error.h"
|
||||
@@ -89,6 +90,29 @@ otInstance *esp_openthread_get_instance(void);
|
||||
*/
|
||||
esp_err_t esp_openthread_mainloop_exit(void);
|
||||
|
||||
/**
|
||||
* @brief Starts the full OpenThread stack and create a handle task.
|
||||
*
|
||||
* @note The OpenThread instance will also be initialized in this function.
|
||||
*
|
||||
* @param[in] config The OpenThread platform configuration.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_STATE if already initialized
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_openthread_start(esp_openthread_platform_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief This function performs OpenThread stack and platform driver deinitialization and delete the handle task.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_STATE if Thread is already active
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_openthread_stop(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // end of extern "C"
|
||||
#endif
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <spinel.h>
|
||||
#include <esp_openthread.h>
|
||||
|
||||
#if CONFIG_OPENTHREAD_NCP_VENDOR_HOOK
|
||||
|
||||
@@ -15,3 +16,13 @@
|
||||
#define SPINEL_PROP_VENDOR_ESP_COEX_EVENT (SPINEL_PROP_VENDOR_ESP__BEGIN + 3)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void otAppNcpInit(otInstance *aInstance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
@@ -4,12 +4,17 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_openthread.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_openthread_border_router.h"
|
||||
#include "esp_openthread_common_macro.h"
|
||||
#include "esp_openthread_cli.h"
|
||||
#include "esp_openthread_dns64.h"
|
||||
#include "esp_openthread_lock.h"
|
||||
#include "esp_openthread_ncp.h"
|
||||
#include "esp_openthread_netif_glue.h"
|
||||
#include "esp_openthread_platform.h"
|
||||
#include "esp_openthread_sleep.h"
|
||||
#include "esp_openthread_state.h"
|
||||
@@ -18,15 +23,19 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "lwip/dns.h"
|
||||
#include "openthread/instance.h"
|
||||
#include "openthread/logging.h"
|
||||
#include "openthread/netdata.h"
|
||||
#include "openthread/tasklet.h"
|
||||
#include "openthread/thread.h"
|
||||
#include <cstddef>
|
||||
|
||||
#if CONFIG_OPENTHREAD_FTD
|
||||
#include "openthread/dataset_ftd.h"
|
||||
#endif
|
||||
|
||||
static bool s_ot_mainloop_running = false;
|
||||
static SemaphoreHandle_t s_ot_syn_semaphore = NULL;
|
||||
static TaskHandle_t s_ot_task_handle = NULL;
|
||||
|
||||
static int hex_digit_to_int(char hex)
|
||||
{
|
||||
@@ -223,3 +232,81 @@ esp_err_t esp_openthread_deinit(void)
|
||||
otInstanceFinalize(esp_openthread_get_instance());
|
||||
return esp_openthread_platform_deinit();
|
||||
}
|
||||
|
||||
static void ot_task_worker(void *aContext)
|
||||
{
|
||||
esp_openthread_platform_config_t* config = (esp_openthread_platform_config_t *)aContext;
|
||||
// Initialize the OpenThread stack
|
||||
ESP_ERROR_CHECK(esp_openthread_init(config));
|
||||
|
||||
#if CONFIG_OPENTHREAD_FTD || CONFIG_OPENTHREAD_MTD
|
||||
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_OPENTHREAD();
|
||||
esp_netif_t *openthread_netif = esp_netif_new(&cfg);
|
||||
assert(openthread_netif != NULL);
|
||||
ESP_ERROR_CHECK(esp_netif_attach(openthread_netif, esp_openthread_netif_glue_init(config)));
|
||||
#endif
|
||||
|
||||
#if CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC
|
||||
// The OpenThread log level directly matches ESP log level
|
||||
(void)otLoggingSetLevel(CONFIG_LOG_DEFAULT_LEVEL);
|
||||
#endif // CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC
|
||||
|
||||
#if CONFIG_OPENTHREAD_CLI
|
||||
esp_openthread_cli_init();
|
||||
esp_openthread_cli_console_command_register();
|
||||
#endif // CONFIG_OPENTHREAD_CLI
|
||||
|
||||
xSemaphoreGive(s_ot_syn_semaphore);
|
||||
#if CONFIG_OPENTHREAD_RADIO
|
||||
otAppNcpInit(esp_openthread_get_instance());
|
||||
#endif
|
||||
|
||||
// Run the main loop
|
||||
esp_openthread_launch_mainloop();
|
||||
|
||||
#if CONFIG_OPENTHREAD_RADIO
|
||||
ESP_LOGE(OT_PLAT_LOG_TAG, "RCP deinitialization is not supported for now");
|
||||
assert(false);
|
||||
#endif
|
||||
#if CONFIG_OPENTHREAD_CLI
|
||||
esp_openthread_cli_console_command_unregister();
|
||||
#endif // CONFIG_OPENTHREAD_CLI
|
||||
|
||||
#if CONFIG_OPENTHREAD_FTD || CONFIG_OPENTHREAD_MTD
|
||||
// Clean up
|
||||
esp_openthread_netif_glue_deinit();
|
||||
esp_netif_destroy(openthread_netif);
|
||||
#endif
|
||||
|
||||
ESP_ERROR_CHECK(esp_openthread_deinit());
|
||||
|
||||
xSemaphoreGive(s_ot_syn_semaphore);
|
||||
vTaskDelay(portMAX_DELAY);
|
||||
}
|
||||
|
||||
esp_err_t esp_openthread_start(esp_openthread_platform_config_t *config)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(s_ot_syn_semaphore == NULL, ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, "OpenThread has been initialized");
|
||||
s_ot_syn_semaphore = xSemaphoreCreateBinary();
|
||||
ESP_RETURN_ON_FALSE(s_ot_syn_semaphore != NULL, ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, "Failed to create s_ot_syn_semaphore");
|
||||
assert(xTaskCreate(ot_task_worker, CONFIG_OPENTHREAD_TASK_NAME, CONFIG_OPENTHREAD_TASK_SIZE, config, CONFIG_OPENTHREAD_TASK_PRIORITY, &s_ot_task_handle) == pdPASS);
|
||||
xSemaphoreTake(s_ot_syn_semaphore, portMAX_DELAY);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_openthread_stop(void)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(s_ot_syn_semaphore != NULL, ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, "OpenThread is not initialized");
|
||||
esp_openthread_lock_acquire(portMAX_DELAY);
|
||||
otInstance *instance = esp_openthread_get_instance();
|
||||
bool is_thread_not_active = (otThreadGetDeviceRole(instance) == OT_DEVICE_ROLE_DISABLED && otIp6IsEnabled(instance) == false);
|
||||
esp_openthread_lock_release();
|
||||
ESP_RETURN_ON_FALSE(is_thread_not_active, ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, "Thread interface is still active");
|
||||
esp_openthread_mainloop_exit();
|
||||
xSemaphoreTake(s_ot_syn_semaphore, portMAX_DELAY);
|
||||
vTaskDelete(s_ot_task_handle);
|
||||
vSemaphoreDelete(s_ot_syn_semaphore);
|
||||
s_ot_task_handle = NULL;
|
||||
s_ot_syn_semaphore = NULL;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user