From 842a17596655e0b8dce05c86e192cf29f5389aa4 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 26 Nov 2025 12:22:27 +0530 Subject: [PATCH] fix(nimble): Memory optimization + dynamic memory support --- components/bt/CMakeLists.txt | 4 + components/bt/host/nimble/Kconfig.in | 478 +++++++++++------- .../host/nimble/esp-hci/src/esp_nimble_hci.c | 20 +- components/bt/host/nimble/nimble | 2 +- .../host/nimble/port/include/esp_nimble_cfg.h | 132 ++++- .../host/nimble/port/include/esp_nimble_mem.h | 47 +- components/bt/porting/include/bt_osi_mem.h | 79 +++ components/bt/porting/mem/bt_osi_mem.c | 276 +++++++++- components/bt/porting/mem/os_msys_init.c | 13 +- .../npl/freertos/src/npl_os_freertos.c | 7 + .../bt/porting/transport/src/hci_transport.c | 2 + 11 files changed, 842 insertions(+), 218 deletions(-) diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 57007eb0d2..fc1afbc246 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -685,6 +685,10 @@ if(CONFIG_BT_ENABLED) "porting/transport/src/hci_transport.c" ) + list(APPEND include_dirs + host/nimble/port/include + ) + if(CONFIG_BT_CONTROLLER_DISABLED) list(APPEND srcs "host/nimble/nimble/porting/nimble/src/hal_uart.c" diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index e05126678f..5328a7008e 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -80,28 +80,28 @@ menu "Roles and Profiles" depends on BT_NIMBLE_ENABLED default y help - Enables central role + Enables BLE Central role config BT_NIMBLE_ROLE_PERIPHERAL bool "Enable BLE Peripheral role" depends on BT_NIMBLE_ENABLED default y help - Enable peripheral role + Enable BLE Peripheral role config BT_NIMBLE_ROLE_BROADCASTER bool "Enable BLE Broadcaster role" depends on BT_NIMBLE_ENABLED default y help - Enables broadcaster role + Enables BLE broadcaster role config BT_NIMBLE_ROLE_OBSERVER bool "Enable BLE Observer role" depends on BT_NIMBLE_ENABLED default y help - Enables observer role + Enables BLE Observer role config BT_NIMBLE_GATT_CLIENT bool "Enable BLE GATT Client support" @@ -127,57 +127,84 @@ menu "Security (SMP)" help Enable BLE sm feature - config BT_NIMBLE_SM_LEGACY - bool "Security manager legacy pairing" - depends on BT_NIMBLE_SECURITY_ENABLE - default y - help - Enable security manager legacy pairing + if BT_NIMBLE_SECURITY_ENABLE + config BT_NIMBLE_SM_LEGACY + bool "Security manager legacy pairing" + default y + help + Enable security manager legacy pairing - config BT_NIMBLE_SM_SC - bool "Security manager secure connections (4.2)" - depends on BT_NIMBLE_SECURITY_ENABLE - default y - help - Enable security manager secure connections + config BT_NIMBLE_SM_SC + bool "Security manager secure connections (4.2)" + default y + help + Enable security manager secure connections - config BT_NIMBLE_SM_SC_DEBUG_KEYS - bool "Use predefined public-private key pair" - default n - depends on BT_NIMBLE_SECURITY_ENABLE && BT_NIMBLE_SM_SC - help - If this option is enabled, SM uses predefined DH key pair as described - in Core Specification, Vol. 3, Part H, 2.3.5.6.1. This allows to - decrypt air traffic easily and thus should only be used for debugging. + config BT_NIMBLE_SM_SC_DEBUG_KEYS + bool "Use predefined public-private key pair" + default n + depends on BT_NIMBLE_SM_SC + help + If this option is enabled, SM uses predefined DH key pair as described + in Core Specification, Vol. 3, Part H, 2.3.5.6.1. This allows to + decrypt air traffic easily and thus should only be used for debugging. - config BT_NIMBLE_LL_CFG_FEAT_LE_ENCRYPTION - bool "Enable LE encryption" - depends on BT_NIMBLE_SECURITY_ENABLE && BT_NIMBLE_ENABLED - default y - help - Enable encryption connection + config BT_NIMBLE_LL_CFG_FEAT_LE_ENCRYPTION + bool "Enable LE encryption" + default y + help + Enable encryption connection - config BT_NIMBLE_SM_LVL - int "Security level" - depends on BT_NIMBLE_SECURITY_ENABLE - default 0 - help - LE Security Mode 1 Levels: - 1. No Security - 2. Unauthenticated pairing with encryption - 3. Authenticated pairing with encryption - 4. Authenticated LE Secure Connections pairing with encryption using a 128-bit strength encryption key. + config BT_NIMBLE_SM_LVL + int "Security level" + default 0 + help + LE Security Mode 1 Levels: + 1. No Security + 2. Unauthenticated pairing with encryption + 3. Authenticated pairing with encryption + 4. Authenticated LE Secure Connections pairing with encryption using a 128-bit strength encryption key. - config BT_NIMBLE_SM_SC_ONLY - int "Enable Secure Connections Only Mode" - depends on BT_NIMBLE_SECURITY_ENABLE - default 0 - help - Enable Secure Connections Only Mode + config BT_NIMBLE_SM_SC_ONLY + int "Enable Secure Connections Only Mode" + default 0 + help + Enable Secure Connections Only Mode + config BT_NIMBLE_SMP_ID_RESET + bool "Reset device identity when all bonding records are deleted" + default n + help + There are tracking risks associated with using a fixed or static IRK. + If enabled this option, NimBLE will assign a new randomly-generated IRK + when all pairing and bonding records are deleted. This would decrease the ability + of a previously paired peer to be used to determine whether a device + with which it previously shared an IRK is within range. + + config BT_NIMBLE_NVS_PERSIST + bool "Persist the BLE Bonding keys in NVS" + default n + help + Enable this flag to make bonding persistent across device reboots + + config BT_NIMBLE_MAX_BONDS + int "Maximum number of bonds to save across reboots" + default 3 + help + Defines maximum number of bonds to save for peer security and our security + + config BT_NIMBLE_HANDLE_REPEAT_PAIRING_DELETION + bool "Enable stack handling of repeat pairing" + default n + help + Use this option to let stack internally handle the request for repeat pairing. + Enabling this option will delete the pairing of the device and stack will NOT post any event + to application. If this option is disabled, application will get BLE_GAP_EVENT_REPEAT_PAIRING + event. + endif endmenu #SMP -menu "GAP / GATT / Device Settings" +menu "GAP" config BT_NIMBLE_RPA_TIMEOUT int "RPA timeout in seconds" range 1 41400 @@ -193,15 +220,15 @@ menu "GAP / GATT / Device Settings" range 1 15 default 12 help - BLE list size + BLE Whitelist size config BT_NIMBLE_ENABLE_CONN_REATTEMPT bool "Enable connection reattempts on connection establishment error" default y if (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || SOC_ESP_NIMBLE_CONTROLLER) default n if IDF_TARGET_ESP32 help - Enable to make the NimBLE host to reattempt GAP connection on connection - establishment failure. + Enable to make the NimBLE host to reattempt GAP connection attempt in case of + connection establishment failure due to reason 0x3E. config BT_NIMBLE_MAX_CONN_REATTEMPT int "Maximum number connection reattempts" @@ -211,23 +238,23 @@ menu "GAP / GATT / Device Settings" help Defines maximum number of connection reattempts. - config BT_NIMBLE_HANDLE_REPEAT_PAIRING_DELETION - bool "Enable stack handling of repeat pairing" - default n + config BT_NIMBLE_HS_PVCY + bool "Enable privacy related APIs" + default y depends on BT_NIMBLE_ENABLED help - Use this option to let stack internally handle the request for repeat pairing. - Enabling this option will delete the pairing of the device and stack will NOT post any event - to application. If this option is disabled, application will get BLE_GAP_EVENT_REPEAT_PAIRING - event. + Enable this option to include host-side APIs related to BLE privacy. + Disable it if your application does not require privacy features (such as + RPA generation, resolving, or privacy-based pairing). Disabling this option + excludes privacy-related code from the host to reduce memory usage. config BT_NIMBLE_HOST_BASED_PRIVACY bool "Enable host based privacy for random address." default n - depends on BT_NIMBLE_ENABLED && IDF_TARGET_ESP32 + depends on BT_NIMBLE_ENABLED && BT_NIMBLE_HS_PVCY && IDF_TARGET_ESP32 help Use this option to do host based Random Private Address resolution. - If this option is disabled then controller based privacy is used. + This option is valid only for ESP32 config BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN bool "Allow Connections with scanning in progress" @@ -246,6 +273,7 @@ menu "GAP / GATT / Device Settings" config BT_NIMBLE_MAX_CONNECTIONS int "Maximum number of concurrent connections" + depends on BT_NIMBLE_ROLE_CENTRAL || BT_NIMBLE_ROLE_PERIPHERAL range 1 2 if IDF_TARGET_ESP32C2 range 1 70 if SOC_ESP_NIMBLE_CONTROLLER range 1 9 @@ -259,60 +287,13 @@ menu "GAP / GATT / Device Settings" configure BT_CTRL_BLE_MAX_ACT from controller menu. For ESP32C2, ESP32C6 and ESP32H2, each connection will take about 1k DRAM. - config BT_NIMBLE_MAX_BONDS - int "Maximum number of bonds to save across reboots" - default 3 - depends on BT_NIMBLE_ENABLED - help - Defines maximum number of bonds to save for peer security and our security - config BT_NIMBLE_MAX_CCCDS int "Maximum number of CCC descriptors to save across reboots" default 8 - depends on BT_NIMBLE_ENABLED + depends on BT_NIMBLE_ENABLED && BT_NIMBLE_NVS_PERSIST help Defines maximum number of CCC descriptors to save - - config BT_NIMBLE_NVS_PERSIST - bool "Persist the BLE Bonding keys in NVS" - depends on BT_NIMBLE_ENABLED - default n - help - Enable this flag to make bonding persistent across device reboots - - config BT_NIMBLE_SMP_ID_RESET - bool "Reset device identity when all bonding records are deleted" - default n - help - There are tracking risks associated with using a fixed or static IRK. - If enabled this option, NimBLE will assign a new randomly-generated IRK - when all pairing and bonding records are deleted. This would decrease the ability - of a previously paired peer to be used to determine whether a device - with which it previously shared an IRK is within range. - - config BT_NIMBLE_ATT_PREFERRED_MTU - int "Preferred MTU size in octets" - depends on BT_NIMBLE_ENABLED - default 256 - help - This is the default value of ATT MTU indicated by the device during an ATT MTU exchange. - This value can be changed using API ble_att_set_preferred_mtu() - - config BT_NIMBLE_ATT_MAX_PREP_ENTRIES - int "Max Prepare write entries" - depends on BT_NIMBLE_ENABLED - default 64 - help - This is the default value of ATT Maximum prepare entries - - config BT_NIMBLE_GATT_MAX_PROCS - int "Maximum number of GATT client procedures" - depends on BT_NIMBLE_ENABLED - default 4 - help - Maximum number of GATT client procedures that can be executed. - config BT_NIMBLE_CRYPTO_STACK_MBEDTLS bool "Override TinyCrypt with mbedTLS for crypto computations" default y @@ -329,19 +310,12 @@ menu "GAP / GATT / Device Settings" help BLE Host stop procedure timeout in milliseconds. - config BT_NIMBLE_USE_ESP_TIMER bool "Enable Esp Timer for Nimble" default y help Set this option to use Esp Timer which has higher priority timer instead of FreeRTOS timer - config BT_NIMBLE_BLE_GATT_BLOB_TRANSFER - bool "Blob transfer" - help - This option is used when data to be sent is more than 512 bytes. For peripheral role, - BT_NIMBLE_MSYS_1_BLOCK_COUNT needs to be increased according to the need. - config BT_NIMBLE_HS_FLOW_CTRL bool "Enable Host Flow control" depends on BT_NIMBLE_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER @@ -376,6 +350,113 @@ menu "GAP / GATT / Device Settings" endmenu #GAP +menu "GATT / ATT" + config BT_NIMBLE_ATT_PREFERRED_MTU + int "Preferred MTU size in octets" + depends on BT_NIMBLE_GATT_CLIENT || BT_NIMBLE_GATT_SERVER + default 256 + help + This is the default value of ATT MTU indicated by the device during an ATT MTU exchange. + This value can be changed using API ble_att_set_preferred_mtu() + + config BT_NIMBLE_ATT_MAX_PREP_ENTRIES + int "Max Prepare write entries" + depends on BT_NIMBLE_GATT_CLIENT || BT_NIMBLE_GATT_SERVER + default 64 + help + This is the default value of ATT Maximum prepare entries + + config BT_NIMBLE_GATT_MAX_PROCS + int "Maximum number of GATT client procedures" + depends on BT_NIMBLE_GATT_CLIENT || BT_NIMBLE_GATT_SERVER + default 4 + help + Maximum number of GATT client procedures that can be executed. + + config BT_NIMBLE_BLE_GATT_BLOB_TRANSFER + bool "Blob transfer" + depends on BT_NIMBLE_GATT_CLIENT || BT_NIMBLE_GATT_SERVER + help + This option is used when data to be sent is more than 512 bytes. For peripheral role, + BT_NIMBLE_MSYS_1_BLOCK_COUNT needs to be increased according to the need. + + + menuconfig BT_NIMBLE_GATT_CACHING + bool "Enable GATT caching" + depends on BT_NIMBLE_ENABLED + select BT_NIMBLE_DYNAMIC_SERVICE + help + Enable GATT caching + + config BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES + bool "Include services in GATT caching" + depends on BT_NIMBLE_GATT_CACHING + default n + help + Enable this option to include *included services* (e.g., services referenced by other services) + in the GATT database cache. Disabling this will skip caching of included service entries. + + config BT_NIMBLE_INCL_SVC_DISCOVERY + bool + default y if BT_NIMBLE_GATT_CACHING && BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES + default n if BT_NIMBLE_GATT_CACHING && !BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES + default n if !BT_NIMBLE_GATT_CACHING + prompt "Enable Included service discovery" if !BT_NIMBLE_GATT_CACHING + help + Enable this option to start discovery for included service. + + config BT_NIMBLE_GATT_CACHING_MAX_CONNS + int "Maximum connections to be cached" + depends on BT_NIMBLE_GATT_CACHING + default BT_NIMBLE_MAX_CONNECTIONS + help + Set this option to set the upper limit on number of connections to be cached. + + config BT_NIMBLE_GATT_CACHING_MAX_SVCS + int "Maximum number of services per connection" + depends on BT_NIMBLE_GATT_CACHING + default 64 + help + Set this option to set the upper limit on number of services per connection to be cached. + + config BT_NIMBLE_GATT_CACHING_MAX_INCL_SVCS + int "Maximum number of included services per connection" + depends on BT_NIMBLE_GATT_CACHING + default 64 + help + Set this option to set the upper limit on number of included services per connection to be cached. + + config BT_NIMBLE_GATT_CACHING_MAX_CHRS + int "Maximum number of characteristics per connection" + depends on BT_NIMBLE_GATT_CACHING + default 64 + help + Set this option to set the upper limit on number of characteristics per connection to be cached. + + config BT_NIMBLE_GATT_CACHING_MAX_DSCS + int "Maximum number of descriptors per connection" + depends on BT_NIMBLE_GATT_CACHING + default 64 + help + Set this option to set the upper limit on number of descriptors per connection to be cached. + + config BT_NIMBLE_GATT_CACHING_DISABLE_AUTO + bool "Do not start discovery procedure automatically upon receiving Out of Sync" + depends on BT_NIMBLE_GATT_CACHING + default n + help + When client receives ATT out-of-sync error message, it will not automatically start the discovery procedure + to correct the invalid cache. + + config BT_NIMBLE_GATT_CACHING_ASSOC_ENABLE + bool "Enable association-based GATT caching" + depends on BT_NIMBLE_GATT_CACHING + default n + help + Enable this option to use associated address caching instead of performing service discovery. + +endmenu #GATT/ATT + menu "L2CAP" config BT_NIMBLE_L2CAP_COC_MAX_NUM int "Maximum number of connection oriented channels" @@ -388,7 +469,7 @@ menu "L2CAP" config BT_NIMBLE_L2CAP_ENHANCED_COC bool "L2CAP Enhanced Connection Oriented Channel" depends on BT_NIMBLE_ENABLED && (BT_NIMBLE_L2CAP_COC_MAX_NUM >= 1) - default 0 + default n help Enable Enhanced Credit Based Flow Control Mode @@ -416,7 +497,7 @@ menu "Memory Settings" int "MSYS_2 Block Count" default 24 help - Dynamic memory count + Dynamic memory count for block 2 config BT_NIMBLE_MSYS_2_BLOCK_SIZE int "MSYS_2 Block Size" @@ -735,7 +816,7 @@ menu "BLE 6.x Features" depends on BT_NIMBLE_ENABLED && (SOC_BLE_60_SUPPORTED || BT_CONTROLLER_DISABLED) default n help - Enable BLE 6 feature + Enable BLE 6.x feature support if BT_NIMBLE_60_FEATURE_SUPPORT config BT_NIMBLE_CHANNEL_SOUNDING @@ -1124,80 +1205,6 @@ menu "Extra Features" help This enables user to add/remove Gatt services at runtime - menuconfig BT_NIMBLE_GATT_CACHING - bool "Enable GATT caching" - depends on BT_NIMBLE_ENABLED - select BT_NIMBLE_DYNAMIC_SERVICE - help - Enable GATT caching - - config BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES - bool "Include services in GATT caching" - depends on BT_NIMBLE_GATT_CACHING - default n - help - Enable this option to include *included services* (e.g., services referenced by other services) - in the GATT database cache. Disabling this will skip caching of included service entries. - - config BT_NIMBLE_INCL_SVC_DISCOVERY - bool - default y if BT_NIMBLE_GATT_CACHING && BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES - default n if BT_NIMBLE_GATT_CACHING && !BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES - default n if !BT_NIMBLE_GATT_CACHING - prompt "Enable Included service discovery" if !BT_NIMBLE_GATT_CACHING - help - Enable this option to start discovery for included service. - - config BT_NIMBLE_GATT_CACHING_MAX_CONNS - int "Maximum connections to be cached" - depends on BT_NIMBLE_GATT_CACHING - default BT_NIMBLE_MAX_CONNECTIONS - help - Set this option to set the upper limit on number of connections to be cached. - - config BT_NIMBLE_GATT_CACHING_MAX_SVCS - int "Maximum number of services per connection" - depends on BT_NIMBLE_GATT_CACHING - default 64 - help - Set this option to set the upper limit on number of services per connection to be cached. - - config BT_NIMBLE_GATT_CACHING_MAX_INCL_SVCS - int "Maximum number of included services per connection" - depends on BT_NIMBLE_GATT_CACHING - default 64 - help - Set this option to set the upper limit on number of included services per connection to be cached. - - config BT_NIMBLE_GATT_CACHING_MAX_CHRS - int "Maximum number of characteristics per connection" - depends on BT_NIMBLE_GATT_CACHING - default 64 - help - Set this option to set the upper limit on number of characteristics per connection to be cached. - - config BT_NIMBLE_GATT_CACHING_MAX_DSCS - int "Maximum number of descriptors per connection" - depends on BT_NIMBLE_GATT_CACHING - default 64 - help - Set this option to set the upper limit on number of descriptors per connection to be cached. - - config BT_NIMBLE_GATT_CACHING_DISABLE_AUTO - bool "Do not start discovery procedure automatically upon receiving Out of Sync" - depends on BT_NIMBLE_GATT_CACHING - default n - help - When client receives ATT out-of-sync error message, it will not automatically start the discovery procedure - to correct the invalid cache. - - config BT_NIMBLE_GATT_CACHING_ASSOC_ENABLE - bool "Enable association-based GATT caching" - depends on BT_NIMBLE_GATT_CACHING - default n - help - Enable this option to use associated address caching instead of performing service discovery. - config BT_NIMBLE_BLUFI_ENABLE bool "Enable blufi functionality" depends on BT_NIMBLE_ENABLED @@ -1235,7 +1242,6 @@ menu "Extra Features" error suggests insufficient security, then the central will initiate pairing and retry the service request. - config BT_NIMBLE_EATT_CHAN_NUM int "Maximum number of EATT channels" default 0 @@ -1256,6 +1262,59 @@ menu "Extra Features" depends on BT_NIMBLE_ENABLED && BT_NIMBLE_SECURITY_ENABLE help Enable support for user defined static passkey for SMP + + config BT_NIMBLE_DTM_MODE_TEST + bool "Enable DTM related test procedure support" + default y + depends on BT_NIMBLE_ENABLED + help + Enable DTM related test procedure support + + config BT_NIMBLE_MEM_OPTIMIZATION + bool "Enable memory optimization" + depends on BT_NIMBLE_ENABLED + default y + help + This option enables memory optimizations in the NimBLE stack. + + config BT_NIMBLE_STATIC_TO_DYNAMIC + bool "Use Dynamic Memory allocations instead of static" + depends on BT_NIMBLE_ENABLED + default y + help + This option enables use of dynamic memory allocation instead of static + allocation for variable global / local variable. This helps in improving + memory footprint + + config BT_NIMBLE_SM_SIGN_CNT + bool "Enable Sign counter operations" + default y + depends on BT_NIMBLE_ENABLED + help + Enable Sign counter operations + + config BT_NIMBLE_CPFD_CAFD + bool "Enable CPFD/CAPD support" + default y + depends on BT_NIMBLE_ENABLED + help + Enable CPFD and CAPD gatt descriptors support + + config BT_NIMBLE_RECONFIG_MTU + bool "Reconfig L2CAP MTU support" + default y + depends on BT_NIMBLE_ENABLED + help + Enable Support to reconfigure L2CAP MTU / MPS + + config BT_NIMBLE_LOW_SPEED_MODE + bool "Reduce DRAM/IRAM usage by moving GATT/GAP/NPL functions to FLASH" + default n + help + Disabling IRAM-optimized paths will place functions in FLASH (.irom.text) + instead of DRAM (.iram.text/.text in internal RAM). Suitable for low-speed + GAP/GATT operations to reduce RAM usage. + endmenu menu "NimBLE Mesh" @@ -1475,6 +1534,16 @@ menu "Host-controller Transport" endmenu #Transport menu "Debugging/Testing" + config BT_NIMBLE_MEM_DEBUG + bool "NimBLE memory debug" + depends on BT_NIMBLE_ENABLED && !BT_NIMBLE_ISO + default n + help + Enable NimBLE memory debug to track memory allocations and deallocations. + This feature records the function name, line number, and size of each allocation, + and provides APIs to display memory usage statistics, find memory leaks, and + monitor peak memory usage. + choice BT_NIMBLE_LOG_LEVEL prompt "NimBLE Host log verbosity" depends on BT_NIMBLE_ENABLED @@ -1553,3 +1622,28 @@ menu "Vendor / Optimization" help This enable BLE high duty advertising interval feature endmenu #Vendor + +menu "Helper Utils" + config BT_NIMBLE_CHK_HOST_STATUS + bool "Enable host status query support" + default y + depends on BT_NIMBLE_ENABLED + help + Enable support to query host status + + config BT_NIMBLE_UTIL_API + bool "Enable helper APIs" + default y + depends on BT_NIMBLE_ENABLED + help + Enable support for misc APIs like set data addr change, read local resolv addr + and set host feature + + config BT_NIMBLE_EXTRA_ADV_FIELDS + bool "Enable extra Adv report fields parsing" + default y + depends on BT_NIMBLE_ENABLED + help + Enable support for parsing of more adv fields as per spec + +endmenu diff --git a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c index aeacc4cbb1..4ce220882e 100644 --- a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c +++ b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c @@ -38,8 +38,10 @@ static ble_hci_trans_rx_cmd_fn *ble_hci_rx_cmd_hs_cb; static void *ble_hci_rx_cmd_hs_arg; +#if NIMBLE_BLE_CONNECT static ble_hci_trans_rx_acl_fn *ble_hci_rx_acl_hs_cb; static void *ble_hci_rx_acl_hs_arg; +#endif /* * The MBUF payload size must accommodate the HCI data header size plus the @@ -57,8 +59,9 @@ const static char *TAG = "NimBLE"; int os_msys_buf_alloc(void); void os_msys_buf_free(void); +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) extern uint8_t ble_hs_enabled_state; - +#endif void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb, void *cmd_arg, ble_hci_trans_rx_acl_fn *acl_cb, @@ -66,8 +69,10 @@ void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb, { ble_hci_rx_cmd_hs_cb = cmd_cb; ble_hci_rx_cmd_hs_arg = cmd_arg; +#if NIMBLE_BLE_CONNECT ble_hci_rx_acl_hs_cb = acl_cb; ble_hci_rx_acl_hs_arg = acl_arg; +#endif } void esp_vhci_host_send_packet_wrapper(uint8_t *data, uint16_t len) @@ -118,6 +123,7 @@ int ble_hci_trans_ll_evt_tx(uint8_t *hci_ev) return rc; } +#if NIMBLE_BLE_CONNECT int ble_hci_trans_hs_acl_tx(struct os_mbuf *om) { uint16_t len = 0; @@ -147,6 +153,7 @@ int ble_hci_trans_hs_acl_tx(struct os_mbuf *om) return rc; } +#endif int ble_hci_trans_ll_acl_tx(struct os_mbuf *om) { @@ -166,7 +173,7 @@ int ble_hci_trans_reset(void) return 0; } - +#if NIMBLE_BLE_CONNECT static void ble_hci_rx_acl(uint8_t *data, uint16_t len) { struct os_mbuf *m = NULL; @@ -209,6 +216,7 @@ static void ble_hci_rx_acl(uint8_t *data, uint16_t len) ble_transport_to_hs_acl(m); OS_EXIT_CRITICAL(sr); } +#endif /* * @brief: BT controller callback function, used to notify the upper layer that @@ -264,7 +272,11 @@ static int host_rcv_pkt(uint8_t *data, uint16_t len) bt_record_hci_data(data, len); - if(!ble_hs_enabled_state) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (!ble_hs_get_enabled_state()) { +#else + if (!ble_hs_enabled_state) { +#endif /* If host is not enabled, drop the packet */ esp_rom_printf("Host not enabled. Dropping the packet!"); return 0; @@ -308,7 +320,9 @@ static int host_rcv_pkt(uint8_t *data, uint16_t len) rc = ble_hci_trans_ll_evt_tx(evbuf); assert(rc == 0); } else if (data[0] == BLE_HCI_UART_H4_ACL) { +#if NIMBLE_BLE_CONNECT ble_hci_rx_acl(data + 1, len - 1); +#endif } return 0; } diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 450d35aae0..e2f8239def 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 450d35aae01161d271c6eb2cddc6444519baee67 +Subproject commit e2f8239def9fc39b03dd5c719f6c794b1d675c23 diff --git a/components/bt/host/nimble/port/include/esp_nimble_cfg.h b/components/bt/host/nimble/port/include/esp_nimble_cfg.h index 4fad474a43..8155a2a6d0 100644 --- a/components/bt/host/nimble/port/include/esp_nimble_cfg.h +++ b/components/bt/host/nimble/port/include/esp_nimble_cfg.h @@ -125,10 +125,12 @@ #define BLE_SCAN_RSP_DATA_MAX_LEN_N (MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE) #endif -#ifndef CONFIG_BT_NIMBLE_MAX_PERIODIC_SYNCS -#define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (0) -#else +#ifndef MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS +#ifdef CONFIG_BT_NIMBLE_MAX_PERIODIC_SYNCS #define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (CONFIG_BT_NIMBLE_MAX_PERIODIC_SYNCS) +#else +#define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (0) +#endif #endif #ifndef CONFIG_BT_NIMBLE_MAX_PERIODIC_ADVERTISER_LIST @@ -279,6 +281,7 @@ #else #define MYNEWT_VAL_BLE_CONN_SUBRATING (CONFIG_BT_NIMBLE_SUBRATE) #endif + #ifndef CONFIG_BT_NIMBLE_PERIODIC_ADV_ENH #define MYNEWT_VAL_BLE_PERIODIC_ADV_ENH (0) #else @@ -951,13 +954,31 @@ #endif #if CONFIG_IDF_TARGET_ESP32 + +#define MYNEWT_VAL_BLE_HS_PVCY (1) #define MYNEWT_VAL_BLE_HOST_BASED_PRIVACY (1) + #else + #ifndef MYNEWT_VAL_BLE_HOST_BASED_PRIVACY +#if CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY #define MYNEWT_VAL_BLE_HOST_BASED_PRIVACY (CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY) +#else +#define MYNEWT_VAL_BLE_HOST_BASED_PRIVACY (0) #endif #endif +#ifndef MYNEWT_VAL_BLE_HS_PVCY +#ifdef CONFIG_BT_NIMBLE_HS_PVCY +#define MYNEWT_VAL_BLE_HS_PVCY CONFIG_BT_NIMBLE_HS_PVCY +#else +#define MYNEWT_VAL_BLE_HS_PVCY (0) +#endif +#endif + + +#endif + #ifndef MYNEWT_VAL_BLE_RPA_TIMEOUT #define MYNEWT_VAL_BLE_RPA_TIMEOUT (CONFIG_BT_NIMBLE_RPA_TIMEOUT) #endif @@ -1040,15 +1061,27 @@ #endif #ifndef MYNEWT_VAL_BLE_STORE_MAX_BONDS +#ifdef CONFIG_BT_NIMBLE_MAX_BONDS #define MYNEWT_VAL_BLE_STORE_MAX_BONDS CONFIG_BT_NIMBLE_MAX_BONDS +#else +#define MYNEWT_VAL_BLE_STORE_MAX_BONDS (0) +#endif #endif #ifndef MYNEWT_VAL_BLE_STORE_MAX_CCCDS +#ifdef CONFIG_BT_NIMBLE_MAX_CCCDS #define MYNEWT_VAL_BLE_STORE_MAX_CCCDS CONFIG_BT_NIMBLE_MAX_CCCDS +#else +#define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (0) +#endif #endif #ifndef MYNEWT_VAL_BLE_STORE_MAX_CSFCS +#ifdef CONFIG_BT_NIMBLE_MAX_BONDS #define MYNEWT_VAL_BLE_STORE_MAX_CSFCS CONFIG_BT_NIMBLE_MAX_BONDS +#else +#define MYNEWT_VAL_BLE_STORE_MAX_CSFCS (0) +#endif #endif #ifdef CONFIG_BT_NIMBLE_MAX_EADS @@ -2186,11 +2219,11 @@ #endif #endif -#ifndef MYNEWT_VAL_BLE_ERR_CHECK -#ifdef CONFIG_BT_NIMBLE_PRINT_ERR_NAME -#define MYNEWT_VAL_BLE_ERR_CHECK CONFIG_BT_NIMBLE_PRINT_ERR_NAME +#ifndef MYNEWT_VAL_BT_NIMBLE_MEM_OPTIMIZATION +#ifdef CONFIG_BT_NIMBLE_MEM_OPTIMIZATION +#define MYNEWT_VAL_BT_NIMBLE_MEM_OPTIMIZATION CONFIG_BT_NIMBLE_MEM_OPTIMIZATION #else -#define MYNEWT_VAL_BLE_ERR_CHECK (0) +#define MYNEWT_VAL_BT_NIMBLE_MEM_OPTIMIZATION (0) #endif #endif @@ -2214,6 +2247,91 @@ #endif #endif +#ifndef MYNEWT_VAL_BLE_DTM_MODE_TEST +#ifdef CONFIG_BT_NIMBLE_DTM_MODE_TEST +#define MYNEWT_VAL_BLE_DTM_MODE_TEST CONFIG_BT_NIMBLE_DTM_MODE_TEST +#else +#define MYNEWT_VAL_BLE_DTM_MODE_TEST (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_HOST_STATUS +#ifdef CONFIG_BT_NIMBLE_CHK_HOST_STATUS +#define MYNEWT_VAL_BLE_HOST_STATUS CONFIG_BT_NIMBLE_CHK_HOST_STATUS +#else +#define MYNEWT_VAL_BLE_HOST_STATUS (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_SM_SIGN_CNT +#ifdef CONFIG_BT_NIMBLE_SM_SIGN_CNT +#define MYNEWT_VAL_BLE_SM_SIGN_CNT CONFIG_BT_NIMBLE_SM_SIGN_CNT +#else +#define MYNEWT_VAL_BLE_SM_SIGN_CNT (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_CPFD_CAFD +#ifdef CONFIG_BT_NIMBLE_CPFD_CAFD +#define MYNEWT_VAL_BLE_CPFD_CAFD CONFIG_BT_NIMBLE_CPFD_CAFD +#else +#define MYNEWT_VAL_BLE_CPFD_CAFD (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_RECONFIG_MTU +#ifdef CONFIG_BT_NIMBLE_RECONFIG_MTU +#define MYNEWT_VAL_BLE_RECONFIG_MTU CONFIG_BT_NIMBLE_RECONFIG_MTU +#else +#define MYNEWT_VAL_BLE_RECONFIG_MTU (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_ERR_NAME +#ifdef CONFIG_BT_NIMBLE_PRINT_ERR_NAME +#define MYNEWT_VAL_BLE_ERR_NAME CONFIG_BT_NIMBLE_PRINT_ERR_NAME +#else +#define MYNEWT_VAL_BLE_ERR_NAME (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_UTIL_API +#ifdef CONFIG_BT_NIMBLE_UTIL_API +#define MYNEWT_VAL_BLE_UTIL_API CONFIG_BT_NIMBLE_UTIL_API +#else +#define MYNEWT_VAL_BLE_UTIL_API (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_EXTRA_ADV_FIELDS +#ifdef CONFIG_BT_NIMBLE_EXTRA_ADV_FIELDS +#define MYNEWT_VAL_BLE_EXTRA_ADV_FIELDS CONFIG_BT_NIMBLE_EXTRA_ADV_FIELDS +#else +#define CONFIG_BT_NIMBLE_EXTRA_ADV_FIELDS (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_LOW_SPEED_MODE +#ifdef CONFIG_BT_NIMBLE_LOW_SPEED_MODE +#define MYNEWT_VAL_BLE_LOW_SPEED_MODE CONFIG_BT_NIMBLE_LOW_SPEED_MODE +#else +#define MYNEWT_VAL_BLE_LOW_SPEED_MODE (0) +#endif +#endif + + +#ifndef MYNEWT_VAL_BLE_STATIC_TO_DYNAMIC +#ifdef CONFIG_BT_NIMBLE_STATIC_TO_DYNAMIC +#define MYNEWT_VAL_BLE_STATIC_TO_DYNAMIC CONFIG_BT_NIMBLE_STATIC_TO_DYNAMIC +#else +#define MYNEWT_VAL_BLE_STATIC_TO_DYNAMIC (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_RESTART_PAIR +#define MYNEWT_VAL_BLE_RESTART_PAIR (1) +#endif + #ifndef MYNEWT_VAL_MP_RUNTIME_ALLOC #ifdef CONFIG_BT_NIMBLE_MEMPOOL_RUNTIME_ALLOC #define MYNEWT_VAL_MP_RUNTIME_ALLOC (1) diff --git a/components/bt/host/nimble/port/include/esp_nimble_mem.h b/components/bt/host/nimble/port/include/esp_nimble_mem.h index 0b5e5aae74..d0c5a75185 100644 --- a/components/bt/host/nimble/port/include/esp_nimble_mem.h +++ b/components/bt/host/nimble/port/include/esp_nimble_mem.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,10 +16,55 @@ extern "C" { // #pragma message "This file should be replaced with bt_osi_mem.h, used here for compatibility" #include "bt_osi_mem.h" + +#if CONFIG_BT_NIMBLE_MEM_DEBUG + +#define nimble_platform_mem_malloc(size) \ +({ \ + void *p; \ + do { \ + p = bt_osi_mem_malloc(size); \ + nimble_mem_dbg_record(p, size, __func__, __LINE__); \ + } while (0); \ + p; \ +}) + +#define nimble_platform_mem_calloc(count, size) \ +({ \ + void *p; \ + do { \ + p = bt_osi_mem_calloc(count, size); \ + nimble_mem_dbg_record(p, (count) * (size), __func__, __LINE__); \ + } while (0); \ + p; \ +}) + +#define nimble_platform_mem_realloc(ptr, new_size) \ +({ \ + void *p; \ + do { \ + p = nimble_mem_dbg_realloc(ptr, new_size, __func__, __LINE__); \ + } while (0); \ + p; \ +}) + +#define nimble_platform_mem_free(ptr) \ +do { \ + void *tmp_ptr = (void *)(ptr); \ + nimble_mem_dbg_clean(tmp_ptr, __func__, __LINE__); \ + bt_osi_mem_free(tmp_ptr); \ +} while (0) + +#else + #define nimble_platform_mem_malloc bt_osi_mem_malloc #define nimble_platform_mem_calloc bt_osi_mem_calloc +#define nimble_platform_mem_realloc realloc #define nimble_platform_mem_free bt_osi_mem_free +#endif // CONFIG_BT_NIMBLE_MEM_DEBUG + + #ifdef __cplusplus } #endif diff --git a/components/bt/porting/include/bt_osi_mem.h b/components/bt/porting/include/bt_osi_mem.h index a97165d707..8a8c448b1d 100644 --- a/components/bt/porting/include/bt_osi_mem.h +++ b/components/bt/porting/include/bt_osi_mem.h @@ -29,3 +29,82 @@ void bt_osi_mem_count_limit_set(uint16_t count_limit); size_t bt_osi_mem_internal_used_size_get(void); size_t bt_osi_mem_used_size_get(void); #endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + +#if CONFIG_BT_NIMBLE_MEM_DEBUG +/** + * @brief Initialize NimBLE memory debug module + */ +void nimble_mem_dbg_init(void); + +/** + * @brief Record memory allocation information + * + * @param p Pointer to allocated memory + * @param size Size of allocation + * @param func Function name where allocation occurred + * @param line Line number where allocation occurred + */ +void nimble_mem_dbg_record(void *p, int size, const char *func, int line); + +/** + * @brief Clean up memory allocation record + * + * @param p Pointer to memory being freed + * @param func Function name where free occurred + * @param line Line number where free occurred + */ +void nimble_mem_dbg_clean(void *p, const char *func, int line); + +/** + * @brief Display all memory debug information + */ +void nimble_mem_dbg_show(void); + +/** + * @brief Get maximum memory size used + * + * @return Maximum memory size in bytes + */ +uint32_t nimble_mem_dbg_get_max_size(void); + +/** + * @brief Get current memory size in use + * + * @return Current memory size in bytes + */ +uint32_t nimble_mem_dbg_get_current_size(void); + +/** + * @brief Start tracking memory usage for a specific section + * + * @param index Section index (0 to NIMBLE_MEM_DBG_MAX_SECTION_NUM-1) + */ +void nimble_mem_dbg_set_section_start(uint8_t index); + +/** + * @brief Stop tracking memory usage for a specific section + * + * @param index Section index (0 to NIMBLE_MEM_DBG_MAX_SECTION_NUM-1) + */ +void nimble_mem_dbg_set_section_end(uint8_t index); + +/** + * @brief Get maximum memory size used in a specific section + * + * @param index Section index (0 to NIMBLE_MEM_DBG_MAX_SECTION_NUM-1) + * @return Maximum memory size in bytes for this section + */ +uint32_t nimble_mem_dbg_get_max_size_section(uint8_t index); + +/** + * @brief Reallocate memory with debug tracking + * + * @param ptr Pointer to memory to reallocate + * @param new_size New size of allocation + * @param func Function name where realloc occurred + * @param line Line number where realloc occurred + * @return Pointer to reallocated memory + */ +void *nimble_mem_dbg_realloc(void *ptr, size_t new_size, const char *func, int line); + +#endif // CONFIG_BT_NIMBLE_MEM_DEBUG diff --git a/components/bt/porting/mem/bt_osi_mem.c b/components/bt/porting/mem/bt_osi_mem.c index 306ec8290e..e020abbf77 100644 --- a/components/bt/porting/mem/bt_osi_mem.c +++ b/components/bt/porting/mem/bt_osi_mem.c @@ -19,7 +19,248 @@ static size_t host_mem_used_size = 0; static uint16_t mem_count_limit = 0; static uint16_t curr_mem_count; #endif // CONFIG_BT_LE_MEM_CHECK_ENABLED -IRAM_ATTR void *bt_osi_mem_malloc(size_t size) + +#if CONFIG_BT_NIMBLE_MEM_DEBUG + +#define NIMBLE_MEM_DBG_INFO_MAX 1024*3 +typedef struct { + void *p; + int size; + const char *func; + int line; +} nimble_mem_dbg_info_t; + +static uint32_t nimble_mem_dbg_count = 0; +static nimble_mem_dbg_info_t nimble_mem_dbg_info[NIMBLE_MEM_DBG_INFO_MAX]; +static uint32_t nimble_mem_dbg_current_size = 0; +static uint32_t nimble_mem_dbg_max_size = 0; + +#define NIMBLE_MEM_DBG_MAX_SECTION_NUM 5 +typedef struct { + bool used; + uint32_t max_size; +} nimble_mem_dbg_max_size_section_t; +static nimble_mem_dbg_max_size_section_t nimble_mem_dbg_max_size_section[NIMBLE_MEM_DBG_MAX_SECTION_NUM]; + +void nimble_mem_dbg_init(void) +{ + int i; + + for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) { + nimble_mem_dbg_info[i].p = NULL; + nimble_mem_dbg_info[i].size = 0; + nimble_mem_dbg_info[i].func = NULL; + nimble_mem_dbg_info[i].line = 0; + } + nimble_mem_dbg_count = 0; + nimble_mem_dbg_current_size = 0; + nimble_mem_dbg_max_size = 0; + + for (i = 0; i < NIMBLE_MEM_DBG_MAX_SECTION_NUM; i++){ + nimble_mem_dbg_max_size_section[i].used = false; + nimble_mem_dbg_max_size_section[i].max_size = 0; + } +} + +void nimble_mem_dbg_record(void *p, int size, const char *func, int line) +{ + int i; + + if (!p || size == 0) { + ESP_LOGE("BT_NIMBLE_MEM", "%s invalid !!\n", __func__); + return; + } + + for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) { + if (nimble_mem_dbg_info[i].p == NULL) { + nimble_mem_dbg_info[i].p = p; + nimble_mem_dbg_info[i].size = size; + nimble_mem_dbg_info[i].func = func; + nimble_mem_dbg_info[i].line = line; + nimble_mem_dbg_count++; + break; + } + } + + if (i >= NIMBLE_MEM_DBG_INFO_MAX) { + ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line); + } + + nimble_mem_dbg_current_size += size; + if(nimble_mem_dbg_max_size < nimble_mem_dbg_current_size) { + nimble_mem_dbg_max_size = nimble_mem_dbg_current_size; + } + + for (i = 0; i < NIMBLE_MEM_DBG_MAX_SECTION_NUM; i++){ + if (nimble_mem_dbg_max_size_section[i].used) { + if(nimble_mem_dbg_max_size_section[i].max_size < nimble_mem_dbg_current_size) { + nimble_mem_dbg_max_size_section[i].max_size = nimble_mem_dbg_current_size; + } + } + } +} + +void nimble_mem_dbg_clean(void *p, const char *func, int line) +{ + int i; + + if (!p) { + ESP_LOGE("BT_NIMBLE_MEM", "%s %d free->%p invalid\n", func, line, p); + return; + } + + for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) { + if (nimble_mem_dbg_info[i].p == p) { + nimble_mem_dbg_current_size -= nimble_mem_dbg_info[i].size; + nimble_mem_dbg_info[i].p = NULL; + nimble_mem_dbg_info[i].size = 0; + nimble_mem_dbg_info[i].func = NULL; + nimble_mem_dbg_info[i].line = 0; + nimble_mem_dbg_count--; + break; + } + } + + if (i >= NIMBLE_MEM_DBG_INFO_MAX) { + ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line); + } +} + +void nimble_mem_dbg_show(void) +{ + int i; + + for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) { + if (nimble_mem_dbg_info[i].p || nimble_mem_dbg_info[i].size != 0 ) { + ESP_LOGE("BT_NIMBLE_MEM", "--> p %p, s %d, f %s, l %d\n", + nimble_mem_dbg_info[i].p, nimble_mem_dbg_info[i].size, + nimble_mem_dbg_info[i].func, nimble_mem_dbg_info[i].line); + } + } + ESP_LOGE("BT_NIMBLE_MEM", "--> count %ld\n", nimble_mem_dbg_count); + ESP_LOGE("BT_NIMBLE_MEM", "--> size %ldB\n--> max size %ldB\n", + nimble_mem_dbg_current_size, nimble_mem_dbg_max_size); +} + +uint32_t nimble_mem_dbg_get_max_size(void) +{ + return nimble_mem_dbg_max_size; +} + +uint32_t nimble_mem_dbg_get_current_size(void) +{ + return nimble_mem_dbg_current_size; +} + +void nimble_mem_dbg_set_section_start(uint8_t index) +{ + if (index >= NIMBLE_MEM_DBG_MAX_SECTION_NUM) { + ESP_LOGE("BT_NIMBLE_MEM", "Then range of index should be between 0 and %d, current index is %d.\n", + NIMBLE_MEM_DBG_MAX_SECTION_NUM - 1, index); + return; + } + + if (nimble_mem_dbg_max_size_section[index].used) { + ESP_LOGW("BT_NIMBLE_MEM", "This index(%d) has been started, restart it.\n", index); + } + + nimble_mem_dbg_max_size_section[index].used = true; + nimble_mem_dbg_max_size_section[index].max_size = nimble_mem_dbg_current_size; +} + +void nimble_mem_dbg_set_section_end(uint8_t index) +{ + if (index >= NIMBLE_MEM_DBG_MAX_SECTION_NUM) { + ESP_LOGE("BT_NIMBLE_MEM", "Then range of index should be between 0 and %d, current index is %d.\n", + NIMBLE_MEM_DBG_MAX_SECTION_NUM - 1, index); + return; + } + + if (!nimble_mem_dbg_max_size_section[index].used) { + ESP_LOGE("BT_NIMBLE_MEM", "This index(%d) has not been started.\n", index); + return; + } + + nimble_mem_dbg_max_size_section[index].used = false; +} + +uint32_t nimble_mem_dbg_get_max_size_section(uint8_t index) +{ + if (index >= NIMBLE_MEM_DBG_MAX_SECTION_NUM){ + ESP_LOGE("BT_NIMBLE_MEM", "Then range of index should be between 0 and %d, current index is %d.\n", + NIMBLE_MEM_DBG_MAX_SECTION_NUM - 1, index); + return 0; + } + + return nimble_mem_dbg_max_size_section[index].max_size; +} + +void *nimble_mem_dbg_realloc(void *ptr, size_t new_size, const char *func, int line) +{ + size_t old_size = 0; + int i; + + void *new_ptr = realloc(ptr, new_size); + if (new_ptr == NULL && new_size > 0) { + // realloc failed, keep old ptr record + return NULL; + } + + // Find and clean old record if ptr is not NULL + if (ptr != NULL) { + for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) { + if (nimble_mem_dbg_info[i].p == ptr) { + old_size = nimble_mem_dbg_info[i].size; + nimble_mem_dbg_current_size -= old_size; + + nimble_mem_dbg_info[i].p = NULL; + nimble_mem_dbg_info[i].size = 0; + nimble_mem_dbg_info[i].func = NULL; + nimble_mem_dbg_info[i].line = 0; + nimble_mem_dbg_count--; + break; + } + } + } + + // Record the new allocation if new_size > 0 + if (new_ptr != NULL && new_size > 0) { + for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) { + if (nimble_mem_dbg_info[i].p == NULL) { + nimble_mem_dbg_info[i].p = new_ptr; + nimble_mem_dbg_info[i].size = new_size; + nimble_mem_dbg_info[i].func = func; + nimble_mem_dbg_info[i].line = line; + nimble_mem_dbg_count++; + break; + } + } + + if (i >= NIMBLE_MEM_DBG_INFO_MAX) { + ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line); + } + + nimble_mem_dbg_current_size += new_size; + if (nimble_mem_dbg_max_size < nimble_mem_dbg_current_size) { + nimble_mem_dbg_max_size = nimble_mem_dbg_current_size; + } + + for (i = 0; i < NIMBLE_MEM_DBG_MAX_SECTION_NUM; i++) { + if (nimble_mem_dbg_max_size_section[i].used && + nimble_mem_dbg_max_size_section[i].max_size < nimble_mem_dbg_current_size) { + nimble_mem_dbg_max_size_section[i].max_size = nimble_mem_dbg_current_size; + } + } + } + + return new_ptr; +} +#endif // CONFIG_BT_NIMBLE_MEM_DEBUG + +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void *bt_osi_mem_malloc(size_t size) { void *mem = NULL; #ifdef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL @@ -47,7 +288,10 @@ IRAM_ATTR void *bt_osi_mem_malloc(size_t size) return mem; } -IRAM_ATTR void *bt_osi_mem_calloc(size_t n, size_t size) +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void *bt_osi_mem_calloc(size_t n, size_t size) { void *mem = NULL; #ifdef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL @@ -67,7 +311,10 @@ IRAM_ATTR void *bt_osi_mem_calloc(size_t n, size_t size) return mem; } -IRAM_ATTR void *bt_osi_mem_malloc_internal(size_t size) +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void *bt_osi_mem_malloc_internal(size_t size) { void *mem_ptr; #if CONFIG_BT_LE_MEM_CHECK_ENABLED @@ -87,7 +334,10 @@ IRAM_ATTR void *bt_osi_mem_malloc_internal(size_t size) return mem_ptr; } -IRAM_ATTR void *bt_osi_mem_calloc_internal(size_t n, size_t size) +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void *bt_osi_mem_calloc_internal(size_t n, size_t size) { void *mem_ptr; #if CONFIG_BT_LE_MEM_CHECK_ENABLED @@ -107,7 +357,10 @@ IRAM_ATTR void *bt_osi_mem_calloc_internal(size_t n, size_t size) return mem_ptr; } -IRAM_ATTR void bt_osi_mem_free_internal(void *ptr) +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void bt_osi_mem_free_internal(void *ptr) { #if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED if (ptr) { @@ -116,10 +369,15 @@ IRAM_ATTR void bt_osi_mem_free_internal(void *ptr) controller_mem_used_size -= alloc_size; } #endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED - heap_caps_free(ptr); + if (ptr) { + heap_caps_free(ptr); + } } -IRAM_ATTR void bt_osi_mem_free(void *ptr) +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void bt_osi_mem_free(void *ptr) { #if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED if (ptr) { @@ -128,7 +386,9 @@ IRAM_ATTR void bt_osi_mem_free(void *ptr) host_mem_used_size -= alloc_size; } #endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED - heap_caps_free(ptr); + if (ptr) { + heap_caps_free(ptr); + } } #if CONFIG_BT_LE_MEM_CHECK_ENABLED diff --git a/components/bt/porting/mem/os_msys_init.c b/components/bt/porting/mem/os_msys_init.c index 1a121e6d0b..b0340f42cf 100644 --- a/components/bt/porting/mem/os_msys_init.c +++ b/components/bt/porting/mem/os_msys_init.c @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2019-2025 Espressif Systems (Shanghai) CO LTD */ #include @@ -12,6 +12,7 @@ #include "mem_api.h" #include "bt_osi_mem.h" #include "esp_err.h" +#include "esp_nimble_mem.h" #if CONFIG_BT_NIMBLE_ENABLED #include "syscfg/syscfg.h" @@ -168,17 +169,17 @@ int os_msys_buf_alloc(void) { #if OS_MSYS_1_BLOCK_COUNT > 0 - os_msys_init_1_data = (os_membuf_t *)bt_osi_mem_calloc(1, (sizeof(os_membuf_t) * SYSINIT_MSYS_1_MEMPOOL_SIZE)); + os_msys_init_1_data = (os_membuf_t *)nimble_platform_mem_calloc(1, (sizeof(os_membuf_t) * SYSINIT_MSYS_1_MEMPOOL_SIZE)); if (!os_msys_init_1_data) { return ESP_ERR_NO_MEM; } #endif #if OS_MSYS_2_BLOCK_COUNT > 0 - os_msys_init_2_data = (os_membuf_t *)bt_osi_mem_calloc(1, (sizeof(os_membuf_t) * SYSINIT_MSYS_2_MEMPOOL_SIZE)); + os_msys_init_2_data = (os_membuf_t *)nimble_platform_mem_calloc(1, (sizeof(os_membuf_t) * SYSINIT_MSYS_2_MEMPOOL_SIZE)); if (!os_msys_init_2_data) { #if OS_MSYS_1_BLOCK_COUNT > 0 - bt_osi_mem_free(os_msys_init_1_data); + nimble_platform_mem_free(os_msys_init_1_data); os_msys_init_1_data = NULL; #endif return ESP_ERR_NO_MEM; @@ -192,12 +193,12 @@ void os_msys_buf_free(void) { #if OS_MSYS_1_BLOCK_COUNT > 0 - bt_osi_mem_free(os_msys_init_1_data); + nimble_platform_mem_free(os_msys_init_1_data); os_msys_init_1_data = NULL; #endif #if OS_MSYS_2_BLOCK_COUNT > 0 - bt_osi_mem_free(os_msys_init_2_data); + nimble_platform_mem_free(os_msys_init_2_data); os_msys_init_2_data = NULL; #endif diff --git a/components/bt/porting/npl/freertos/src/npl_os_freertos.c b/components/bt/porting/npl/freertos/src/npl_os_freertos.c index 4103e62042..1e98cf8933 100644 --- a/components/bt/porting/npl/freertos/src/npl_os_freertos.c +++ b/components/bt/porting/npl/freertos/src/npl_os_freertos.c @@ -165,6 +165,13 @@ npl_freertos_eventq_deinit(struct ble_npl_eventq *evq) { struct ble_npl_eventq_freertos *eventq = (struct ble_npl_eventq_freertos *)evq->eventq; +#if CONFIG_BT_NIMBLE_STATIC_TO_DYNAMIC + /* Deinit can be invoked twice without init . Handle this case */ + if (eventq == NULL) { + return; + } +#endif + BLE_LL_ASSERT(eventq); vQueueDelete(eventq->q); #if OS_MEM_ALLOC diff --git a/components/bt/porting/transport/src/hci_transport.c b/components/bt/porting/transport/src/hci_transport.c index 29c2e00131..9d2e0a1204 100644 --- a/components/bt/porting/transport/src/hci_transport.c +++ b/components/bt/porting/transport/src/hci_transport.c @@ -26,9 +26,11 @@ hci_transport_controller_packet_rx(hci_driver_data_type_t data_type, uint8_t *da r_ble_hci_trans_hs_cmd_tx(data); } +#if CONFIG_BT_BLUEDROID_ENABLED || (CONFIG_BT_NIMBLE_ENABLED && (CONFIG_BT_NIMBLE_ROLE_CENTRAL || CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)) if (data_type == HCI_DRIVER_TYPE_ACL) { r_ble_hci_trans_hs_acl_tx((struct os_mbuf *) data); } +#endif return 0; }