From 2db6f3cddacb48d2b8b15e4192d77672b0a9246b Mon Sep 17 00:00:00 2001 From: Tan Yan Quan Date: Tue, 27 Jan 2026 15:35:53 +0800 Subject: [PATCH 1/3] feat(openthread): use explicit source list for RCP build --- components/openthread/CMakeLists.txt | 278 +++--------------- components/openthread/linker.lf | 2 +- .../src/esp_openthread_platform.cpp | 18 +- components/openthread/srcs_ftd_mtd.cmake | 114 +++++++ components/openthread/srcs_radio.cmake | 97 ++++++ components/openthread/srcs_spinel.cmake | 45 +++ 6 files changed, 314 insertions(+), 240 deletions(-) create mode 100644 components/openthread/srcs_ftd_mtd.cmake create mode 100644 components/openthread/srcs_radio.cmake create mode 100644 components/openthread/srcs_spinel.cmake diff --git a/components/openthread/CMakeLists.txt b/components/openthread/CMakeLists.txt index 34ef874c735..5d5d0694a4d 100644 --- a/components/openthread/CMakeLists.txt +++ b/components/openthread/CMakeLists.txt @@ -5,14 +5,12 @@ if(${idf_target} STREQUAL "linux") endif() if(CONFIG_OPENTHREAD_ENABLED OR CONFIG_IDF_DOC_BUILD OR CONFIG_OPENTHREAD_SPINEL_ONLY) - set(public_include_dirs "include" "openthread/include") endif() if(CONFIG_OPENTHREAD_ENABLED) - set(private_include_dirs "openthread/examples/platforms" "openthread/src" @@ -24,239 +22,18 @@ if(CONFIG_OPENTHREAD_ENABLED) "openthread/src/ncp" "private_include") - set(src_dirs - "src" - "src/port" - "openthread/examples/platforms/utils" - "openthread/src/core/api" - "openthread/src/core/common" - "openthread/src/core/crypto" - "openthread/src/core/diags" - "openthread/src/core/instance" - "openthread/src/core/mac" - "openthread/src/core/radio" - "openthread/src/core/thread" - "openthread/src/core/utils" - "openthread/src/lib/hdlc" - "openthread/src/lib/spinel") - - set(exclude_srcs - "openthread/examples/platforms/utils/logging_rtt.c" - "openthread/examples/platforms/utils/soft_source_match_table.c" - "openthread/src/core/instance/extension_example.cpp") - - if(CONFIG_OPENTHREAD_FTD OR CONFIG_OPENTHREAD_MTD) - list(APPEND src_dirs - "openthread/src/core/backbone_router" - "openthread/src/core/coap" - "openthread/src/core/meshcop" - "openthread/src/core/net" - "openthread/src/lib/platform") - - if(CONFIG_OPENTHREAD_CLI) - list(APPEND src_dirs - "openthread/examples/apps/cli" - "openthread/src/cli") - - list(APPEND exclude_srcs - "openthread/examples/apps/cli/main.c") - endif() - - elseif(CONFIG_OPENTHREAD_RADIO) - list(APPEND src_dirs - "openthread/src/ncp" - "openthread/examples/apps/ncp") - - list(APPEND exclude_srcs - "src/port/esp_openthread_state.c" - "openthread/examples/apps/ncp/main.c" - "openthread/src/core/api/backbone_router_api.cpp" - "openthread/src/core/api/child_supervision_api.cpp" - "openthread/src/core/api/dataset_api.cpp" - "openthread/src/core/api/dns_api.cpp" - "openthread/src/core/api/entropy_api.cpp" - "openthread/src/core/api/heap_api.cpp" - "openthread/src/core/api/icmp6_api.cpp" - "openthread/src/core/api/ip6_api.cpp" - "openthread/src/core/api/link_api.cpp" - "openthread/src/core/api/link_metrics_api.cpp" - "openthread/src/core/api/message_api.cpp" - "openthread/src/core/api/nat64_api.cpp" - "openthread/src/core/api/netdata_api.cpp" - "openthread/src/core/api/netdiag_api.cpp" - "openthread/src/core/api/network_time_api.cpp" - "openthread/src/core/api/random_crypto_api.cpp" - "openthread/src/core/api/tcp_api.cpp" - "openthread/src/core/api/udp_api.cpp" - "openthread/src/core/common/heap.cpp" - "openthread/src/core/common/heap_string.cpp" - "openthread/src/core/common/notifier.cpp" - "openthread/src/core/common/settings.cpp" - "openthread/src/core/common/time_ticker.cpp" - "openthread/src/core/mac/channel_mask.cpp" - "openthread/src/core/mac/data_poll_handler.cpp" - "openthread/src/core/mac/data_poll_sender.cpp" - "openthread/src/core/mac/mac.cpp" - "openthread/src/core/mac/mac_filter.cpp" - "openthread/src/core/mac/mac_links.cpp" - "openthread/src/core/thread/announce_begin_server.cpp" - "openthread/src/core/thread/announce_sender.cpp" - "openthread/src/core/thread/address_resolver.cpp" - "openthread/src/core/thread/child.cpp" - "openthread/src/core/thread/child_supervision.cpp" - "openthread/src/core/thread/csl_tx_scheduler.cpp" - "openthread/src/core/thread/discover_scanner.cpp" - "openthread/src/core/thread/energy_scan_server.cpp" - "openthread/src/core/thread/indirect_sender.cpp" - "openthread/src/core/thread/key_manager.cpp" - "openthread/src/core/thread/link_metrics.cpp" - "openthread/src/core/thread/lowpan.cpp" - "openthread/src/core/thread/mesh_forwarder.cpp" - "openthread/src/core/thread/mesh_forwarder_ftd.cpp" - "openthread/src/core/thread/mesh_forwarder_mtd.cpp" - "openthread/src/core/thread/message_framer.cpp" - "openthread/src/core/thread/mle.cpp" - "openthread/src/core/thread/mle_ftd.cpp" - "openthread/src/core/thread/mle_p2p.cpp" - "openthread/src/core/thread/mle_router.cpp" - "openthread/src/core/thread/mle_types.cpp" - "openthread/src/core/thread/neighbor.cpp" - "openthread/src/core/thread/neighbor_table.cpp" - "openthread/src/core/thread/network_data.cpp" - "openthread/src/core/thread/network_data_leader.cpp" - "openthread/src/core/thread/network_data_leader_ftd.cpp" - "openthread/src/core/thread/network_data_types.cpp" - "openthread/src/core/thread/network_data_service.cpp" - "openthread/src/core/thread/network_diagnostic.cpp" - "openthread/src/core/thread/network_diagnostic_tlvs.cpp" - "openthread/src/core/thread/panid_query_server.cpp" - "openthread/src/core/thread/router.cpp" - "openthread/src/core/thread/thread_netif.cpp" - "openthread/src/core/thread/time_sync_service.cpp" - "openthread/src/core/thread/tmf.cpp" - "openthread/src/core/thread/topology.cpp" - "openthread/src/core/utils/child_supervision.cpp") - endif() - - if(CONFIG_OPENTHREAD_RADIO_NATIVE) - list(APPEND exclude_srcs - "src/port/esp_openthread_radio_spinel.cpp" - "src/port/esp_spi_spinel_interface.cpp" - "src/port/esp_uart_spinel_interface.cpp" - ) - elseif(CONFIG_OPENTHREAD_RADIO_SPINEL_UART OR CONFIG_OPENTHREAD_RADIO_SPINEL_SPI) - list(APPEND exclude_srcs - "src/port/esp_openthread_radio.c" - "src/port/esp_openthread_sleep.c") - elseif(CONFIG_OPENTHREAD_RADIO_154_NONE) - list(APPEND exclude_srcs - "src/port/esp_openthread_radio_spinel.cpp" - "src/port/esp_spi_spinel_interface.cpp" - "src/port/esp_uart_spinel_interface.cpp" - "src/port/esp_openthread_radio.c" - "src/port/esp_openthread_sleep.c" - ) - endif() - - if(NOT CONFIG_OPENTHREAD_RADIO_TREL) - list(APPEND exclude_srcs - "src/port/esp_openthread_trel.c") - endif() - - if(CONFIG_OPENTHREAD_BORDER_ROUTER) - list(APPEND src_dirs - "openthread/src/core/border_router") - endif() - - if(CONFIG_OPENTHREAD_FTD) - set_source_files_properties("openthread/src/core/net/srp_server.cpp" - PROPERTIES COMPILE_FLAGS - -Wno-maybe-uninitialized) - endif() - - if(CONFIG_OPENTHREAD_NCP_VENDOR_HOOK) - list(APPEND src_dirs - "src/ncp") - if(CONFIG_OPENTHREAD_RCP_UART OR CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG) - list(APPEND exclude_srcs - "src/ncp/esp_openthread_ncp_spi.cpp") - elseif(CONFIG_OPENTHREAD_RCP_SPI) - list(APPEND exclude_srcs - "src/ncp/esp_openthread_ncp_hdlc.cpp") - endif() - endif() - - if(NOT CONFIG_OPENTHREAD_DNS64_CLIENT) - list(APPEND exclude_srcs - "src/esp_openthread_dns64.c") - endif() - - if(NOT CONFIG_FREERTOS_USE_TICKLESS_IDLE) - list(APPEND exclude_srcs - "src/port/esp_openthread_sleep.c") - endif() - - if(NOT CONFIG_OPENTHREAD_PLATFORM_MSGPOOL_MANAGEMENT) - list(APPEND exclude_srcs - "src/port/esp_openthread_messagepool.c") - endif() - - if(NOT CONFIG_OPENTHREAD_RCP_SPINEL_CONSOLE) - list(APPEND exclude_srcs - "src/ncp/esp_openthread_ncp_console.cpp") - endif() - if(CONFIG_OPENTHREAD_FTD) + include(srcs_ftd_mtd.cmake) set(device_type "OPENTHREAD_FTD=1") elseif(CONFIG_OPENTHREAD_MTD) + include(srcs_ftd_mtd.cmake) set(device_type "OPENTHREAD_MTD=1") elseif(CONFIG_OPENTHREAD_RADIO) + include(srcs_radio.cmake) set(device_type "OPENTHREAD_RADIO=1") endif() elseif(CONFIG_OPENTHREAD_SPINEL_ONLY) - - set(src_dirs - "src/spinel" - "src/port" - "openthread/src/lib/spinel" - "openthread/src/lib/hdlc" - "openthread/src/lib/platform" - "openthread/src/core/api" - "openthread/src/core/common" - "openthread/src/core/mac") - - set(private_include_dirs - "private_include" - "openthread/src" - "openthread/src/core" - "openthread/src/include" - "openthread/src/lib" - "openthread/src/lib/hdlc" - "openthread/src/lib/spinel") - - file(GLOB_RECURSE exclude_srcs_list - "src/port/*" - "openthread/src/core/api/*.cpp" - "openthread/src/core/common/*" - "openthread/src/core/mac/*") - - list(REMOVE_ITEM exclude_srcs_list - "${CMAKE_CURRENT_SOURCE_DIR}/src/port/esp_openthread_alarm.c" - "${CMAKE_CURRENT_SOURCE_DIR}/src/port/esp_openthread_logging.c" - "${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/api/error_api.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/api/logging_api.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/common/error.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/common/error.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/common/log.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/common/log.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/common/logging.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/common/string.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/common/string.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/mac/mac_frame.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/openthread/src/core/mac/mac_frame.hpp") - - list(APPEND exclude_srcs ${exclude_srcs_list}) - + include(srcs_spinel.cmake) endif() if(CONFIG_OPENTHREAD_HEADER_CUSTOM) @@ -283,14 +60,45 @@ string(CONCAT OT_FULL_VERSION_STRING "${IDF_VERSION_FOR_OPENTHREAD_PACKAGE}-${OPENTHREAD_VERSION}\; " "${CONFIG_OPENTHREAD_PLATFORM_INFO}\; ${OT_BUILD_TIMESTAMP}") -idf_component_register(SRC_DIRS "${src_dirs}" - EXCLUDE_SRCS "${exclude_srcs}" - INCLUDE_DIRS "${public_include_dirs}" - PRIV_INCLUDE_DIRS "${private_include_dirs}" - REQUIRES esp_netif lwip esp_driver_uart driver - LDFRAGMENTS linker.lf - PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer - ieee802154 mbedtls nvs_flash) +# Register component based on mode +if(CONFIG_OPENTHREAD_FTD OR CONFIG_OPENTHREAD_MTD) + # FTD/MTD modes use directory-based collection from srcs_ftd_mtd.cmake + idf_component_register(SRC_DIRS "${src_dirs}" + EXCLUDE_SRCS "${exclude_srcs}" + INCLUDE_DIRS "${public_include_dirs}" + PRIV_INCLUDE_DIRS "${private_include_dirs}" + REQUIRES esp_netif lwip esp_driver_uart driver + LDFRAGMENTS linker.lf + PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer + ieee802154 mbedtls nvs_flash) +elseif(CONFIG_OPENTHREAD_RADIO) + # RCP mode uses explicit source list from srcs_radio.cmake + idf_component_register(SRCS ${rcp_srcs} + INCLUDE_DIRS "${public_include_dirs}" + PRIV_INCLUDE_DIRS "${private_include_dirs}" + REQUIRES esp_netif lwip esp_driver_uart driver + LDFRAGMENTS linker.lf + PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer + ieee802154 mbedtls nvs_flash) +elseif(CONFIG_OPENTHREAD_SPINEL_ONLY) + # SPINEL_ONLY mode uses explicit source list from srcs_spinel.cmake + idf_component_register(SRCS ${spinel_srcs} + INCLUDE_DIRS "${public_include_dirs}" + PRIV_INCLUDE_DIRS "${private_include_dirs}" + REQUIRES esp_netif lwip esp_driver_uart driver + LDFRAGMENTS linker.lf + PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer + ieee802154 mbedtls nvs_flash) +else() + # This is not supposed to happen, but in older versions of IDF components couldn't be selectively + # enabled based on KConfig options so some examples just included openthread for all configs. + idf_component_register(INCLUDE_DIRS "${public_include_dirs}" + PRIV_INCLUDE_DIRS "${private_include_dirs}" + REQUIRES esp_netif lwip esp_driver_uart driver + LDFRAGMENTS linker.lf + PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer + ieee802154 mbedtls nvs_flash) +endif() if(CONFIG_OPENTHREAD_RADIO_TREL) idf_component_optional_requires(PRIVATE espressif__mdns) diff --git a/components/openthread/linker.lf b/components/openthread/linker.lf index 58c830c8e7a..4be6622a080 100644 --- a/components/openthread/linker.lf +++ b/components/openthread/linker.lf @@ -2,13 +2,13 @@ archive: libopenthread.a entries: if OPENTHREAD_TIMING_OPTIMIZATION = y: - link_metrics (noflash) link_quality (noflash) mac_frame (noflash) radio (noflash) sub_mac (noflash) if OPENTHREAD_TIMING_OPTIMIZATION = y && OPENTHREAD_RADIO = n: + link_metrics (noflash) mesh_forwarder (noflash) csl_tx_scheduler (noflash) mac (noflash) diff --git a/components/openthread/src/esp_openthread_platform.cpp b/components/openthread/src/esp_openthread_platform.cpp index f16891d69c2..82185a1ec6f 100644 --- a/components/openthread/src/esp_openthread_platform.cpp +++ b/components/openthread/src/esp_openthread_platform.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -179,11 +179,21 @@ esp_err_t esp_openthread_platform_deinit(void) esp_openthread_task_queue_deinit(); esp_openthread_radio_deinit(); - if (get_host_connection_mode() == HOST_CONNECTION_MODE_RCP_SPI){ + esp_openthread_host_connection_mode_t host_mode = get_host_connection_mode(); + switch (host_mode) { +#if CONFIG_OPENTHREAD_RCP_SPI + case HOST_CONNECTION_MODE_RCP_SPI: esp_openthread_spi_slave_deinit(); - } else if (get_host_connection_mode() == HOST_CONNECTION_MODE_CLI_UART || - get_host_connection_mode() == HOST_CONNECTION_MODE_RCP_UART) { + break; +#endif +#if CONFIG_OPENTHREAD_RCP_UART || CONFIG_OPENTHREAD_CONSOLE_TYPE_UART + case HOST_CONNECTION_MODE_RCP_UART: + case HOST_CONNECTION_MODE_CLI_UART: esp_openthread_uart_deinit(); + break; +#endif + default: + break; } esp_openthread_lock_deinit(); diff --git a/components/openthread/srcs_ftd_mtd.cmake b/components/openthread/srcs_ftd_mtd.cmake new file mode 100644 index 00000000000..bcfe5fe842d --- /dev/null +++ b/components/openthread/srcs_ftd_mtd.cmake @@ -0,0 +1,114 @@ +# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +# Source files for FTD (Full Thread Device) and MTD (Minimal Thread Device) modes. +# Uses directory-based collection with exclusions. + +set(src_dirs + "src" + "src/port" + "openthread/examples/platforms/utils" + "openthread/src/core/api" + "openthread/src/core/common" + "openthread/src/core/crypto" + "openthread/src/core/diags" + "openthread/src/core/instance" + "openthread/src/core/mac" + "openthread/src/core/radio" + "openthread/src/core/thread" + "openthread/src/core/utils" + "openthread/src/lib/hdlc" + "openthread/src/lib/spinel" + "openthread/src/core/backbone_router" + "openthread/src/core/coap" + "openthread/src/core/meshcop" + "openthread/src/core/net" + "openthread/src/lib/platform" +) + +set(exclude_srcs + "openthread/examples/platforms/utils/logging_rtt.c" + "openthread/examples/platforms/utils/soft_source_match_table.c" + "openthread/src/core/instance/extension_example.cpp" +) + +# CLI sources +if(CONFIG_OPENTHREAD_CLI) + list(APPEND src_dirs + "openthread/examples/apps/cli" + "openthread/src/cli") + list(APPEND exclude_srcs + "openthread/examples/apps/cli/main.c") +endif() + +# Radio interface exclusions +if(CONFIG_OPENTHREAD_RADIO_NATIVE) + list(APPEND exclude_srcs + "src/port/esp_openthread_radio_spinel.cpp" + "src/port/esp_spi_spinel_interface.cpp" + "src/port/esp_uart_spinel_interface.cpp") +elseif(CONFIG_OPENTHREAD_RADIO_SPINEL_UART OR CONFIG_OPENTHREAD_RADIO_SPINEL_SPI) + list(APPEND exclude_srcs + "src/port/esp_openthread_radio.c" + "src/port/esp_openthread_sleep.c") +elseif(CONFIG_OPENTHREAD_RADIO_154_NONE) + list(APPEND exclude_srcs + "src/port/esp_openthread_radio_spinel.cpp" + "src/port/esp_spi_spinel_interface.cpp" + "src/port/esp_uart_spinel_interface.cpp" + "src/port/esp_openthread_radio.c" + "src/port/esp_openthread_sleep.c") +endif() + +# TREL +if(NOT CONFIG_OPENTHREAD_RADIO_TREL) + list(APPEND exclude_srcs + "src/port/esp_openthread_trel.c") +endif() + +# Border router +if(CONFIG_OPENTHREAD_BORDER_ROUTER) + list(APPEND src_dirs + "openthread/src/core/border_router") +endif() + +# FTD-specific +if(CONFIG_OPENTHREAD_FTD) + set_source_files_properties("openthread/src/core/net/srp_server.cpp" + PROPERTIES COMPILE_FLAGS + -Wno-maybe-uninitialized) +endif() + +# NCP vendor hook +if(CONFIG_OPENTHREAD_NCP_VENDOR_HOOK) + list(APPEND src_dirs + "src/ncp") + if(CONFIG_OPENTHREAD_RCP_UART OR CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG) + list(APPEND exclude_srcs + "src/ncp/esp_openthread_ncp_spi.cpp") + elseif(CONFIG_OPENTHREAD_RCP_SPI) + list(APPEND exclude_srcs + "src/ncp/esp_openthread_ncp_hdlc.cpp") + endif() +endif() + +# Optional features +if(NOT CONFIG_OPENTHREAD_DNS64_CLIENT) + list(APPEND exclude_srcs + "src/esp_openthread_dns64.c") +endif() + +if(NOT CONFIG_FREERTOS_USE_TICKLESS_IDLE) + list(APPEND exclude_srcs + "src/port/esp_openthread_sleep.c") +endif() + +if(NOT CONFIG_OPENTHREAD_PLATFORM_MSGPOOL_MANAGEMENT) + list(APPEND exclude_srcs + "src/port/esp_openthread_messagepool.c") +endif() + +if(NOT CONFIG_OPENTHREAD_RCP_SPINEL_CONSOLE) + list(APPEND exclude_srcs + "src/ncp/esp_openthread_ncp_console.cpp") +endif() diff --git a/components/openthread/srcs_radio.cmake b/components/openthread/srcs_radio.cmake new file mode 100644 index 00000000000..42b9d56dc38 --- /dev/null +++ b/components/openthread/srcs_radio.cmake @@ -0,0 +1,97 @@ +# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +# Source files for RCP (Radio Co-Processor) mode. +# Uses explicit whitelist to avoid including non-RCP-compatible files. +# This prevents new OpenThread files from breaking RCP builds. + +set(rcp_srcs + # OpenThread core - RADIO_COMMON_SOURCES from openthread/src/core/CMakeLists.txt + # No need for crypto/crypto_platform_mbedtls.cpp because we use esp-idf implementation + openthread/src/core/api/diags_api.cpp + openthread/src/core/api/error_api.cpp + openthread/src/core/api/instance_api.cpp + openthread/src/core/api/link_raw_api.cpp + openthread/src/core/api/logging_api.cpp + openthread/src/core/api/random_noncrypto_api.cpp + openthread/src/core/api/tasklet_api.cpp + openthread/src/core/common/binary_search.cpp + openthread/src/core/common/error.cpp + openthread/src/core/common/frame_builder.cpp + openthread/src/core/common/log.cpp + openthread/src/core/common/random.cpp + openthread/src/core/common/string.cpp + openthread/src/core/common/tasklet.cpp + openthread/src/core/common/timer.cpp + openthread/src/core/common/uptime.cpp + openthread/src/core/crypto/aes_ccm.cpp + openthread/src/core/crypto/aes_ecb.cpp + openthread/src/core/crypto/crypto_platform.cpp + openthread/src/core/crypto/storage.cpp + openthread/src/core/diags/factory_diags.cpp + openthread/src/core/instance/instance.cpp + openthread/src/core/mac/link_raw.cpp + openthread/src/core/mac/mac_frame.cpp + openthread/src/core/mac/mac_header_ie.cpp + openthread/src/core/mac/mac_types.cpp + openthread/src/core/mac/sub_mac.cpp + openthread/src/core/mac/sub_mac_callbacks.cpp + openthread/src/core/mac/sub_mac_csl_receiver.cpp + openthread/src/core/mac/sub_mac_wed.cpp + openthread/src/core/radio/radio.cpp + openthread/src/core/radio/radio_callbacks.cpp + openthread/src/core/radio/radio_platform.cpp + openthread/src/core/thread/link_quality.cpp + openthread/src/core/utils/otns.cpp + openthread/src/core/utils/parse_cmdline.cpp + openthread/src/core/utils/power_calibration.cpp + # Platform utils + openthread/examples/platforms/utils/mac_frame.cpp + # HDLC library + openthread/src/lib/hdlc/hdlc.cpp + # Spinel library + openthread/src/lib/spinel/spinel.c + openthread/src/lib/spinel/spinel_buffer.cpp + openthread/src/lib/spinel/spinel_decoder.cpp + openthread/src/lib/spinel/spinel_encoder.cpp + # NCP + openthread/src/ncp/changed_props_set.cpp + openthread/src/ncp/ncp_base.cpp + openthread/src/ncp/ncp_base_dispatcher.cpp + openthread/src/ncp/ncp_base_radio.cpp + openthread/examples/apps/ncp/ncp.c + # ESP port + src/port/esp_openthread_alarm.c + src/port/esp_openthread_logging.c + src/port/esp_openthread_misc.c + src/port/esp_openthread_radio.c + src/port/esp_openthread_settings.c + # ESP sources + src/esp_openthread.cpp + src/esp_openthread_lock.c + src/esp_openthread_platform.cpp + src/esp_openthread_task_queue.c + # ESP NCP + src/ncp/esp_openthread_ncp.cpp +) + +# Conditional sources based on host connection mode +if(CONFIG_OPENTHREAD_RCP_UART OR CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG) + list(APPEND rcp_srcs + openthread/src/ncp/ncp_hdlc.cpp + src/port/esp_openthread_uart.c) + if(CONFIG_OPENTHREAD_NCP_VENDOR_HOOK) + list(APPEND rcp_srcs src/ncp/esp_openthread_ncp_hdlc.cpp) + endif() +elseif(CONFIG_OPENTHREAD_RCP_SPI) + list(APPEND rcp_srcs + openthread/src/ncp/ncp_spi.cpp + src/port/esp_openthread_spi_slave.c) + if(CONFIG_OPENTHREAD_NCP_VENDOR_HOOK) + list(APPEND rcp_srcs src/ncp/esp_openthread_ncp_spi.cpp) + endif() +endif() + +if(CONFIG_OPENTHREAD_NCP_VENDOR_HOOK AND CONFIG_OPENTHREAD_RCP_SPINEL_CONSOLE) + list(APPEND rcp_srcs src/ncp/esp_openthread_ncp_console.cpp) +endif() diff --git a/components/openthread/srcs_spinel.cmake b/components/openthread/srcs_spinel.cmake new file mode 100644 index 00000000000..0dd7daf4076 --- /dev/null +++ b/components/openthread/srcs_spinel.cmake @@ -0,0 +1,45 @@ +# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +# Source files for SPINEL_ONLY mode. +# Minimal build for host-side spinel communication. +# Uses explicit whitelist for clarity. + +set(private_include_dirs + "private_include" + "openthread/src" + "openthread/src/core" + "openthread/src/include" + "openthread/src/lib" + "openthread/src/lib/hdlc" + "openthread/src/lib/spinel" +) + +set(spinel_srcs + # ESP spinel sources + src/spinel/esp_radio_spinel.cpp + src/spinel/esp_radio_spinel_uart_interface.cpp + # ESP port (minimal) + src/port/esp_openthread_alarm.c + src/port/esp_openthread_logging.c + # OpenThread spinel library + openthread/src/lib/spinel/spinel.c + openthread/src/lib/spinel/spinel_buffer.cpp + openthread/src/lib/spinel/spinel_decoder.cpp + openthread/src/lib/spinel/spinel_encoder.cpp + openthread/src/lib/spinel/spinel_helper.cpp + openthread/src/lib/spinel/radio_spinel.cpp + openthread/src/lib/spinel/spinel_driver.cpp + openthread/src/lib/spinel/logger.cpp + # OpenThread HDLC library + openthread/src/lib/hdlc/hdlc.cpp + # OpenThread platform library + openthread/src/lib/platform/exit_code.c + # OpenThread core (minimal) + openthread/src/core/api/error_api.cpp + openthread/src/core/api/logging_api.cpp + openthread/src/core/common/error.cpp + openthread/src/core/common/log.cpp + openthread/src/core/common/string.cpp + openthread/src/core/mac/mac_frame.cpp +) From 7f1cfeac1954d2b32a946a97d4f880410f03de81 Mon Sep 17 00:00:00 2001 From: Tan Yan Quan Date: Thu, 12 Feb 2026 15:09:01 +0800 Subject: [PATCH 2/3] feat(openthread): use heap_caps_calloc_prefer for messagepool --- components/openthread/CMakeLists.txt | 8 ++--- components/openthread/Kconfig | 1 + .../src/esp_openthread_platform.cpp | 2 +- .../src/port/esp_openthread_memory.c | 2 +- .../src/port/esp_openthread_messagepool.c | 31 +++++++++++++------ 5 files changed, 29 insertions(+), 15 deletions(-) diff --git a/components/openthread/CMakeLists.txt b/components/openthread/CMakeLists.txt index 5d5d0694a4d..feddf7d7b29 100644 --- a/components/openthread/CMakeLists.txt +++ b/components/openthread/CMakeLists.txt @@ -70,7 +70,7 @@ if(CONFIG_OPENTHREAD_FTD OR CONFIG_OPENTHREAD_MTD) REQUIRES esp_netif lwip esp_driver_uart driver LDFRAGMENTS linker.lf PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer - ieee802154 mbedtls nvs_flash) + ieee802154 mbedtls nvs_flash esp_psram) elseif(CONFIG_OPENTHREAD_RADIO) # RCP mode uses explicit source list from srcs_radio.cmake idf_component_register(SRCS ${rcp_srcs} @@ -79,7 +79,7 @@ elseif(CONFIG_OPENTHREAD_RADIO) REQUIRES esp_netif lwip esp_driver_uart driver LDFRAGMENTS linker.lf PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer - ieee802154 mbedtls nvs_flash) + ieee802154 mbedtls nvs_flash esp_psram) elseif(CONFIG_OPENTHREAD_SPINEL_ONLY) # SPINEL_ONLY mode uses explicit source list from srcs_spinel.cmake idf_component_register(SRCS ${spinel_srcs} @@ -88,7 +88,7 @@ elseif(CONFIG_OPENTHREAD_SPINEL_ONLY) REQUIRES esp_netif lwip esp_driver_uart driver LDFRAGMENTS linker.lf PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer - ieee802154 mbedtls nvs_flash) + ieee802154 mbedtls nvs_flash esp_psram) else() # This is not supposed to happen, but in older versions of IDF components couldn't be selectively # enabled based on KConfig options so some examples just included openthread for all configs. @@ -97,7 +97,7 @@ else() REQUIRES esp_netif lwip esp_driver_uart driver LDFRAGMENTS linker.lf PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer - ieee802154 mbedtls nvs_flash) + ieee802154 mbedtls nvs_flash esp_psram) endif() if(CONFIG_OPENTHREAD_RADIO_TREL) diff --git a/components/openthread/Kconfig b/components/openthread/Kconfig index c6bf703d8cd..6a258d3f73f 100644 --- a/components/openthread/Kconfig +++ b/components/openthread/Kconfig @@ -436,6 +436,7 @@ menu "OpenThread" config OPENTHREAD_PLATFORM_MSGPOOL_MANAGEMENT bool 'Allocate message pool buffer from PSRAM' + depends on OPENTHREAD_PLATFORM_MALLOC_CAP_SPIRAM default y help If enabled, the message pool is managed by platform defined logic. diff --git a/components/openthread/src/esp_openthread_platform.cpp b/components/openthread/src/esp_openthread_platform.cpp index 82185a1ec6f..c00c48ed557 100644 --- a/components/openthread/src/esp_openthread_platform.cpp +++ b/components/openthread/src/esp_openthread_platform.cpp @@ -227,6 +227,6 @@ uint32_t esp_openthread_get_alloc_caps(void) #if CONFIG_OPENTHREAD_PLATFORM_MALLOC_CAP_SPIRAM (MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); #else - (MALLOC_CAP_DEFAULT | MALLOC_CAP_8BIT); + (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); #endif } diff --git a/components/openthread/src/port/esp_openthread_memory.c b/components/openthread/src/port/esp_openthread_memory.c index 67c3c6df454..6b5aba17f2c 100644 --- a/components/openthread/src/port/esp_openthread_memory.c +++ b/components/openthread/src/port/esp_openthread_memory.c @@ -13,7 +13,7 @@ void *otPlatCAlloc(size_t num, size_t size) { - return heap_caps_calloc(num, size, esp_openthread_get_alloc_caps()); + return heap_caps_calloc_prefer(num, size, 3, esp_openthread_get_alloc_caps(), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); } void otPlatFree(void *ptr) diff --git a/components/openthread/src/port/esp_openthread_messagepool.c b/components/openthread/src/port/esp_openthread_messagepool.c index 17761b50618..7996af33408 100644 --- a/components/openthread/src/port/esp_openthread_messagepool.c +++ b/components/openthread/src/port/esp_openthread_messagepool.c @@ -1,35 +1,48 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "openthread-core-config.h" #include "esp_openthread_common_macro.h" +#include "esp_openthread_platform.h" #include "esp_err.h" #include "esp_log.h" #include "esp_heap_caps.h" +#include "esp_psram.h" #include "openthread/instance.h" #include "openthread/platform/messagepool.h" -int s_buffer_pool_head = -1; -otMessageBuffer **s_buffer_pool_pointer = NULL; -otMessageBuffer *s_buffer_pool = NULL; +// Fallback buffer count at runtime for non-PSRAM targets (matches Kconfig default) +#define OT_MSGPOOL_NUM_BUFFERS_NO_PSRAM 65 + +static int s_buffer_pool_head = -1; +static otMessageBuffer **s_buffer_pool_pointer = NULL; +static otMessageBuffer *s_buffer_pool = NULL; void otPlatMessagePoolInit(otInstance *aInstance, uint16_t aMinNumFreeBuffers, size_t aBufferSize) { - otMessageBuffer *buffer_pool = (otMessageBuffer *)heap_caps_calloc(aMinNumFreeBuffers, aBufferSize, MALLOC_CAP_SPIRAM); - s_buffer_pool_pointer = (otMessageBuffer **)heap_caps_calloc(aMinNumFreeBuffers, sizeof(otMessageBuffer **), MALLOC_CAP_SPIRAM); + uint16_t num_buffers = aMinNumFreeBuffers; + + if (!esp_psram_is_initialized() && num_buffers > OT_MSGPOOL_NUM_BUFFERS_NO_PSRAM) { + ESP_LOGW(OT_PLAT_LOG_TAG, "PSRAM not available, reducing message pool from %u to %u buffers", + num_buffers, OT_MSGPOOL_NUM_BUFFERS_NO_PSRAM); + num_buffers = OT_MSGPOOL_NUM_BUFFERS_NO_PSRAM; + } + + otMessageBuffer *buffer_pool = (otMessageBuffer *)heap_caps_calloc_prefer(num_buffers, aBufferSize, 3, esp_openthread_get_alloc_caps(), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + s_buffer_pool_pointer = (otMessageBuffer **)heap_caps_calloc_prefer(num_buffers, sizeof(otMessageBuffer **), 3, esp_openthread_get_alloc_caps(), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); if (buffer_pool == NULL || s_buffer_pool_pointer == NULL) { ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to create message buffer pool"); assert(false); } - for (uint16_t i = 0; i < aMinNumFreeBuffers; i++) { + for (uint16_t i = 0; i < num_buffers; i++) { s_buffer_pool_pointer[i] = buffer_pool + i * aBufferSize / sizeof(otMessageBuffer); } - s_buffer_pool_head = aMinNumFreeBuffers - 1; + s_buffer_pool_head = num_buffers - 1; s_buffer_pool = buffer_pool; - ESP_LOGI(OT_PLAT_LOG_TAG, "Create message buffer pool successfully, size %d", aMinNumFreeBuffers*aBufferSize); + ESP_LOGI(OT_PLAT_LOG_TAG, "Create message buffer pool successfully, size %d", num_buffers * aBufferSize); } otMessageBuffer *otPlatMessagePoolNew(otInstance *aInstance) From 0c03fc73a93f55c44de681a5d48d360d8cafded8 Mon Sep 17 00:00:00 2001 From: Xu Si Yu Date: Thu, 25 Dec 2025 19:09:42 +0800 Subject: [PATCH 3/3] feat(openthread): add a task block monitor --- components/openthread/Kconfig | 22 +++ .../private_include/esp_openthread_debug.h | 55 ++++++++ components/openthread/src/esp_openthread.cpp | 19 ++- .../src/port/esp_openthread_debug.c | 131 ++++++++++++++++++ examples/openthread/.build-test-rules.yml | 2 + examples/openthread/ot_br/partitions.csv | 6 +- .../openthread/ot_br/sdkconfig.ci.br_debug | 2 + .../ot_br/sdkconfig.ci.br_debug_riscv | 2 + examples/openthread/ot_br/sdkconfig.defaults | 6 +- .../ot_br/sdkconfig.defaults.esp32p4 | 2 + examples/openthread/ot_cli/partitions.csv | 6 +- 11 files changed, 243 insertions(+), 10 deletions(-) create mode 100644 components/openthread/private_include/esp_openthread_debug.h create mode 100644 components/openthread/src/port/esp_openthread_debug.c create mode 100644 examples/openthread/ot_br/sdkconfig.ci.br_debug create mode 100644 examples/openthread/ot_br/sdkconfig.ci.br_debug_riscv diff --git a/components/openthread/Kconfig b/components/openthread/Kconfig index 6a258d3f73f..52730eeaf70 100644 --- a/components/openthread/Kconfig +++ b/components/openthread/Kconfig @@ -623,5 +623,27 @@ menu "OpenThread" information whenever an OpenThread assert occurs. This can help developers analyze unexpected failures by providing additional MAC layer context. + config OPENTHREAD_TASK_BLOCK_MONITOR + depends on OPENTHREAD_DEBUG + bool "Enable OpenThread Task Block Monitor" + default n + help + Enable monitoring of OpenThread tasks to detect if a task is blocked + and unable to continue its normal execution loop. Useful for debugging + issues where tasks stop progressing due to deadlocks or resource waits. + On RISC-V targets, in order to get meaningful backtraces when a task is + detected as blocked, ESP_SYSTEM_USE_EH_FRAME must be enabled in + ESP System Settings. + + config OPENTHREAD_TASK_BLOCK_MONITOR_TIMEOUT + depends on OPENTHREAD_TASK_BLOCK_MONITOR + int "Task Block Monitor Timeout (seconds)" + range 1 60 + default 20 + help + Set the timeout (in seconds) for detecting a blocked task. + The timer is started at the beginning of each task main loop + and stopped at the end. If the timer expires, the task is considered blocked. + endmenu diff --git a/components/openthread/private_include/esp_openthread_debug.h b/components/openthread/private_include/esp_openthread_debug.h new file mode 100644 index 00000000000..8e6ea8f5206 --- /dev/null +++ b/components/openthread/private_include/esp_openthread_debug.h @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR +/** + * @brief This function creates the OpenThread task block monitor. + * The monitor task periodically checks whether the OpenThread mainloop + * has been blocked for more than `CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR_TIMEOUT` + * seconds and prints backtraces when a block is detected. + * + * @return + * - ESP_OK on success + * - ESP_FAIL if the monitor task cannot be created + * + */ +esp_err_t esp_openthread_task_block_monitor_create(void); + +/** + * @brief This function deletes the OpenThread task block monitor. + * + * @return + * - ESP_OK on success + * + */ +esp_err_t esp_openthread_task_block_monitor_delete(void); + +/** + * @brief This function enables or disables the OpenThread task block monitor. + * + * @note When enabled, the latest mainloop activity timestamp is updated and the + * monitor task starts checking for blocking. When disabled, monitoring is + * temporarily stopped. + * + * @param[in] enable True to enable the monitor, false to disable it. + * + */ +void esp_openthread_task_block_monitor_set(bool enable); +#endif // CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR + +#ifdef __cplusplus +} +#endif diff --git a/components/openthread/src/esp_openthread.cpp b/components/openthread/src/esp_openthread.cpp index 1868cf0f250..74522d64b83 100644 --- a/components/openthread/src/esp_openthread.cpp +++ b/components/openthread/src/esp_openthread.cpp @@ -18,6 +18,7 @@ #include "esp_openthread_platform.h" #include "esp_openthread_sleep.h" #include "esp_openthread_state.h" +#include "esp_openthread_debug.h" #include "esp_openthread_task_queue.h" #include "esp_openthread_types.h" #include "freertos/FreeRTOS.h" @@ -27,7 +28,6 @@ #include "openthread/netdata.h" #include "openthread/tasklet.h" #include "openthread/thread.h" -#include #if CONFIG_OPENTHREAD_FTD #include "openthread/dataset_ftd.h" @@ -186,6 +186,10 @@ esp_err_t esp_openthread_launch_mainloop(void) esp_err_t error = ESP_OK; s_ot_mainloop_running = true; +#if CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR + ESP_ERROR_CHECK(esp_openthread_task_block_monitor_create()); +#endif + while (s_ot_mainloop_running) { FD_ZERO(&mainloop.read_fds); FD_ZERO(&mainloop.write_fds); @@ -206,8 +210,14 @@ esp_err_t esp_openthread_launch_mainloop(void) #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE && CONFIG_OPENTHREAD_RADIO_NATIVE */ esp_openthread_lock_release(); - if (select(mainloop.max_fd + 1, &mainloop.read_fds, &mainloop.write_fds, &mainloop.error_fds, - &mainloop.timeout) >= 0) { +#if CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR + esp_openthread_task_block_monitor_set(false); +#endif + int result = select(mainloop.max_fd + 1, &mainloop.read_fds, &mainloop.write_fds, &mainloop.error_fds, &mainloop.timeout); +#if CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR + esp_openthread_task_block_monitor_set(true); +#endif + if (result >= 0) { esp_openthread_lock_acquire(portMAX_DELAY); error = esp_openthread_platform_process(instance, &mainloop); while (otTaskletsArePending(instance)) { @@ -224,6 +234,9 @@ esp_err_t esp_openthread_launch_mainloop(void) break; } } +#if CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR + ESP_ERROR_CHECK(esp_openthread_task_block_monitor_delete()); +#endif return error; } diff --git a/components/openthread/src/port/esp_openthread_debug.c b/components/openthread/src/port/esp_openthread_debug.c new file mode 100644 index 00000000000..d77a1f0ffb0 --- /dev/null +++ b/components/openthread/src/port/esp_openthread_debug.c @@ -0,0 +1,131 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" + +#include +#include +#include + +#include "esp_check.h" +#include "esp_log.h" +#include "esp_timer.h" +#include "esp_debug_helpers.h" +#include "esp_openthread_debug.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#if CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR + +#include "esp_private/eh_frame_parser.h" +#include "esp_attr.h" +#include "esp_private/esp_cpu_internal.h" +#include "esp_private/panic_internal.h" +#include "esp_private/freertos_debug.h" + +static const char *TAG = "OT_DEBUG"; +static TaskHandle_t s_ot_task_block_monitor_task = NULL; +static atomic_llong s_ot_task_block_monitor_latest_time = 0; +static atomic_bool s_ot_task_block_monitor_active = false; +static const int64_t s_ot_task_block_monitor_timeout = CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR_TIMEOUT * 1000000; +static bool is_backtrace_printed = false; + +#if CONFIG_IDF_TARGET_ARCH_RISCV +static esp_err_t IRAM_ATTR esp_task_backtrace_print(TaskHandle_t target_task) +{ + TaskSnapshot_t snapshot = {}; + void *frame = NULL; + + vTaskGetSnapshot(target_task, &snapshot); + + frame = snapshot.pxTopOfStack; + char *name = pcTaskGetName(target_task); + + ESP_LOGI(TAG, "Target Task Backtrace: %s", name ? name : "No Name"); + +#if CONFIG_ESP_SYSTEM_USE_EH_FRAME + esp_eh_frame_print_backtrace(frame); +#else + esp_cpu_frame_t backtrace_frame = {}; + const int current_core = xPortGetCoreID(); + memset(&backtrace_frame, 0, sizeof(esp_cpu_frame_t)); + memcpy(&backtrace_frame, frame, sizeof(esp_cpu_frame_t)); + + panic_prepare_frame_from_ctx(&backtrace_frame); + panic_print_registers(&backtrace_frame, current_core); + + esp_rom_printf("\r\n"); + esp_rom_printf("Please enable CONFIG_ESP_SYSTEM_USE_EH_FRAME option to have a full backtrace.\r\n"); +#endif + + return ESP_OK; +} +#endif + +static void ot_debug_monitor_task(void *arg) +{ + (void)arg; + + while (true) { + if (atomic_load(&s_ot_task_block_monitor_active)) { + int64_t elapsed = esp_timer_get_time() - atomic_load(&s_ot_task_block_monitor_latest_time); + if (elapsed > s_ot_task_block_monitor_timeout && !is_backtrace_printed) { + is_backtrace_printed = true; + ESP_LOGW(TAG, + "OpenThread mainloop blocked for more than %d seconds, printing all tasks backtrace", + CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR_TIMEOUT); +#if CONFIG_IDF_TARGET_ARCH_XTENSA + esp_backtrace_print_all_tasks(10); +#elif CONFIG_IDF_TARGET_ARCH_RISCV + TaskHandle_t handle = xTaskGetHandle(CONFIG_OPENTHREAD_TASK_NAME); + if (handle) { + esp_task_backtrace_print(handle); + } +#endif + } else if (elapsed <= s_ot_task_block_monitor_timeout) { + is_backtrace_printed = false; + } + } + + vTaskDelay(pdMS_TO_TICKS(1000)); + } +} + +esp_err_t esp_openthread_task_block_monitor_create(void) +{ + ESP_RETURN_ON_FALSE(s_ot_task_block_monitor_task == NULL, ESP_OK, TAG, "Task block monitor already created"); + + BaseType_t ret = xTaskCreate(ot_debug_monitor_task, "ot_task_monitor", 3072, NULL, CONFIG_OPENTHREAD_TASK_PRIORITY, &s_ot_task_block_monitor_task); + ESP_RETURN_ON_FALSE(ret == pdPASS, ESP_FAIL, TAG, "Failed to create OpenThread task block monitor"); + + ESP_LOGI(TAG, "OpenThread task block monitor created"); + esp_openthread_task_block_monitor_set(true); + return ESP_OK; +} + +esp_err_t esp_openthread_task_block_monitor_delete(void) +{ + ESP_RETURN_ON_FALSE(s_ot_task_block_monitor_task != NULL, ESP_OK, TAG, "Task block monitor not created"); + + esp_openthread_task_block_monitor_set(false); + vTaskDelete(s_ot_task_block_monitor_task); + s_ot_task_block_monitor_task = NULL; + + ESP_LOGI(TAG, "OpenThread task block monitor deleted"); + return ESP_OK; +} + +void esp_openthread_task_block_monitor_set(bool enable) +{ + if (enable) { + atomic_store(&s_ot_task_block_monitor_latest_time, esp_timer_get_time()); + atomic_store(&s_ot_task_block_monitor_active, true); + } else { + atomic_store(&s_ot_task_block_monitor_active, false); + } +} + +#endif // CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR diff --git a/examples/openthread/.build-test-rules.yml b/examples/openthread/.build-test-rules.yml index 5ae422c4616..8c322783d7c 100644 --- a/examples/openthread/.build-test-rules.yml +++ b/examples/openthread/.build-test-rules.yml @@ -25,6 +25,8 @@ examples/openthread/ot_br: enable: - if: (SOC_WIFI_SUPPORTED == 1 or IDF_TARGET == "esp32p4") and CONFIG_NAME != "native_radio" - if: SOC_WIFI_SUPPORTED == 1 and (SOC_IEEE802154_SUPPORTED == 1 and CONFIG_NAME == "native_radio") + disable: + - if: IDF_TARGET in ["esp32", "esp32s2", "esp32s3"] and CONFIG_NAME == "br_debug_riscv" disable_test: - if: IDF_TARGET not in ["esp32s3"] reason: only test on esp32s3 diff --git a/examples/openthread/ot_br/partitions.csv b/examples/openthread/ot_br/partitions.csv index 376458ad8b8..531e721a29d 100644 --- a/examples/openthread/ot_br/partitions.csv +++ b/examples/openthread/ot_br/partitions.csv @@ -1,5 +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, 1900K, +nvs, data, nvs, , 0x6000, +phy_init, data, phy, , 0x1000, +factory, app, factory, , 2000K, diff --git a/examples/openthread/ot_br/sdkconfig.ci.br_debug b/examples/openthread/ot_br/sdkconfig.ci.br_debug new file mode 100644 index 00000000000..85b50225fae --- /dev/null +++ b/examples/openthread/ot_br/sdkconfig.ci.br_debug @@ -0,0 +1,2 @@ +CONFIG_OPENTHREAD_DEBUG=y +CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR=y diff --git a/examples/openthread/ot_br/sdkconfig.ci.br_debug_riscv b/examples/openthread/ot_br/sdkconfig.ci.br_debug_riscv new file mode 100644 index 00000000000..85b50225fae --- /dev/null +++ b/examples/openthread/ot_br/sdkconfig.ci.br_debug_riscv @@ -0,0 +1,2 @@ +CONFIG_OPENTHREAD_DEBUG=y +CONFIG_OPENTHREAD_TASK_BLOCK_MONITOR=y diff --git a/examples/openthread/ot_br/sdkconfig.defaults b/examples/openthread/ot_br/sdkconfig.defaults index 7fe886d91f3..23cd52c6e18 100644 --- a/examples/openthread/ot_br/sdkconfig.defaults +++ b/examples/openthread/ot_br/sdkconfig.defaults @@ -4,7 +4,6 @@ CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" -CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table @@ -58,3 +57,8 @@ CONFIG_EXAMPLE_CONNECT_THREAD=n CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3584 CONFIG_ESP_MAIN_TASK_STACK_SIZE=6144 # end of ESP System Settings + +# +# Serial flasher config +# +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y diff --git a/examples/openthread/ot_br/sdkconfig.defaults.esp32p4 b/examples/openthread/ot_br/sdkconfig.defaults.esp32p4 index 3b161864c7f..8277f12de55 100644 --- a/examples/openthread/ot_br/sdkconfig.defaults.esp32p4 +++ b/examples/openthread/ot_br/sdkconfig.defaults.esp32p4 @@ -5,3 +5,5 @@ CONFIG_OPENTHREAD_BORDER_ROUTER_AUTO_START=y # Enable PPP support as a workaround to ensure LWIP thread-lib compatibility for Ethernet builds CONFIG_LWIP_PPP_SUPPORT=y CONFIG_LWIP_PPP_SERVER_SUPPORT=y +# Increase size of bootloader due to frame pointer. Only overflowed on P4. +CONFIG_PARTITION_TABLE_OFFSET=0x9000 diff --git a/examples/openthread/ot_cli/partitions.csv b/examples/openthread/ot_cli/partitions.csv index a55f875a133..4062dba21c4 100644 --- a/examples/openthread/ot_cli/partitions.csv +++ b/examples/openthread/ot_cli/partitions.csv @@ -1,5 +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, 0x140000, +nvs, data, nvs, , 0x6000, +phy_init, data, phy, , 0x1000, +factory, app, factory, , 0x180000,