Merge branch 'dev/ble-log-202603_v6.0' into 'release/v6.0'

dev: BLE Log 202603 (6.0)

See merge request espressif/esp-idf!47277
This commit is contained in:
Island
2026-04-28 13:25:12 +08:00
83 changed files with 7376 additions and 2168 deletions
+12 -14
View File
@@ -25,6 +25,7 @@ set(common_include_dirs
common/btc/profile/esp/include
common/hci_log/include
common/ble_log/include
common/ble_log/deprecated/include
)
set(ble_mesh_include_dirs
@@ -133,8 +134,7 @@ if(CONFIG_BT_ENABLED)
"common/osi/osi.c"
"common/osi/semaphore.c"
"porting/mem/bt_osi_mem.c"
"common/ble_log/ble_log_spi_out.c"
"common/ble_log/ble_log_uhci_out.c"
"common/ble_log/deprecated/ble_log_spi_out.c"
)
# BLE Log Module
@@ -1021,6 +1021,16 @@ idf_component_register(SRCS "${srcs}"
PRIV_REQUIRES "${bt_priv_requires}"
LDFRAGMENTS "${ldscripts}")
# UART redir wrap flags — needed whenever BLE Log uses UART DMA on port 0,
# regardless of whether BLE controller is enabled.
if(DEFINED CONFIG_BLE_LOG_PRPH_UART_DMA_PORT)
if(CONFIG_BLE_LOG_PRPH_UART_DMA_PORT EQUAL 0)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=uart_tx_chars")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=uart_write_bytes")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=uart_write_bytes_with_break")
endif()
endif()
if(CONFIG_BLE_COMPRESSED_LOG_ENABLE)
if(LOG_COMPRESSION_TARGET)
add_dependencies(${COMPONENT_LIB} ${LOG_COMPRESSION_TARGET})
@@ -1055,18 +1065,6 @@ if(CONFIG_BT_ENABLED)
if(CONFIG_BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE)
target_link_options(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=esp_panic_handler")
endif()
if(CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=uart_tx_chars")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=uart_write_bytes")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=uart_write_bytes_with_break")
endif()
if(DEFINED CONFIG_BLE_LOG_PRPH_UART_DMA_PORT)
if(CONFIG_BLE_LOG_PRPH_UART_DMA_PORT EQUAL 0)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=uart_tx_chars")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=uart_write_bytes")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=uart_write_bytes_with_break")
endif()
endif()
if(CONFIG_IDF_TARGET_ESP32C6)
add_prebuilt_library(libble_app
"${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c6/esp32c6-bt-lib/esp32c6/libble_app.a"
+165 -247
View File
@@ -35,256 +35,174 @@ choice BT_SMP_CRYPTO_STACK
endchoice
menu "BLE Log"
menu "BT Logs"
menu "Log Sources"
menuconfig BT_LE_CONTROLLER_LOG_ENABLED
depends on SOC_ESP_NIMBLE_CONTROLLER
bool "Enable Controller logs"
default n
choice BT_LE_CONTROLLER_LOG_OUTPUT_MODE
depends on BT_LE_CONTROLLER_LOG_ENABLED
prompt "Controller log output mode"
default BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2 if BLE_LOG_ENABLED
default BT_LE_CTRL_LEGACY_LOG_MODE_ENABLED
config BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
depends on BLE_LOG_ENABLED
bool "BLE Log v2 mode"
help
Utilize BLE Log v2 for controller log
config BT_LE_CTRL_LEGACY_LOG_MODE_ENABLED
depends on !BLE_LOG_ENABLED
bool "Legacy log mode (Deprecated)"
endchoice
if BT_LE_CONTROLLER_LOG_ENABLED && BT_LE_CTRL_LEGACY_LOG_MODE_ENABLED
config BT_LE_CONTROLLER_LOG_CTRL_ENABLED
bool "Enable controller link layer logs"
default y
config BT_LE_CONTROLLER_LOG_HCI_ENABLED
bool "Enable controller HCI logs"
default y
config BT_LE_CONTROLLER_LOG_DUMP_ONLY
bool "Controller log dump mode only"
default y
help
Only operate in dump mode. Logs are cached internally only,
not output asynchronously.
config BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
bool "Output controller logs to SPI bus (Experimental)"
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
select BT_BLE_LOG_SPI_OUT_ENABLED
default n
help
Output ble controller logs to SPI bus
config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
bool "Store controller logs to flash (Experimental)"
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
default n
help
Store ble controller logs to flash memory.
config BT_LE_CONTROLLER_LOG_PARTITION_SIZE
int "Controller log partition size (multiples of 4K)"
depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
default 65536
help
The size of ble controller log partition shall be a multiples of 4K.
The name of log partition shall be "bt_ctrl_log".
The partition type shall be ESP_PARTITION_TYPE_DATA.
The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY.
config BT_LE_LOG_CTRL_BUF1_SIZE
int "First controller log buffer size"
default 4096
help
Configure the size of the first BLE controller LOG buffer.
config BT_LE_LOG_CTRL_BUF2_SIZE
int "Second controller log buffer size"
default 1024
help
Configure the size of the second BLE controller LOG buffer.
config BT_LE_LOG_HCI_BUF_SIZE
int "HCI log buffer size"
default 4096
help
Configure the size of the BLE HCI LOG buffer.
endif
config BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL
int "Controller log output level"
depends on BT_LE_CONTROLLER_LOG_ENABLED
range 0 5
default 2 if BT_LOG_CRITICAL_ONLY_CTRL
default 1
help
The output level of controller log.
config BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH
hex "Controller log module output switch"
depends on BT_LE_CONTROLLER_LOG_ENABLED
range 0 0xFFFFFFFF
default 0xFFFFFFFF
help
Bitmask to enable/disable logging for individual controller
modules. 0xFFFFFFFF enables all modules.
config BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE
bool "Enable wrap panic handler"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default n
help
Wrap esp_panic_handler to get controller logs when PC pointer exception crashes.
config BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE
bool "Enable esp_task_wdt_isr_user_handler implementation"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default n
help
Implement esp_task_wdt_isr_user_handler to get controller logs when task wdt issue is triggered.
endmenu
menuconfig BT_LOG_CRITICAL_ONLY
bool "Enable bandwidth-optimized log mode (critical logs only)"
default n
depends on !BT_STACK_NO_LOG
select BLE_LOG_ENABLED
select BLE_COMPRESSED_LOG_ENABLE
help
Enable bandwidth-optimized logging for the BLE Log Async Output
system. When enabled, only high-severity logs are captured and
log encoding is applied to reduce UART/SPI DMA bandwidth usage.
Each stack component below can be independently enabled.
Requires a DMA-backed output peripheral — configure in:
BLE Log Module → BLE Log peripheral choice.
if BT_LOG_CRITICAL_ONLY
config BT_LOG_CRITICAL_ONLY_CTRL
bool "Controller: bandwidth-optimized logging"
depends on SOC_ESP_NIMBLE_CONTROLLER || BT_CTRL_RUN_IN_FLASH_ONLY
select BT_LE_CONTROLLER_LOG_ENABLED if SOC_ESP_NIMBLE_CONTROLLER
select BT_CTRL_LE_LOG_EN if !SOC_ESP_NIMBLE_CONTROLLER
default y
help
Enable controller log output via the async transport with
a reduced output level for bandwidth optimization.
The controller log level defaults to 2 when active.
config BT_LOG_CRITICAL_ONLY_HOST
bool "Host: bandwidth-optimized logging"
select BLE_HOST_COMPRESSED_LOG_ENABLE if BT_BLUEDROID_ENABLED
default y
help
Enable host stack log encoding via the async transport.
For Bluedroid, the per-level compression options control
which severity levels are encoded — configure in:
Settings of BLE Log Compression → BLE Host log compression.
config BT_LOG_CRITICAL_ONLY_MESH
bool "Mesh: bandwidth-optimized logging"
depends on SOC_BLE_MESH_SUPPORTED && BLE_MESH
select BLE_MESH_COMPRESSED_LOG_ENABLE
default y
help
Enable mesh log encoding via the async transport.
The per-level compression options are configured in:
Settings of BLE Log Compression → BLE Mesh log compression.
endif # BT_LOG_CRITICAL_ONLY
source "$IDF_PATH/components/bt/common/ble_log/Kconfig.in"
endmenu
config BT_BLE_LOG_SPI_OUT_ENABLED
bool "Output ble logs to SPI bus (Experimental)"
default n
help
Output ble logs to SPI bus
config BT_BLE_LOG_SPI_OUT_UL_TASK_BUF_SIZE
int "SPI transaction buffer size for upper layer task logs"
depends on BT_BLE_LOG_SPI_OUT_ENABLED
default 512
help
SPI transaction buffer size for upper layer task logs.
There will be 2 SPI DMA buffers with the same size.
config BT_BLE_LOG_SPI_OUT_HCI_ENABLED
bool "Enable HCI log output to SPI"
depends on BT_BLE_LOG_SPI_OUT_ENABLED
default n
help
Enable logging of HCI packets to the SPI bus when BLE SPI log output is enabled.
config BT_BLE_LOG_SPI_OUT_HCI_BUF_SIZE
int "SPI transaction buffer size for HCI logs"
depends on BT_BLE_LOG_SPI_OUT_HCI_ENABLED
default 1024
help
SPI transaction buffer size for HCI logs.
There will be 2 SPI DMA buffers with the same size.
config BT_BLE_LOG_SPI_OUT_HCI_TASK_CNT
int "HCI task count"
depends on BT_BLE_LOG_SPI_OUT_HCI_ENABLED
default 1
help
HCI task count
config BT_BLE_LOG_SPI_OUT_HOST_ENABLED
bool "Enable Host log output to SPI"
depends on BT_BLE_LOG_SPI_OUT_ENABLED
default n
help
This configuration applies to the logs of both Bluedroid Host and NimBLE Host.
When BLE SPI log output is enabled, this option allows host logs to be transmitted via SPI.
config BT_BLE_LOG_SPI_OUT_HOST_BUF_SIZE
int "SPI transaction buffer size for host logs"
depends on BT_BLE_LOG_SPI_OUT_HOST_ENABLED
default 1024
help
SPI transaction buffer size for host logs.
There will be 2 SPI DMA buffers with the same size.
config BT_BLE_LOG_SPI_OUT_HOST_TASK_CNT
int "Host task count"
depends on BT_BLE_LOG_SPI_OUT_HOST_ENABLED
default 2
help
Host task count.
config BT_BLE_LOG_SPI_OUT_LL_ENABLED
bool "Enable Controller log output to SPI"
depends on BT_BLE_LOG_SPI_OUT_ENABLED
depends on BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
default n
help
Enable controller log output to SPI bus.
config BT_BLE_LOG_SPI_OUT_LL_TASK_BUF_SIZE
int "SPI transaction buffer size for lower layer task logs"
depends on BT_BLE_LOG_SPI_OUT_LL_ENABLED
default 1024
help
SPI transaction buffer size for lower layer task logs.
There will be 2 SPI DMA buffers with the same size.
config BT_BLE_LOG_SPI_OUT_LL_ISR_BUF_SIZE
int "SPI transaction buffer size for lower layer ISR logs"
depends on BT_BLE_LOG_SPI_OUT_LL_ENABLED
default 512
help
SPI transaction buffer size for lower layer ISR logs.
There will be 2 SPI DMA buffers with the same size.
config BT_BLE_LOG_SPI_OUT_LL_HCI_BUF_SIZE
int "SPI transaction buffer size for lower layer HCI logs"
depends on BT_BLE_LOG_SPI_OUT_LL_ENABLED
default 512
help
SPI transaction buffer size for upper layer HCI logs.
There will be 2 SPI DMA buffers with the same size
config BT_BLE_LOG_SPI_OUT_MOSI_IO_NUM
int "GPIO number of SPI MOSI"
depends on BT_BLE_LOG_SPI_OUT_ENABLED
default 0
help
GPIO number of SPI MOSI
config BT_BLE_LOG_SPI_OUT_SCLK_IO_NUM
int "GPIO number of SPI SCLK"
depends on BT_BLE_LOG_SPI_OUT_ENABLED
default 1
help
GPIO number of SPI SCLK
config BT_BLE_LOG_SPI_OUT_CS_IO_NUM
int "GPIO number of SPI CS"
depends on BT_BLE_LOG_SPI_OUT_ENABLED
default 2
help
GPIO number of SPI CS
config BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
bool "Enable ble log & logic analyzer log time sync"
depends on BT_BLE_LOG_SPI_OUT_ENABLED
default y
help
Enable ble log & logic analyzer log time sync
config BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM
int "GPIO number of SYNC IO"
depends on BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
default 3
help
GPIO number of SYNC IO
config BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
bool "Enable periodic buffer flush out"
depends on BT_BLE_LOG_SPI_OUT_ENABLED
default n
help
Enable periodic buffer flush out
Not recommended when SPI receiver is unavailable
config BT_BLE_LOG_SPI_OUT_FLUSH_TIMEOUT
int "Buffer flush out period in unit of ms"
depends on BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
default 1000
help
Buffer flush out period in unit of ms
config BT_BLE_LOG_SPI_OUT_LE_AUDIO_ENABLED
bool "Enable LE Audio log output to SPI"
depends on BT_BLE_LOG_SPI_OUT_ENABLED
default n
help
Enable LE Audio log output to SPI
config BT_BLE_LOG_SPI_OUT_LE_AUDIO_BUF_SIZE
int "SPI transaction buffer size for LE Audio logs"
depends on BT_BLE_LOG_SPI_OUT_LE_AUDIO_ENABLED
default 1024
help
SPI transaction buffer size for LE Audio logs.
There will be 2 SPI DMA buffers with the same size.
config BT_BLE_LOG_SPI_OUT_LE_AUDIO_TASK_CNT
int "LE audio task count"
depends on BT_BLE_LOG_SPI_OUT_LE_AUDIO_ENABLED
default 1
help
LE audio task count
config BT_BLE_LOG_SPI_OUT_MESH_ENABLED
bool "Enable BLE mesh log output to SPI"
depends on BT_BLE_LOG_SPI_OUT_ENABLED
default n
help
Enable BLE mesh log output to SPI
config BT_BLE_LOG_SPI_OUT_MESH_BUF_SIZE
int "SPI transaction buffer size for BLE mesh logs"
depends on BT_BLE_LOG_SPI_OUT_MESH_ENABLED
default 1024
help
SPI transaction buffer size for BLE mesh logs.
There will be 2 SPI DMA buffers with the same size.
config BT_BLE_LOG_SPI_OUT_MESH_TASK_CNT
int "Mesh task count"
depends on BT_BLE_LOG_SPI_OUT_MESH_ENABLED
default 3
help
Mesh task count
config BT_BLE_LOG_UHCI_OUT_ENABLED
bool "Output ble logs via UHCI (UART DMA) driver (Experimental)"
default n
help
Output ble logs via UHCI (UART DMA) driver
On enable, BT_BLE_LOG_UHCI_OUT_UART_PORT would be reinited with
BT_BLE_LOG_UHCI_OUT_UART_BAUD_RATE as new baud rate and
BT_BLE_LOG_UHCI_OUT_UART_IO_NUM_TX as new UART Tx IO
config BT_BLE_LOG_UHCI_OUT_UART_PORT
int "UART port connected to UHCI controller"
depends on BT_BLE_LOG_UHCI_OUT_ENABLED
default 0
help
UART port connected to UHCI controller
If UART port 0 is selected, UART VFS Driver, UART ROM Driver
and UART Driver output would be redirected to BLE Log UHCI Out
to solve UART Tx FIFO multi-task access issue
config BT_BLE_LOG_UHCI_OUT_LL_TASK_BUF_SIZE
int "UHCI transaction buffer size for lower layer task logs"
depends on BT_BLE_LOG_UHCI_OUT_ENABLED
default 1024
help
UHCI transaction buffer size for lower layer task logs
config BT_BLE_LOG_UHCI_OUT_LL_ISR_BUF_SIZE
int "UHCI transaction buffer size for lower layer ISR logs"
depends on BT_BLE_LOG_UHCI_OUT_ENABLED
default 1024
help
UHCI transaction buffer size for lower layer ISR logs
config BT_BLE_LOG_UHCI_OUT_LL_HCI_BUF_SIZE
int "UHCI transaction buffer size for lower layer HCI logs"
depends on BT_BLE_LOG_UHCI_OUT_ENABLED
default 1024
help
UHCI transaction buffer size for lower layer HCI logs
config BT_BLE_LOG_UHCI_OUT_UART_NEED_INIT
bool "Enable to init UART port"
depends on BT_BLE_LOG_UHCI_OUT_ENABLED
default y
help
Enable to init UART port
config BT_BLE_LOG_UHCI_OUT_UART_BAUD_RATE
int "Baud rate for BT_BLE_LOG_UHCI_OUT_UART_PORT"
depends on BT_BLE_LOG_UHCI_OUT_UART_NEED_INIT
default 3000000
help
Baud rate for BT_BLE_LOG_UHCI_OUT_UART_PORT
config BT_BLE_LOG_UHCI_OUT_UART_IO_NUM_TX
int "IO number for UART TX port"
depends on BT_BLE_LOG_UHCI_OUT_UART_NEED_INIT
default 0
help
IO number for UART TX port
config BT_LE_USED_MEM_STATISTICS_ENABLED
bool "Enable used memory statistics"
default n
+55 -43
View File
@@ -1,8 +1,8 @@
config BLE_LOG_ENABLED
bool "Enable BLE Log Module (Experimental)"
bool "Enable BT Log Async Output (Dev Only)"
default n
help
Enable BLE Log Module
Enable BT Log Async Output
if BLE_LOG_ENABLED
config BLE_LOG_TASK_STACK_SIZE
@@ -13,15 +13,22 @@ if BLE_LOG_ENABLED
help
Stack size for BLE Log Task
config BLE_LOG_LBM_TRANS_SIZE
int "Buffer size for each peripheral transport"
default 512
config BLE_LOG_LBM_TRANS_BUF_SIZE
int "Total buffer memory per common LBM (bytes)"
default 2048
help
There're 2 log buffer managers (LBMs) with compare-and-swap
(CAS) protection, 1 LBM with FreeRTOS mutex protection, 1 LBM
without protection for critical section. Each LBM is managing
2 ping-pong buffers, which means there will be 4 * 2 *
BLE_LOG_LBM_TRANS_SIZE bytes buffer allocated
Total buffer memory allocated for each common pool log buffer
manager (LBM). This memory is divided equally among internal
transport buffers. Must be a multiple of BLE_LOG_TRANS_BUF_CNT
(currently 4).
The common pool contains:
- BLE_LOG_LBM_ATOMIC_LOCK_TASK_CNT atomic LBMs (task context)
- BLE_LOG_LBM_ATOMIC_LOCK_ISR_CNT atomic LBMs (ISR context)
- 2 spinlock-protected LBMs (one for task, one for ISR fallback)
Total common pool memory:
(ATOMIC_TASK_CNT + ATOMIC_ISR_CNT + 2) * BLE_LOG_LBM_TRANS_BUF_SIZE
config BLE_LOG_LBM_ATOMIC_LOCK_TASK_CNT
int "Count of log buffer managers with atomic lock protection for task context"
@@ -47,7 +54,6 @@ if BLE_LOG_ENABLED
depends on SOC_ESP_NIMBLE_CONTROLLER
default y
select BT_LE_CONTROLLER_LOG_ENABLED
select BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
select BLE_LOG_LL_ENABLED
help
Current BLE Controller is ESP BLE Controller
@@ -71,14 +77,21 @@ if BLE_LOG_ENABLED
Enable BLE Log for Link Layer
if BLE_LOG_LL_ENABLED
config BLE_LOG_LBM_LL_TRANS_SIZE
int "Buffer size for each peripheral transport of Link Layer LBM"
default 1024
config BLE_LOG_LBM_LL_TRANS_BUF_SIZE
int "Total buffer memory per Link Layer LBM (bytes)"
default 2048
help
There're 2 Link Layer dedicated log buffer managers (LBMs) with
compare-and-swap (CAS) protection. Each LBM is managing 2 ping-
pong buffers, which means there will be additional 2 * 2 *
BLE_LOG_LBM_LL_TRANS_SIZE bytes buffer allocated
Total buffer memory allocated for each Link Layer dedicated
log buffer manager (LBM). This memory is divided equally among
internal transport buffers. Must be a multiple of
BLE_LOG_TRANS_BUF_CNT (currently 4).
There are 2 Link Layer LBMs without lock protection (each is
accessed from a single context only):
- LL task LBM (Link Layer task context logs)
- LL HCI LBM (Link Layer HCI context logs)
Total LL pool memory: 2 * BLE_LOG_LBM_LL_TRANS_BUF_SIZE
config BLE_LOG_LL_HCI_LOG_PAYLOAD_LEN_LIMIT_ENABLED
bool "Enable LL HCI Log Payload Length Limit"
@@ -104,30 +117,6 @@ if BLE_LOG_ENABLED
help
Enable BLE Host side HCI Logging
config BLE_LOG_PAYLOAD_CHECKSUM_ENABLED
bool "Enable payload checksum for BLE Log data integrity check"
default y
help
Checksum is the default method for BLE Log data integrity check,
but for targets with slow CPU speed, it may cause significant system
performance decrease; a compromise could be made to balance the
realtime performance and log data integrity, which is calculating the
checksum of frame head and payload all together by default, or only
calculate the checksum of frame head to minimize performance decrease
config BLE_LOG_XOR_CHECKSUM_ENABLED
bool "Enable XOR checksum for BLE Log payload integrity check"
default y
help
XOR checksum is introduced for integrity check performance optimization.
config BLE_LOG_ENH_STAT_ENABLED
bool "Enable enhanced statistics for BLE Log"
default n
help
Enable enhanced statistics for written/lost frame/bytes count, which may
cost additional ~100kB memory
config BLE_LOG_TS_ENABLED
bool "Enable BLE Log Timestamp Synchronization (TS)"
default n
@@ -177,6 +166,7 @@ if BLE_LOG_ENABLED
choice BLE_LOG_PRPH_CHOICE
prompt "BLE Log peripheral choice"
default BLE_LOG_PRPH_UART_DMA if SOC_UHCI_SUPPORTED
default BLE_LOG_PRPH_DUMMY
help
Choose BLE Log peripheral
@@ -228,7 +218,7 @@ if BLE_LOG_ENABLED
config BLE_LOG_PRPH_UART_DMA_BAUD_RATE
int "Baud rate of UART port for UART DMA transport"
default 921600
default 3000000
help
Determine the baud rate of UART port
@@ -242,4 +232,26 @@ if BLE_LOG_ENABLED
menu "Settings of BLE Log Compression"
source "$IDF_PATH/components/bt/common/ble_log/extension/log_compression/Kconfig.in"
endmenu
# Deprecated options -- retained for backward sdkconfig compatibility.
# These symbols have no prompt so they never appear in menuconfig.
config BLE_LOG_LBM_TRANS_SIZE
int
default 512
config BLE_LOG_ENH_STAT_ENABLED
bool
default y
config BLE_LOG_PAYLOAD_CHECKSUM_ENABLED
bool
default y
config BLE_LOG_LBM_LL_TRANS_SIZE
int
default 512
endif
menu "Legacy SPI Log Output (Deprecated - use BT Log Async Output instead)"
source "$IDF_PATH/components/bt/common/ble_log/deprecated/Kconfig.in"
endmenu
+76 -40
View File
@@ -1,6 +1,6 @@
# BLE Log Module
A high-performance, modular Bluetooth logging system that provides real-time log capture and transmission capabilities for the ESP-IDF Bluetooth stack.
A high-performance, modular Bluetooth logging system that provides real-time log capture and asynchronous transmission capabilities for the ESP-IDF Bluetooth stack.
## Table of Contents
@@ -32,18 +32,21 @@ The BLE Log module is an efficient logging system specifically designed for the
### Core Functionality
- **Multi-source Log Collection**: Supports multiple log sources including Link Layer, Host, HCI, etc.
- **Multi-source Log Collection**: Supports multiple log sources including Link Layer, Host, HCI, UART redirection, etc.
- **High Concurrency Processing**: Uses atomic and spin lock mechanisms for multi-task concurrent writing
- **Real-time Transmission**: Asynchronous transmission mechanism based on FreeRTOS tasks
- **Data Integrity**: Configurable checksum mechanism ensures data integrity
- **Memory Optimization**: Ping-pong buffer design minimizes memory usage
- **Data Integrity**: Checksum mechanism ensures data integrity (always enabled)
- **Multi-buffer Transport**: Each LBM manages multiple transport buffers (default 4) for improved throughput over the legacy ping-pong design
- **Cross-pool Buffer Fallback**: LBM acquire attempts all atomic LBMs before falling back to spinlock LBMs, improving buffer availability under contention
### Advanced Features
- **UART Redirection**: When using UART DMA on PORT 0, UART output (including `esp_rom_printf`) is transparently redirected through the async log pipeline
- **Timestamp Synchronization**: Supports timestamp synchronization with external devices (optional)
- **Enhanced Statistics**: Detailed logging statistics including loss rate analysis (optional)
- **Enhanced Statistics**: Detailed logging statistics including written/lost frame and byte counts (always enabled)
- **Buffer Utilization Reporting**: Per-LBM buffer utilization and inflight peak tracking for diagnostics
- **Link Layer Integration**: Deep integration with ESP-IDF Bluetooth Link Layer
- **Multiple Transmission Methods**: Supports SPI DMA, UART DMA, and Dummy transmission
- **Multiple Transmission Methods**: Supports SPI Master DMA, UART DMA, and Dummy transmission
### Performance Features
@@ -58,7 +61,7 @@ The BLE Log module is an efficient logging system specifically designed for the
Enable the BLE Log module in `menuconfig`:
```
Component config → Bluetooth → Enable BLE Log Module (Experimental)
Component config → Bluetooth → Enable BT Log Async Output (Dev Only)
```
### 2. Basic Configuration
@@ -102,8 +105,8 @@ void ble_log_write_hex_ll(uint32_t len, const uint8_t *addr,
| Configuration | Default | Description |
|---------------|---------|-------------|
| `CONFIG_BLE_LOG_ENABLED` | n | Enable BLE Log module |
| `CONFIG_BLE_LOG_LBM_TRANS_SIZE` | 512 | Size of each transport buffer |
| `CONFIG_BLE_LOG_ENABLED` | n | Enable BT Log Async Output |
| `CONFIG_BLE_LOG_LBM_TRANS_BUF_SIZE` | 2048 | Total buffer memory per common LBM (bytes). Divided equally among `BLE_LOG_TRANS_BUF_CNT` (4) internal transport buffers. |
| `CONFIG_BLE_LOG_LBM_ATOMIC_LOCK_TASK_CNT` | 2 | Number of atomic lock LBMs for task context |
| `CONFIG_BLE_LOG_LBM_ATOMIC_LOCK_ISR_CNT` | 1 | Number of atomic lock LBMs for ISR context |
@@ -112,23 +115,31 @@ void ble_log_write_hex_ll(uint32_t len, const uint8_t *addr,
| Configuration | Default | Description |
|---------------|---------|-------------|
| `CONFIG_BLE_LOG_LL_ENABLED` | y | Enable Link Layer logging |
| `CONFIG_BLE_LOG_LBM_LL_TRANS_SIZE` | 1024 | Link Layer transport buffer size |
| `CONFIG_BLE_LOG_LBM_LL_TRANS_BUF_SIZE` | 2048 | Total buffer memory per Link Layer LBM (bytes). Divided equally among `BLE_LOG_TRANS_BUF_CNT` (4) internal transport buffers. |
### Advanced Features
### Other Features
| Configuration | Default | Description |
|---------------|---------|-------------|
| `CONFIG_BLE_LOG_PAYLOAD_CHECKSUM_ENABLED` | y | Enable payload checksum |
| `CONFIG_BLE_LOG_ENH_STAT_ENABLED` | n | Enable enhanced statistics |
| `CONFIG_BLE_LOG_TS_ENABLED` | n | Enable timestamp synchronization |
| `CONFIG_BLE_LOG_HOST_HCI_LOG_ENABLED` | n | Enable BLE Host side HCI logging |
> **Note**: Payload checksum and enhanced statistics are now always enabled and no longer have separate Kconfig options.
### Transport Method Configuration
| Transport | Configuration | Description |
|-----------|---------------|-------------|
| Dummy | `CONFIG_BLE_LOG_PRPH_DUMMY` | Debug dummy transport |
| Dummy | `CONFIG_BLE_LOG_PRPH_DUMMY` | Debug dummy transport (default unless `SOC_UHCI_SUPPORTED`) |
| SPI Master DMA | `CONFIG_BLE_LOG_PRPH_SPI_MASTER_DMA` | SPI DMA transport |
| UART DMA | `CONFIG_BLE_LOG_PRPH_UART_DMA` | UART DMA transport |
| UART DMA | `CONFIG_BLE_LOG_PRPH_UART_DMA` | UART DMA transport (default when `SOC_UHCI_SUPPORTED`). Default baud rate: 3000000. |
### Deprecated / Removed
| Module | Status | Notes |
|--------|--------|-------|
| Legacy SPI Log Output | Deprecated | Moved to `deprecated/` directory. Use BT Log Async Output instead. A separate Kconfig menu "Legacy SPI Log Output" is available for backward compatibility. |
| UHCI Out | Removed | The standalone UHCI Out module (`ble_log_uhci_out.c`) has been removed. UART DMA transport under the main BLE Log peripheral interface replaces it. |
## API Reference
@@ -187,10 +198,19 @@ typedef enum {
BLE_LOG_SRC_HOST, // Host layer logs
BLE_LOG_SRC_HCI, // HCI layer logs
BLE_LOG_SRC_ENCODE, // Encoding layer logs
BLE_LOG_SRC_REDIR, // UART redirection (PORT 0 only)
BLE_LOG_SRC_MAX,
} ble_log_src_t;
```
### HCI Log Macro
```c
#define ble_log_write_hci(direction, data, len)
```
Writes an HCI packet with direction encoding. `direction` is `BLE_LOG_HCI_DOWNSTREAM` (0) or `BLE_LOG_HCI_UPSTREAM` (1). Direction is encoded in the MSB of the first byte (HCI type).
### Link Layer API (Conditional Compilation)
#### `void ble_log_write_hex_ll(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag)`
@@ -213,6 +233,7 @@ enum {
BLE_LOG_LL_FLAG_ISR,
BLE_LOG_LL_FLAG_HCI,
BLE_LOG_LL_FLAG_RAW,
BLE_LOG_LL_FLAG_OMDATA,
BLE_LOG_LL_FLAG_HCI_UPSTREAM,
};
```
@@ -326,31 +347,37 @@ void example_performance_test() {
### Memory Usage Estimation
Each LBM's total buffer memory is configured directly via Kconfig. The configured value is divided equally among `BLE_LOG_TRANS_BUF_CNT` (currently 4) internal transport buffers.
Memory usage under default configuration:
```
Total Buffers = (Atomic Task LBMs + Atomic ISR LBMs + Spin LBMs) × 2 × Transport Buffer Size
Default Config = (2 + 1 + 2) × 2 × 512 = 5120 bytes
Common Pool:
LBM count = Atomic Task (2) + Atomic ISR (1) + Spinlock (2) = 5
Total = 5 × BLE_LOG_LBM_TRANS_BUF_SIZE = 5 × 2048 = 10240 bytes
Additional when Link Layer enabled:
LL Buffers = 2 × 2 × 1024 = 4096 bytes
Link Layer Pool (when CONFIG_BLE_LOG_LL_ENABLED):
LBM count = 2 (LL task + LL HCI)
Total = 2 × BLE_LOG_LBM_LL_TRANS_BUF_SIZE = 2 × 2048 = 4096 bytes
Additional when Enhanced Statistics enabled:
Statistics Data = Log Source Count × sizeof(ble_log_stat_mgr_t) = 8 × 40 = 320 bytes
Statistics (always enabled):
Total = BLE_LOG_SRC_MAX × sizeof(ble_log_stat_mgr_t) = 9 × 20 = 180 bytes
UART Redirect (when UART DMA on PORT 0):
Additional BLE_LOG_TRANS_BUF_CNT (4) transport buffers
```
### Performance Optimization Recommendations
1. **Adjust LBM Count**: Adjust atomic lock LBM count based on concurrency requirements
2. **Buffer Size**: Adjust transport buffer size based on log volume
3. **Transport Method**: Choose optimal transport method based on hardware (SPI DMA typically has best performance)
4. **Checksum**: Consider disabling payload checksum when performance requirements are extremely high
2. **Buffer Size**: Adjust total buffer memory per LBM based on log volume; must be a multiple of `BLE_LOG_TRANS_BUF_CNT` (4)
3. **Transport Method**: Choose optimal transport method based on hardware (UART DMA is default on supported SoCs)
### Real-time Considerations
- Critical code paths are marked with `BLE_LOG_IRAM_ATTR` and run in IRAM
- Atomic operations avoid lock contention
- Ping-pong buffers ensure continuous writing
- Multi-buffer transport ensures continuous writing even when some buffers are in-flight
## Troubleshooting
@@ -388,13 +415,11 @@ if (!initialized) {
**Solutions**:
```c
// Enable enhanced statistics to check loss rate
#if CONFIG_BLE_LOG_ENH_STAT_ENABLED
// Statistics will be automatically included in logs
#endif
// Enhanced statistics are always enabled — check written/lost frame
// and byte counts in the log stream output
// Adjust buffer size
// CONFIG_BLE_LOG_LBM_TRANS_SIZE=1024
// Increase total buffer memory per LBM
// CONFIG_BLE_LOG_LBM_TRANS_BUF_SIZE=4096
// Increase atomic lock LBM count
// CONFIG_BLE_LOG_LBM_ATOMIC_LOCK_TASK_CNT=4
@@ -405,17 +430,16 @@ if (!initialized) {
**Symptoms**: System response becomes slow
**Possible Causes**:
- Checksum calculation overhead
- Transmission bottleneck
- Lock contention
**Solutions**:
```c
// Disable payload checksum
// CONFIG_BLE_LOG_PAYLOAD_CHECKSUM_ENABLED=n
// Use faster transmission method
// CONFIG_BLE_LOG_PRPH_SPI_MASTER_DMA=y
// CONFIG_BLE_LOG_PRPH_UART_DMA=y (default on SOC_UHCI_SUPPORTED targets)
// Increase baud rate (default is now 3000000)
// CONFIG_BLE_LOG_PRPH_UART_DMA_BAUD_RATE=3000000
// Adjust task priority
#define BLE_LOG_TASK_PRIO configMAX_PRIORITIES-3
@@ -431,12 +455,11 @@ if (!initialized) {
ble_log_dump_to_console();
```
#### 2. Enable Enhanced Statistics
#### 2. Check Enhanced Statistics
```c
// Enable in menuconfig
// CONFIG_BLE_LOG_ENH_STAT_ENABLED=y
// Statistics will be automatically output to logs
// Enhanced statistics are always enabled
// Written/lost frame and byte counts are automatically output to logs
```
#### 3. Monitor Memory Usage
@@ -448,3 +471,16 @@ void monitor_memory() {
printf("Free heap after init: %d\n", esp_get_free_heap_size());
}
```
## Important Notes
### Buffer Size Constraints
- `CONFIG_BLE_LOG_LBM_TRANS_BUF_SIZE` and `CONFIG_BLE_LOG_LBM_LL_TRANS_BUF_SIZE` must be multiples of `BLE_LOG_TRANS_BUF_CNT` (currently 4)
- The per-buffer size (total ÷ 4) must be at least large enough to hold one frame overhead (`BLE_LOG_FRAME_OVERHEAD`)
- `BLE_LOG_TRANS_BUF_CNT` must be a power of 2
### Migration from Legacy Modules
- **UHCI Out**: The standalone `ble_log_uhci_out` module has been removed. Use the UART DMA peripheral transport (`CONFIG_BLE_LOG_PRPH_UART_DMA`) instead.
- **SPI Out**: The legacy SPI log output has been moved to `deprecated/`. A separate Kconfig menu "Legacy SPI Log Output (Deprecated)" is available for backward compatibility, but new projects should use BT Log Async Output with the SPI Master DMA peripheral transport.
@@ -1,795 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "ble_log/ble_log_uhci_out.h"
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
// Private includes
#include "esp_bt.h"
// sdkconfig defines
#define UHCI_OUT_LL_TASK_BUF_SIZE CONFIG_BT_BLE_LOG_UHCI_OUT_LL_TASK_BUF_SIZE
#define UHCI_OUT_LL_ISR_BUF_SIZE CONFIG_BT_BLE_LOG_UHCI_OUT_LL_ISR_BUF_SIZE
#define UHCI_OUT_LL_HCI_BUF_SIZE CONFIG_BT_BLE_LOG_UHCI_OUT_LL_HCI_BUF_SIZE
#define UHCI_OUT_UART_PORT CONFIG_BT_BLE_LOG_UHCI_OUT_UART_PORT
#define UHCI_OUT_UART_NEED_INIT CONFIG_BT_BLE_LOG_UHCI_OUT_UART_NEED_INIT
#if UHCI_OUT_UART_NEED_INIT
#define UHCI_OUT_UART_BAUD_RATE CONFIG_BT_BLE_LOG_UHCI_OUT_UART_BAUD_RATE
#define UHCI_OUT_UART_IO_NUM_TX CONFIG_BT_BLE_LOG_UHCI_OUT_UART_IO_NUM_TX
#endif // UHCI_OUT_UART_NEED_INIT
// Private defines
#define UHCI_OUT_MAX_TRANSFER_SIZE (10240)
#define UHCI_OUT_MALLOC(size) heap_caps_malloc(size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
#define UHCI_OUT_FLUSH_TIMEOUT_MS (100)
#define UHCI_OUT_FLUSH_TIMEOUT_US (UHCI_OUT_FLUSH_TIMEOUT_MS * 1000)
#define UHCI_OUT_USER_BUF_SIZE (512)
#define UHCI_OUT_UART_PORT0 (0)
#define UHCI_OUT_UART_PORT1 (1)
#define UHCI_OUT_UART_DRIVER_RX_BUF_SIZE (32)
// Queue size defines
#define UHCI_OUT_PING_PONG_BUF_CNT (2)
#define UHCI_OUT_USER_QUEUE_SIZE (UHCI_OUT_PING_PONG_BUF_CNT)
#define UHCI_OUT_LL_QUEUE_SIZE (3 * UHCI_OUT_PING_PONG_BUF_CNT)
#define UHCI_OUT_QUEUE_SIZE (UHCI_OUT_USER_QUEUE_SIZE + UHCI_OUT_LL_QUEUE_SIZE)
#if CONFIG_SOC_ESP_NIMBLE_CONTROLLER
#include "os/os_mbuf.h"
#endif /* CONFIG_SOC_ESP_NIMBLE_CONTROLLER */
// Private typedefs
typedef struct {
// This flag is for multithreading, must be a word, do not modify
volatile uint32_t flag;
uint16_t buf_size;
uint16_t length;
uint8_t buffer[0];
} uhci_out_trans_cb_t;
typedef struct {
uhci_out_trans_cb_t *trans_cb[2];
uint8_t trans_cb_idx;
uint8_t type;
uint16_t lost_frame_cnt;
uint32_t lost_bytes_cnt;
uint32_t frame_sn;
} uhci_out_log_cb_t;
typedef struct {
uint16_t length;
uint8_t source;
uint8_t type;
uint16_t frame_sn;
} __attribute__((packed)) frame_head_t;
typedef struct {
uint8_t type;
uint16_t lost_frame_cnt;
uint32_t lost_bytes_cnt;
} __attribute__((packed)) loss_payload_t;
// Private enums
enum {
TRANS_CB_FLAG_AVAILABLE = 0,
TRANS_CB_FLAG_NEED_QUEUE,
TRANS_CB_FLAG_IN_QUEUE,
};
enum {
LOG_CB_TYPE_USER = 0,
LOG_CB_TYPE_LL,
};
enum {
LOG_CB_LL_SUBTYPE_TASK = 0,
LOG_CB_LL_SUBTYPE_ISR,
LOG_CB_LL_SUBTYPE_HCI
};
enum {
LL_LOG_FLAG_CONTINUE = 0,
LL_LOG_FLAG_END,
LL_LOG_FLAG_TASK,
LL_LOG_FLAG_ISR,
LL_LOG_FLAG_HCI,
LL_LOG_FLAG_RAW,
LL_LOG_FLAG_OMDATA,
LL_LOG_FLAG_HCI_UPSTREAM,
};
enum {
LL_EV_FLAG_ISR_APPEND = 0,
LL_EV_FLAG_FLUSH_LOG,
};
// Private variables
static bool uhci_out_inited = false;
static uhci_controller_handle_t uhci_handle = NULL;
static bool user_log_inited = false;
static SemaphoreHandle_t user_log_mutex = NULL;
static uhci_out_log_cb_t *user_log_cb = NULL;
static uint32_t user_last_write_ts = 0;
static bool ll_log_inited = false;
static uhci_out_log_cb_t *ll_task_log_cb = NULL;
static uhci_out_log_cb_t *ll_isr_log_cb = NULL;
static uhci_out_log_cb_t *ll_hci_log_cb = NULL;
static uint32_t ll_ev_flags = 0;
static uint32_t ll_last_write_ts = 0;
static esp_timer_handle_t flush_timer = NULL;
// Private function declarations
extern void esp_panic_handler_feed_wdts(void);
static int uhci_out_init_trans(uhci_out_trans_cb_t **trans_cb, uint16_t buf_size);
static void uhci_out_deinit_trans(uhci_out_trans_cb_t **trans_cb);
static bool uhci_out_tx_done_cb(uhci_controller_handle_t uhci_ctrl,
const uhci_tx_done_event_data_t *edata, void *user_ctx);
static inline void uhci_out_append_trans(uhci_out_trans_cb_t *trans_cb);
static int uhci_out_log_cb_init(uhci_out_log_cb_t **log_cb, uint16_t buf_size, uint8_t type, uint8_t idx);
static void uhci_out_log_cb_deinit(uhci_out_log_cb_t **log_cb);
static inline bool uhci_out_log_cb_check_trans(uhci_out_log_cb_t *log_cb, uint16_t len, bool *need_append);
static inline void uhci_out_log_cb_append_trans(uhci_out_log_cb_t *log_cb);
static inline void uhci_out_log_cb_flush_trans(uhci_out_log_cb_t *log_cb);
static bool uhci_out_log_cb_write(uhci_out_log_cb_t *log_cb, const uint8_t *addr, uint16_t len,
const uint8_t *addr_append, uint16_t len_append, uint8_t source, bool omdata);
static void uhci_out_log_cb_write_loss(uhci_out_log_cb_t *log_cb);
static void uhci_out_log_cb_dump(uhci_out_log_cb_t *log_cb);
static void esp_timer_cb_log_flush(void);
static void uhci_out_user_write_str(const uint8_t *src, uint16_t len);
#if UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
static void uhci_out_user_write_char(char c);
#endif // UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
static int uhci_out_user_log_init(void);
static void uhci_out_user_log_deinit(void);
static int uhci_out_ll_log_init(void);
static void uhci_out_ll_log_deinit(void);
static void uhci_out_ll_log_flush(void);
#if defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C5) ||\
defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32H21)
extern void r_ble_log_simple_put_ev(void);
#define UHCI_OUT_LL_PUT_EV r_ble_log_simple_put_ev()
#elif defined(CONFIG_IDF_TARGET_ESP32C2)
extern void ble_log_simple_put_ev(void);
#define UHCI_OUT_LL_PUT_EV ble_log_simple_put_ev()
#else
#define UHCI_OUT_LL_PUT_EV
#endif
// Private macros
#define UHCI_OUT_FRAME_HEAD_LEN (sizeof(frame_head_t))
#define UHCI_OUT_FRAME_TAIL_LEN (sizeof(uint32_t))
#define UHCI_OUT_FRAME_OVERHEAD (UHCI_OUT_FRAME_HEAD_LEN + UHCI_OUT_FRAME_TAIL_LEN)
#define UHCI_OUT_GET_FRAME_SN(VAR) __atomic_fetch_add(VAR, 1, __ATOMIC_RELAXED)
// Private functions
static int uhci_out_init_trans(uhci_out_trans_cb_t **trans_cb, uint16_t buf_size)
{
// Memory allocations
size_t cb_size = sizeof(uhci_out_trans_cb_t) + buf_size;
*trans_cb = (uhci_out_trans_cb_t *)UHCI_OUT_MALLOC(cb_size);
if (!(*trans_cb)) {
return -1;
}
memset(*trans_cb, 0, sizeof(uhci_out_trans_cb_t));
// Initialization
(*trans_cb)->buf_size = buf_size;
return 0;
}
static void uhci_out_deinit_trans(uhci_out_trans_cb_t **trans_cb)
{
if (!(*trans_cb)) {
return;
}
free(*trans_cb);
*trans_cb = NULL;
return;
}
IRAM_ATTR static bool uhci_out_tx_done_cb(uhci_controller_handle_t uhci_ctrl,
const uhci_tx_done_event_data_t *edata, void *user_ctx)
{
uhci_out_trans_cb_t *trans_cb = (uhci_out_trans_cb_t *)((uint8_t *)edata->buffer - sizeof(uhci_out_trans_cb_t));
trans_cb->length = 0;
trans_cb->flag = TRANS_CB_FLAG_AVAILABLE;
return true;
}
IRAM_ATTR static inline void uhci_out_append_trans(uhci_out_trans_cb_t *trans_cb)
{
if ((trans_cb->flag != TRANS_CB_FLAG_NEED_QUEUE) || !trans_cb->length) {
return;
}
// Note: If task yield after transmission but before flag set
// flag might be reset in tx done ISR before flag set, leading to buffer access failure
trans_cb->flag = TRANS_CB_FLAG_IN_QUEUE;
if (uhci_transmit(uhci_handle, trans_cb->buffer, trans_cb->length) != ESP_OK) {
goto recycle;
}
return;
recycle:
trans_cb->length = 0;
trans_cb->flag = TRANS_CB_FLAG_AVAILABLE;
return;
}
static int uhci_out_log_cb_init(uhci_out_log_cb_t **log_cb, uint16_t buf_size, uint8_t type, uint8_t idx)
{
// Initialize log control block
*log_cb = (uhci_out_log_cb_t *)UHCI_OUT_MALLOC(sizeof(uhci_out_log_cb_t));
if (!(*log_cb)) {
return -1;
}
memset(*log_cb, 0, sizeof(uhci_out_log_cb_t));
// Initialize transactions
int ret = 0;
for (uint8_t i = 0; i < 2; i++) {
ret |= uhci_out_init_trans(&((*log_cb)->trans_cb[i]), buf_size);
}
if (ret != 0) {
uhci_out_log_cb_deinit(log_cb);
return -1;
}
(*log_cb)->type = (type << 4) | (idx);
return 0;
}
static void uhci_out_log_cb_deinit(uhci_out_log_cb_t **log_cb)
{
if (!(*log_cb)) {
return;
}
for (uint8_t i = 0; i < 2; i++) {
if ((*log_cb)->trans_cb[i]) {
uhci_out_deinit_trans(&((*log_cb)->trans_cb[i]));
}
}
free(*log_cb);
*log_cb = NULL;
return;
}
IRAM_ATTR static inline bool uhci_out_log_cb_check_trans(uhci_out_log_cb_t *log_cb, uint16_t len, bool *need_append)
{
uhci_out_trans_cb_t *trans_cb;
*need_append = false;
for (uint8_t i = 0; i < 2; i++) {
trans_cb = log_cb->trans_cb[log_cb->trans_cb_idx];
if (len > trans_cb->buf_size) {
goto failed;
}
if (trans_cb->flag == TRANS_CB_FLAG_AVAILABLE) {
if ((trans_cb->buf_size - trans_cb->length) >= len) {
return true;
} else {
trans_cb->flag = TRANS_CB_FLAG_NEED_QUEUE;
*need_append = true;
}
}
log_cb->trans_cb_idx = !(log_cb->trans_cb_idx);
}
failed:
log_cb->lost_bytes_cnt += len;
log_cb->lost_frame_cnt++;
return false;
}
// CRITICAL: Shall not be called from ISR!
IRAM_ATTR static inline void uhci_out_log_cb_append_trans(uhci_out_log_cb_t *log_cb)
{
uhci_out_trans_cb_t *trans_cb;
uint8_t idx = !log_cb->trans_cb_idx;
for (uint8_t i = 0; i < 2; i++) {
trans_cb = log_cb->trans_cb[idx];
if (trans_cb->flag == TRANS_CB_FLAG_NEED_QUEUE) {
uhci_out_append_trans(trans_cb);
}
idx = !idx;
}
}
IRAM_ATTR static inline void uhci_out_log_cb_flush_trans(uhci_out_log_cb_t *log_cb)
{
uhci_out_trans_cb_t *trans_cb;
for (uint8_t i = 0; i < 2; i++) {
trans_cb = log_cb->trans_cb[i];
if (trans_cb->length && (trans_cb->flag == TRANS_CB_FLAG_AVAILABLE)) {
trans_cb->flag = TRANS_CB_FLAG_NEED_QUEUE;
}
}
}
// Return value: Need append
IRAM_ATTR static bool uhci_out_log_cb_write(uhci_out_log_cb_t *log_cb, const uint8_t *addr, uint16_t len,
const uint8_t *addr_append, uint16_t len_append, uint8_t source, bool omdata)
{
uhci_out_trans_cb_t *trans_cb = log_cb->trans_cb[log_cb->trans_cb_idx];
uint8_t *buf = trans_cb->buffer + trans_cb->length;
uint16_t total_length = len + len_append;
frame_head_t head = {
.length = total_length,
.source = source,
.type = log_cb->type,
.frame_sn = UHCI_OUT_GET_FRAME_SN(&(log_cb->frame_sn)) & 0xFFFF,
};
memcpy(buf, (const uint8_t *)&head, UHCI_OUT_FRAME_HEAD_LEN);
memcpy(buf + UHCI_OUT_FRAME_HEAD_LEN, addr, len);
if (len_append && addr_append) {
#if CONFIG_SOC_ESP_NIMBLE_CONTROLLER
if (omdata) {
os_mbuf_copydata((struct os_mbuf *)addr_append, 0,
len_append, buf + UHCI_OUT_FRAME_HEAD_LEN + len);
}
else
#endif /* CONFIG_SOC_ESP_NIMBLE_CONTROLLER */
{
memcpy(buf + UHCI_OUT_FRAME_HEAD_LEN + len, addr_append, len_append);
}
}
uint32_t checksum = 0;
for (int i = 0; i < UHCI_OUT_FRAME_HEAD_LEN + total_length; i++) {
checksum += buf[i];
}
memcpy(buf + UHCI_OUT_FRAME_HEAD_LEN + total_length, &checksum, UHCI_OUT_FRAME_TAIL_LEN);
trans_cb->length += total_length + UHCI_OUT_FRAME_OVERHEAD;
if ((trans_cb->buf_size - trans_cb->length) <= UHCI_OUT_FRAME_OVERHEAD) {
trans_cb->flag = TRANS_CB_FLAG_NEED_QUEUE;
return true;
}
return false;
}
IRAM_ATTR static void uhci_out_log_cb_write_loss(uhci_out_log_cb_t *log_cb)
{
if (!log_cb->lost_bytes_cnt || !log_cb->lost_frame_cnt) {
return;
}
bool need_append;
uint16_t frame_len = sizeof(loss_payload_t) + UHCI_OUT_FRAME_OVERHEAD;
if (uhci_out_log_cb_check_trans(log_cb, frame_len, &need_append)) {
loss_payload_t payload = {
.type = log_cb->type,
.lost_frame_cnt = log_cb->lost_frame_cnt,
.lost_bytes_cnt = log_cb->lost_bytes_cnt,
};
uhci_out_log_cb_write(log_cb, (const uint8_t *)&payload, sizeof(loss_payload_t),
NULL, 0, BLE_LOG_UHCI_OUT_SOURCE_LOSS, false);
log_cb->lost_frame_cnt = 0;
log_cb->lost_bytes_cnt = 0;
}
}
static void uhci_out_log_cb_dump(uhci_out_log_cb_t *log_cb)
{
uhci_out_trans_cb_t *trans_cb;
uint8_t *buf;
for (uint8_t i = 0; i < 2; i++) {
// Dump the last transaction before dumping the current transaction
log_cb->trans_cb_idx = !(log_cb->trans_cb_idx);
trans_cb = log_cb->trans_cb[log_cb->trans_cb_idx];
buf = (uint8_t *)trans_cb->buffer;
for (uint16_t j = 0; j < trans_cb->buf_size; j++) {
esp_rom_printf("%02x ", buf[j]);
// Feed watchdogs periodically to avoid wdts timeout
if ((j % 100) == 0) {
esp_panic_handler_feed_wdts();
}
}
}
}
static void esp_timer_cb_log_flush(void)
{
uint32_t os_ts = pdTICKS_TO_MS(xTaskGetTickCount());
if ((os_ts - user_last_write_ts) > UHCI_OUT_FLUSH_TIMEOUT_MS) {
xSemaphoreTake(user_log_mutex, portMAX_DELAY);
uhci_out_log_cb_flush_trans(user_log_cb);
uhci_out_log_cb_append_trans(user_log_cb);
xSemaphoreGive(user_log_mutex);
}
if ((esp_bt_controller_get_status() >= ESP_BT_CONTROLLER_STATUS_INITED) &&
((os_ts - ll_last_write_ts) > UHCI_OUT_FLUSH_TIMEOUT_MS)) {
ll_ev_flags |= BIT(LL_EV_FLAG_FLUSH_LOG);
UHCI_OUT_LL_PUT_EV;
}
esp_timer_start_once(flush_timer, UHCI_OUT_FLUSH_TIMEOUT_US);
}
static void uhci_out_user_write_str(const uint8_t *src, uint16_t len)
{
if (!user_log_inited || !src || !len) {
return;
}
xSemaphoreTake(user_log_mutex, portMAX_DELAY);
bool need_append;
if (uhci_out_log_cb_check_trans(user_log_cb, len, &need_append)) {
uhci_out_trans_cb_t *trans_cb = user_log_cb->trans_cb[user_log_cb->trans_cb_idx];
uint8_t *buf = trans_cb->buffer + trans_cb->length;
memcpy(buf, (const uint8_t *)src, len);
trans_cb->length += len;
}
if (need_append) {
uhci_out_log_cb_append_trans(user_log_cb);
}
user_last_write_ts = pdTICKS_TO_MS(xTaskGetTickCount());
xSemaphoreGive(user_log_mutex);
}
#if UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
static void uhci_out_user_write_char(char c)
{
uhci_out_user_write_str((const uint8_t *)&c, 1);
}
#endif // UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
static int uhci_out_user_log_init(void)
{
if (user_log_inited) {
return 0;
}
// Initialize mutex
user_log_mutex = xSemaphoreCreateMutex();
if (!user_log_mutex) {
goto failed;
}
// Initialize log control block
if (uhci_out_log_cb_init(&user_log_cb, UHCI_OUT_USER_BUF_SIZE, LOG_CB_TYPE_USER, 0) != 0) {
goto failed;
}
// Initialization done
user_log_inited = true;
return 0;
failed:
uhci_out_user_log_deinit();
return -1;
}
static void uhci_out_user_log_deinit(void)
{
user_log_inited = false;
if (!user_log_mutex) {
return;
}
xSemaphoreTake(user_log_mutex, portMAX_DELAY);
uhci_out_log_cb_deinit(&user_log_cb);
xSemaphoreGive(user_log_mutex);
vSemaphoreDelete(user_log_mutex);
user_log_mutex = NULL;
}
static int uhci_out_ll_log_init(void)
{
if (ll_log_inited) {
return 0;
}
if (uhci_out_log_cb_init(&ll_task_log_cb, UHCI_OUT_LL_TASK_BUF_SIZE,
LOG_CB_TYPE_LL, LOG_CB_LL_SUBTYPE_TASK) != 0) {
goto failed;
}
if (uhci_out_log_cb_init(&ll_isr_log_cb, UHCI_OUT_LL_ISR_BUF_SIZE,
LOG_CB_TYPE_LL, LOG_CB_LL_SUBTYPE_ISR) != 0) {
goto failed;
}
if (uhci_out_log_cb_init(&ll_hci_log_cb, UHCI_OUT_LL_HCI_BUF_SIZE,
LOG_CB_TYPE_LL, LOG_CB_LL_SUBTYPE_HCI) != 0) {
goto failed;
}
ll_log_inited = true;
return 0;
failed:
uhci_out_ll_log_deinit();
return -1;
}
static void uhci_out_ll_log_deinit(void)
{
ll_log_inited = false;
uhci_out_log_cb_deinit(&ll_hci_log_cb);
uhci_out_log_cb_deinit(&ll_isr_log_cb);
uhci_out_log_cb_deinit(&ll_task_log_cb);
}
static void uhci_out_ll_log_flush(void)
{
if (!ll_log_inited) {
return;
}
uhci_out_log_cb_write_loss(ll_task_log_cb);
uhci_out_log_cb_write_loss(ll_hci_log_cb);
uhci_out_log_cb_flush_trans(ll_task_log_cb);
uhci_out_log_cb_flush_trans(ll_hci_log_cb);
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL_SAFE(&spinlock);
uhci_out_log_cb_write_loss(ll_isr_log_cb);
uhci_out_log_cb_flush_trans(ll_isr_log_cb);
portEXIT_CRITICAL_SAFE(&spinlock);
uhci_out_log_cb_append_trans(ll_task_log_cb);
uhci_out_log_cb_append_trans(ll_hci_log_cb);
uhci_out_log_cb_append_trans(ll_isr_log_cb);
}
// Public functions
int ble_log_uhci_out_init(void)
{
// Avoid double init
if (uhci_out_inited) {
return 0;
}
#if UHCI_OUT_UART_NEED_INIT
uart_config_t uart_config = {
.baud_rate = UHCI_OUT_UART_BAUD_RATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS,
.rx_flow_ctrl_thresh = 122,
};
// Configure UART parameters
uart_param_config(UHCI_OUT_UART_PORT, &uart_config);
uart_set_pin(UHCI_OUT_UART_PORT, UHCI_OUT_UART_IO_NUM_TX, -1, -1, -1);
#endif // UHCI_OUT_UART_NEED_INIT
uhci_controller_config_t uhci_config = {
.uart_port = UHCI_OUT_UART_PORT,
.tx_trans_queue_depth = UHCI_OUT_QUEUE_SIZE,
.max_receive_internal_mem = 1024,
.max_transmit_size = UHCI_OUT_MAX_TRANSFER_SIZE,
.dma_burst_size = 32,
.rx_eof_flags.idle_eof = 1,
};
if (uhci_new_controller(&uhci_config, &uhci_handle) != ESP_OK) {
goto failed;
}
uhci_event_callbacks_t uhci_cbs = {
.on_tx_trans_done = uhci_out_tx_done_cb,
};
uhci_register_event_callbacks(uhci_handle, &uhci_cbs, NULL);
if (uhci_out_user_log_init() != 0) {
goto failed;
}
if (uhci_out_ll_log_init() != 0) {
goto failed;
}
esp_timer_create_args_t timer_args = {
.callback = (esp_timer_cb_t)esp_timer_cb_log_flush,
.dispatch_method = ESP_TIMER_TASK
};
if (esp_timer_create(&timer_args, &flush_timer) != ESP_OK) {
goto failed;
}
#if UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
// Install UART Driver if not installed
if (!uart_is_driver_installed(UHCI_OUT_UART_PORT0)) {
uart_driver_install(UHCI_OUT_UART_PORT0, UHCI_OUT_UART_DRIVER_RX_BUF_SIZE, 0, 0, NULL, 0);
}
// Redirect UART VFS Driver to UART Driver
uart_vfs_dev_use_driver(UHCI_OUT_UART_PORT0);
// Redirect esp_rom_printf to BLE Log UHCI Out
esp_rom_install_channel_putc(1, uhci_out_user_write_char);
esp_rom_install_channel_putc(2, NULL);
#endif // UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
uhci_out_inited = true;
esp_timer_start_once(flush_timer, UHCI_OUT_FLUSH_TIMEOUT_US);
return 0;
failed:
ble_log_uhci_out_deinit();
return -1;
}
void ble_log_uhci_out_deinit(void)
{
uhci_out_inited = false;
if (flush_timer) {
esp_timer_stop(flush_timer);
esp_timer_delete(flush_timer);
flush_timer = NULL;
}
if (uhci_handle) {
uhci_wait_all_tx_transaction_done(uhci_handle, portMAX_DELAY);
uhci_del_controller(uhci_handle);
uhci_handle = NULL;
}
uhci_out_ll_log_deinit();
uhci_out_user_log_deinit();
}
IRAM_ATTR void ble_log_uhci_out_ll_write(uint32_t len, const uint8_t *addr, uint32_t len_append,
const uint8_t *addr_append, uint32_t flag)
{
// Raw logs will come in case of assert, shall be printed to console directly
if (flag & BIT(LL_LOG_FLAG_RAW)) {
if (len && addr) {
for (uint32_t i = 0; i < len; i++) { esp_rom_printf("%02x ", addr[i]); }
}
if (len_append && addr_append) {
for (uint32_t i = 0; i < len_append; i++) { esp_rom_printf("%02x ", addr_append[i]); }
}
if (flag & BIT(LL_LOG_FLAG_END)) { esp_rom_printf("\n"); }
}
if (!ll_log_inited) {
return;
}
bool in_isr = false;
uint8_t source;
uhci_out_log_cb_t *log_cb;
if (flag & BIT(LL_LOG_FLAG_ISR)) {
log_cb = ll_isr_log_cb;
source = BLE_LOG_UHCI_OUT_SOURCE_ESP_ISR;
in_isr = true;
} else if (flag & BIT(LL_LOG_FLAG_HCI)) {
log_cb = ll_hci_log_cb;
source = BLE_LOG_UHCI_OUT_SOURCE_LL_HCI;
} else {
log_cb = ll_task_log_cb;
source = BLE_LOG_UHCI_OUT_SOURCE_ESP;
}
bool omdata = flag & BIT(LL_LOG_FLAG_OMDATA);
bool need_append;
uint16_t frame_len = len + len_append + UHCI_OUT_FRAME_OVERHEAD;
if (uhci_out_log_cb_check_trans(log_cb, frame_len, &need_append)) {
need_append |= uhci_out_log_cb_write(log_cb, addr, len, addr_append,
len_append, source, omdata);
}
ll_last_write_ts = in_isr?\
pdTICKS_TO_MS(xTaskGetTickCountFromISR()):\
pdTICKS_TO_MS(xTaskGetTickCount());
if (need_append) {
if (in_isr) {
ll_ev_flags |= BIT(LL_EV_FLAG_ISR_APPEND);
UHCI_OUT_LL_PUT_EV;
} else {
uhci_out_log_cb_append_trans(log_cb);
}
}
}
IRAM_ATTR void ble_log_uhci_out_ll_log_ev_proc(void)
{
if (!ll_log_inited) {
return;
}
if (ll_ev_flags & BIT(LL_EV_FLAG_ISR_APPEND)) {
uhci_out_log_cb_append_trans(ll_isr_log_cb);
ll_ev_flags &= ~BIT(LL_EV_FLAG_ISR_APPEND);
}
if (ll_ev_flags & BIT(LL_EV_FLAG_FLUSH_LOG)) {
uhci_out_ll_log_flush();
ll_ev_flags &= ~BIT(LL_EV_FLAG_FLUSH_LOG);
}
ll_ev_flags = 0;
}
// Redirect UART Driver to BLE Log UHCI Out
int __real_uart_tx_chars(uart_port_t uart_num, const char *buffer, uint32_t len);
int __wrap_uart_tx_chars(uart_port_t uart_num, const char *buffer, uint32_t len)
{
#if UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
uhci_out_user_write_str((const uint8_t *)buffer, len);
return 0;
#else
return __real_uart_tx_chars(uart_num, buffer, len);
#endif // UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
}
int __real_uart_write_bytes(uart_port_t uart_num, const void *src, size_t size);
int __wrap_uart_write_bytes(uart_port_t uart_num, const void *src, size_t size)
{
#if UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
uhci_out_user_write_str((const uint8_t *)src, size);
return 0;
#else
return __real_uart_write_bytes(uart_num, src, size);
#endif // UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
}
int __real_uart_write_bytes_with_break(uart_port_t uart_num, const void *src, size_t size, int brk_len);
int __wrap_uart_write_bytes_with_break(uart_port_t uart_num, const void *src, size_t size, int brk_len)
{
#if UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
return __wrap_uart_write_bytes(uart_num, src, size);
#else
return __real_uart_write_bytes_with_break(uart_num, src, size, brk_len);
#endif // UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
}
void ble_log_uhci_out_dump_all(void)
{
if (!uhci_out_inited) {
return;
}
#if UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
esp_rom_output_tx_wait_idle(UHCI_OUT_UART_PORT0);
esp_rom_install_uart_printf();
#endif // UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL_SAFE(&spinlock);
if (ll_log_inited) {
esp_rom_printf("[DUMP_START:\n");
uhci_out_log_cb_dump(ll_isr_log_cb);
uhci_out_log_cb_dump(ll_task_log_cb);
uhci_out_log_cb_dump(ll_hci_log_cb);
esp_rom_printf("\n:DUMP_END]\n\n");
}
portEXIT_CRITICAL_SAFE(&spinlock);
#if UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
esp_rom_install_channel_putc(1, uhci_out_user_write_char);
#endif // UHCI_OUT_UART_PORT == UHCI_OUT_UART_PORT0
}
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
@@ -0,0 +1,176 @@
config BT_BLE_LOG_SPI_OUT_ENABLED
bool "Output ble logs to SPI bus (Experimental)"
depends on !BLE_LOG_ENABLED
default n
help
Output ble logs to SPI bus
if BT_BLE_LOG_SPI_OUT_ENABLED
config BT_BLE_LOG_SPI_OUT_UL_TASK_BUF_SIZE
int "SPI transaction buffer size for upper layer task logs"
default 512
help
SPI transaction buffer size for upper layer task logs.
There will be 2 SPI DMA buffers with the same size.
config BT_BLE_LOG_SPI_OUT_HCI_ENABLED
bool "Enable HCI log output to SPI"
default n
help
Enable logging of HCI packets to the SPI bus when BLE SPI log output is enabled.
config BT_BLE_LOG_SPI_OUT_HCI_BUF_SIZE
int "SPI transaction buffer size for HCI logs"
depends on BT_BLE_LOG_SPI_OUT_HCI_ENABLED
default 1024
help
SPI transaction buffer size for HCI logs.
There will be 2 SPI DMA buffers with the same size.
config BT_BLE_LOG_SPI_OUT_HCI_TASK_CNT
int "HCI task count"
depends on BT_BLE_LOG_SPI_OUT_HCI_ENABLED
default 1
help
HCI task count
config BT_BLE_LOG_SPI_OUT_HOST_ENABLED
bool "Enable Host log output to SPI"
default n
help
This configuration applies to the logs of both Bluedroid Host and NimBLE Host.
When BLE SPI log output is enabled, this option allows host logs to be transmitted via SPI.
config BT_BLE_LOG_SPI_OUT_HOST_BUF_SIZE
int "SPI transaction buffer size for host logs"
depends on BT_BLE_LOG_SPI_OUT_HOST_ENABLED
default 1024
help
SPI transaction buffer size for host logs.
There will be 2 SPI DMA buffers with the same size.
config BT_BLE_LOG_SPI_OUT_HOST_TASK_CNT
int "Host task count"
depends on BT_BLE_LOG_SPI_OUT_HOST_ENABLED
default 2
help
Host task count.
config BT_BLE_LOG_SPI_OUT_LL_ENABLED
bool "Enable Controller log output to SPI"
depends on BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
default n
help
Enable controller log output to SPI bus.
config BT_BLE_LOG_SPI_OUT_LL_TASK_BUF_SIZE
int "SPI transaction buffer size for lower layer task logs"
depends on BT_BLE_LOG_SPI_OUT_LL_ENABLED
default 1024
help
SPI transaction buffer size for lower layer task logs.
There will be 2 SPI DMA buffers with the same size.
config BT_BLE_LOG_SPI_OUT_LL_ISR_BUF_SIZE
int "SPI transaction buffer size for lower layer ISR logs"
depends on BT_BLE_LOG_SPI_OUT_LL_ENABLED
default 512
help
SPI transaction buffer size for lower layer ISR logs.
There will be 2 SPI DMA buffers with the same size.
config BT_BLE_LOG_SPI_OUT_LL_HCI_BUF_SIZE
int "SPI transaction buffer size for lower layer HCI logs"
depends on BT_BLE_LOG_SPI_OUT_LL_ENABLED
default 512
help
SPI transaction buffer size for upper layer HCI logs.
There will be 2 SPI DMA buffers with the same size
config BT_BLE_LOG_SPI_OUT_MOSI_IO_NUM
int "GPIO number of SPI MOSI"
default 0
help
GPIO number of SPI MOSI
config BT_BLE_LOG_SPI_OUT_SCLK_IO_NUM
int "GPIO number of SPI SCLK"
default 1
help
GPIO number of SPI SCLK
config BT_BLE_LOG_SPI_OUT_CS_IO_NUM
int "GPIO number of SPI CS"
default 2
help
GPIO number of SPI CS
config BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
bool "Enable ble log & logic analyzer log time sync"
default y
help
Enable ble log & logic analyzer log time sync
config BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM
int "GPIO number of SYNC IO"
depends on BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
default 3
help
GPIO number of SYNC IO
config BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
bool "Enable periodic buffer flush out"
default n
help
Enable periodic buffer flush out
Not recommended when SPI receiver is unavailable
config BT_BLE_LOG_SPI_OUT_FLUSH_TIMEOUT
int "Buffer flush out period in unit of ms"
depends on BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
default 1000
help
Buffer flush out period in unit of ms
config BT_BLE_LOG_SPI_OUT_LE_AUDIO_ENABLED
bool "Enable LE Audio log output to SPI"
default n
help
Enable LE Audio log output to SPI
config BT_BLE_LOG_SPI_OUT_LE_AUDIO_BUF_SIZE
int "SPI transaction buffer size for LE Audio logs"
depends on BT_BLE_LOG_SPI_OUT_LE_AUDIO_ENABLED
default 1024
help
SPI transaction buffer size for LE Audio logs.
There will be 2 SPI DMA buffers with the same size.
config BT_BLE_LOG_SPI_OUT_LE_AUDIO_TASK_CNT
int "LE audio task count"
depends on BT_BLE_LOG_SPI_OUT_LE_AUDIO_ENABLED
default 1
help
LE audio task count
config BT_BLE_LOG_SPI_OUT_MESH_ENABLED
bool "Enable BLE mesh log output to SPI"
default n
help
Enable BLE mesh log output to SPI
config BT_BLE_LOG_SPI_OUT_MESH_BUF_SIZE
int "SPI transaction buffer size for BLE mesh logs"
depends on BT_BLE_LOG_SPI_OUT_MESH_ENABLED
default 1024
help
SPI transaction buffer size for BLE mesh logs.
There will be 2 SPI DMA buffers with the same size.
config BT_BLE_LOG_SPI_OUT_MESH_TASK_CNT
int "Mesh task count"
depends on BT_BLE_LOG_SPI_OUT_MESH_ENABLED
default 3
help
Mesh task count
endif
@@ -35,6 +35,9 @@ typedef enum {
BLE_LOG_SRC_HCI,
BLE_LOG_SRC_ENCODE,
/* UART redirection (PORT 0 only) */
BLE_LOG_SRC_REDIR,
BLE_LOG_SRC_MAX,
} ble_log_src_t;
@@ -1,35 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BT_SPI_OUT_H__
#define __BT_SPI_OUT_H__
#include <stdarg.h>
#include <string.h>
#include "driver/uhci.h"
#include "driver/uart.h"
#include "driver/uart_vfs.h"
#include "esp_rom_serial_output.h"
#include "esp_timer.h"
#include "freertos/semphr.h"
// Public enums
enum {
BLE_LOG_UHCI_OUT_SOURCE_ESP = 0,
BLE_LOG_UHCI_OUT_SOURCE_ESP_ISR = 6,
BLE_LOG_UHCI_OUT_SOURCE_LL_HCI = 8,
BLE_LOG_UHCI_OUT_SOURCE_USER = 0x10,
BLE_LOG_UHCI_OUT_SOURCE_LOSS = 0xFF,
};
// Public functions
int ble_log_uhci_out_init(void);
void ble_log_uhci_out_deinit(void);
void ble_log_uhci_out_ll_write(uint32_t len, const uint8_t *addr, uint32_t len_append,
const uint8_t *addr_append, uint32_t flag);
void ble_log_uhci_out_ll_log_ev_proc(void);
void ble_log_uhci_out_dump_all(void);
#endif // __BT_SPI_OUT_H__
+1 -1
View File
@@ -46,7 +46,7 @@ bool ble_log_init(void)
}
/* Initialize BLE Log peripheral interface */
if (!ble_log_prph_init(BLE_LOG_LBM_CNT)) {
if (!ble_log_prph_init(BLE_LOG_TRANS_TOTAL_CNT)) {
goto exit;
}
+254 -83
View File
@@ -24,23 +24,34 @@ BLE_LOG_STATIC ble_log_lbm_ctx_t *lbm_ctx = NULL;
BLE_LOG_STATIC ble_log_stat_mgr_t *stat_mgr_ctx[BLE_LOG_SRC_MAX] = {0};
/* PRIVATE FUNCTION DECLARATION */
BLE_LOG_STATIC ble_log_lbm_t *ble_log_lbm_acquire(void);
BLE_LOG_STATIC
bool ble_log_lbm_acquire_trans(size_t log_len, ble_log_lbm_t **out_lbm,
ble_log_prph_trans_t ***out_trans);
BLE_LOG_STATIC void ble_log_lbm_release(ble_log_lbm_t *lbm);
BLE_LOG_STATIC
ble_log_prph_trans_t **ble_log_lbm_get_trans(ble_log_lbm_t *lbm, size_t log_len);
BLE_LOG_STATIC
void ble_log_lbm_write_trans(ble_log_prph_trans_t **trans, ble_log_src_t src_code,
const uint8_t *addr, uint16_t len,
const uint8_t *addr_append, uint16_t len_append, bool omdata);
#if CONFIG_BLE_LOG_ENH_STAT_ENABLED
#if BLE_LOG_UART_REDIR_ENABLED
BLE_LOG_STATIC
void ble_log_lbm_stream_seal(ble_log_prph_trans_t **trans, ble_log_src_t src_code);
#endif /* BLE_LOG_UART_REDIR_ENABLED */
BLE_LOG_STATIC void ble_log_stat_mgr_update(ble_log_src_t src_code, uint32_t len, bool lost);
#endif /* CONFIG_BLE_LOG_ENH_STAT_ENABLED */
/* ------------------------- */
/* PRIVATE INTERFACE */
/* ------------------------- */
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC
ble_log_lbm_t *ble_log_lbm_acquire(void)
bool ble_log_lbm_acquire_trans(size_t log_len, ble_log_lbm_t **out_lbm,
ble_log_prph_trans_t ***out_trans)
{
ble_log_lbm_t *lbm = NULL;
*out_lbm = NULL;
*out_trans = NULL;
ble_log_lbm_t *lbm;
ble_log_prph_trans_t **trans;
ble_log_lbm_t *atomic_pool;
ble_log_lbm_t *spin_lbm;
int atomic_pool_size;
@@ -55,18 +66,32 @@ ble_log_lbm_t *ble_log_lbm_acquire(void)
atomic_pool_size = BLE_LOG_LBM_ATOMIC_TASK_CNT;
}
/* Try to acquire atomic LBM first */
/* Try each atomic LBM: acquire lock, check buffer, fallback on failure */
for (int i = 0; i < atomic_pool_size; i++) {
lbm = &atomic_pool[i];
if (ble_log_cas_acquire(&(lbm->atomic_lock))) {
return lbm;
trans = ble_log_lbm_get_trans(lbm, log_len);
if (trans) {
*out_lbm = lbm;
*out_trans = trans;
return true;
}
ble_log_cas_release(&(lbm->atomic_lock));
}
}
/* Fallback to spinlock LBM */
/* Last resort: spinlock LBM */
lbm = spin_lbm;
BLE_LOG_ACQUIRE_SPIN_LOCK(&(lbm->spin_lock));
return lbm;
trans = ble_log_lbm_get_trans(lbm, log_len);
if (trans) {
*out_lbm = lbm;
*out_trans = trans;
return true;
}
BLE_LOG_RELEASE_SPIN_LOCK(&(lbm->spin_lock));
return false;
}
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC
@@ -119,22 +144,13 @@ void ble_log_lbm_write_trans(ble_log_prph_trans_t **trans, ble_log_src_t src_cod
}
/* Data integrity check */
#if CONFIG_BLE_LOG_PAYLOAD_CHECKSUM_ENABLED
uint32_t checksum = ble_log_fast_checksum((const uint8_t *)buf, BLE_LOG_FRAME_HEAD_LEN + payload_len);
#else /* !CONFIG_BLE_LOG_PAYLOAD_CHECKSUM_ENABLED */
/* Note:
* Minimum data integrity check is still required for log parsing reliability,
* which can be achieved by validating the checksum of frame head only */
uint32_t checksum = ble_log_fast_checksum((const uint8_t *)buf, BLE_LOG_FRAME_HEAD_LEN);
#endif /* CONFIG_BLE_LOG_PAYLOAD_CHECKSUM_ENABLED */
BLE_LOG_MEMCPY(buf + BLE_LOG_FRAME_HEAD_LEN + payload_len, &checksum, BLE_LOG_FRAME_TAIL_LEN);
/* Update peripheral transport */
(*trans)->pos += payload_len + BLE_LOG_FRAME_OVERHEAD;
#if CONFIG_BLE_LOG_ENH_STAT_ENABLED
ble_log_stat_mgr_update(src_code, payload_len, false);
#endif /* CONFIG_BLE_LOG_ENH_STAT_ENABLED */
/* Queue trans if full */
if (BLE_LOG_TRANS_FREE_SPACE((*trans)) <= BLE_LOG_FRAME_OVERHEAD) {
@@ -142,24 +158,50 @@ void ble_log_lbm_write_trans(ble_log_prph_trans_t **trans, ble_log_src_t src_cod
}
}
#if CONFIG_BLE_LOG_ENH_STAT_ENABLED
#if BLE_LOG_UART_REDIR_ENABLED
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC
void ble_log_lbm_stream_seal(ble_log_prph_trans_t **trans, ble_log_src_t src_code)
{
if ((*trans)->pos <= BLE_LOG_FRAME_HEAD_LEN) {
return;
}
uint16_t payload_len = (*trans)->pos - BLE_LOG_FRAME_HEAD_LEN;
ble_log_stat_mgr_t *stat_mgr = stat_mgr_ctx[src_code];
uint32_t frame_sn = BLE_LOG_GET_FRAME_SN(&(stat_mgr->frame_sn));
ble_log_frame_head_t frame_head = {
.length = payload_len,
.frame_meta = BLE_LOG_MAKE_FRAME_META(src_code, frame_sn),
};
BLE_LOG_MEMCPY((*trans)->buf, &frame_head, BLE_LOG_FRAME_HEAD_LEN);
uint32_t checksum = ble_log_fast_checksum((*trans)->buf, (*trans)->pos);
BLE_LOG_MEMCPY((*trans)->buf + (*trans)->pos, &checksum, BLE_LOG_FRAME_TAIL_LEN);
(*trans)->pos += BLE_LOG_FRAME_TAIL_LEN;
ble_log_stat_mgr_update(src_code, payload_len, false);
ble_log_rt_queue_trans(trans);
}
#endif /* BLE_LOG_UART_REDIR_ENABLED */
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC
void ble_log_stat_mgr_update(ble_log_src_t src_code, uint32_t len, bool lost)
{
/* Get statistic manager by source code */
ble_log_stat_mgr_t *stat_mgr = stat_mgr_ctx[src_code];
/* Update statistics */
/* Update aligned counters */
uint32_t bytes_cnt = len + BLE_LOG_FRAME_OVERHEAD;
if (lost) {
stat_mgr->enh_stat.lost_frame_cnt++;
stat_mgr->enh_stat.lost_bytes_cnt += bytes_cnt;
BLE_LOG_GET_FRAME_SN(&(stat_mgr->frame_sn)); /* consume SN for loss detection */
stat_mgr->lost_frame_cnt++;
stat_mgr->lost_bytes_cnt += bytes_cnt;
} else {
stat_mgr->enh_stat.written_frame_cnt++;
stat_mgr->enh_stat.written_bytes_cnt += bytes_cnt;
stat_mgr->written_frame_cnt++;
stat_mgr->written_bytes_cnt += bytes_cnt;
}
}
#endif /* CONFIG_BLE_LOG_ENH_STAT_ENABLED */
/* -------------------------- */
/* INTERNAL INTERFACE */
@@ -182,11 +224,12 @@ bool ble_log_lbm_init(void)
ble_log_lbm_t *lbm;
for (int i = 0; i < BLE_LOG_LBM_COMMON_CNT; i++) {
lbm = &(lbm_ctx->lbm_common_pool[i]);
for (int j = 0; j < BLE_LOG_TRANS_PING_PONG_BUF_CNT; j++) {
for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) {
if (!ble_log_prph_trans_init(&(lbm->trans[j]),
CONFIG_BLE_LOG_LBM_TRANS_SIZE)) {
BLE_LOG_TRANS_SIZE)) {
goto exit;
}
lbm->trans[j]->owner = (void *)lbm;
}
}
@@ -204,11 +247,12 @@ bool ble_log_lbm_init(void)
#if CONFIG_BLE_LOG_LL_ENABLED
for (int i = 0; i < BLE_LOG_LBM_LL_MAX; i++) {
lbm = &(lbm_ctx->lbm_ll_pool[i]);
for (int j = 0; j < BLE_LOG_TRANS_PING_PONG_BUF_CNT; j++) {
for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) {
if (!ble_log_prph_trans_init(&(lbm->trans[j]),
CONFIG_BLE_LOG_LBM_LL_TRANS_SIZE)) {
BLE_LOG_TRANS_LL_SIZE)) {
goto exit;
}
lbm->trans[j]->owner = (void *)lbm;
}
}
@@ -225,11 +269,6 @@ bool ble_log_lbm_init(void)
goto exit;
}
BLE_LOG_MEMSET(stat_mgr_ctx[i], 0, sizeof(ble_log_stat_mgr_t));
#if CONFIG_BLE_LOG_ENH_STAT_ENABLED
stat_mgr_ctx[i]->enh_stat.int_src_code = BLE_LOG_INT_SRC_ENH_STAT;
stat_mgr_ctx[i]->enh_stat.src_code = i;
#endif /* CONFIG_BLE_LOG_ENH_STAT_ENABLED */
}
/* Initialization done */
@@ -270,7 +309,7 @@ void ble_log_lbm_deinit(void)
ble_log_lbm_t *lbm;
for (int i = 0; i < BLE_LOG_LBM_CNT; i++) {
lbm = &(lbm_ctx->lbm_pool[i]);
for (int j = 0; j < BLE_LOG_TRANS_PING_PONG_BUF_CNT; j++) {
for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) {
ble_log_prph_trans_deinit(&(lbm->trans[j]));
}
}
@@ -281,18 +320,14 @@ void ble_log_lbm_deinit(void)
}
}
/* Note:
* The function below should be private, but when UART redirection is required,
* it would be a waste to implement get transport function again, thus
* make it available internally */
BLE_LOG_IRAM_ATTR
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC
ble_log_prph_trans_t **ble_log_lbm_get_trans(ble_log_lbm_t *lbm, size_t log_len)
{
/* Check if available buffer can contain incoming log */
ble_log_prph_trans_t **trans;
for (int i = 0; i < BLE_LOG_TRANS_PING_PONG_BUF_CNT; i++) {
for (int i = 0; i < BLE_LOG_TRANS_BUF_CNT; i++) {
trans = &(lbm->trans[lbm->trans_idx]);
if (!(*trans)->prph_owned) {
if (!__atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE)) {
/* Return if there's enough free space in current transport */
if (BLE_LOG_TRANS_FREE_SPACE((*trans)) >= (log_len + BLE_LOG_FRAME_OVERHEAD)) {
return trans;
@@ -305,14 +340,13 @@ ble_log_prph_trans_t **ble_log_lbm_get_trans(ble_log_lbm_t *lbm, size_t log_len)
}
/* Current transport unavailable, switch to the other */
lbm->trans_idx = !lbm->trans_idx;
lbm->trans_idx = (lbm->trans_idx + 1) & (BLE_LOG_TRANS_BUF_CNT - 1);
}
/* Both ping-pong buffers are unavailable */
/* All buffers are unavailable */
return NULL;
}
#if CONFIG_BLE_LOG_ENH_STAT_ENABLED
void ble_log_write_enh_stat(void)
{
BLE_LOG_REF_COUNT_ACQUIRE(&lbm_ref_count);
@@ -320,15 +354,152 @@ void ble_log_write_enh_stat(void)
goto deref;
}
/* Snapshot all sources under one critical section so the set of
* counters is mutually consistent, then write outside the lock. */
ble_log_enh_stat_t snapshots[BLE_LOG_SRC_MAX];
for (int i = 0; i < BLE_LOG_SRC_MAX; i++) {
ble_log_enh_stat_t *enh_stat = &(stat_mgr_ctx[i]->enh_stat);
ble_log_write_hex(BLE_LOG_SRC_INTERNAL, (const uint8_t *)enh_stat, sizeof(ble_log_enh_stat_t));
snapshots[i].int_src_code = BLE_LOG_INT_SRC_ENH_STAT;
snapshots[i].src_code = i;
}
BLE_LOG_ENTER_CRITICAL();
for (int i = 0; i < BLE_LOG_SRC_MAX; i++) {
BLE_LOG_MEMCPY(&snapshots[i].written_frame_cnt,
&stat_mgr_ctx[i]->written_frame_cnt,
4 * sizeof(uint32_t));
}
BLE_LOG_EXIT_CRITICAL();
for (int i = 0; i < BLE_LOG_SRC_MAX; i++) {
ble_log_write_hex(BLE_LOG_SRC_INTERNAL, (const uint8_t *)&snapshots[i], sizeof(ble_log_enh_stat_t));
}
deref:
BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count);
}
#endif /* CONFIG_BLE_LOG_ENH_STAT_ENABLED */
#if BLE_LOG_UART_REDIR_ENABLED
/* ------------------------------------------------- */
/* STREAM WRITE INTERFACE */
/* */
/* Stream mode appends raw data into a transport */
/* buffer with deferred frame encapsulation: */
/* - Header space is reserved on first write */
/* - Data is memcpy'd after the reserved header */
/* - Header and checksum are filled in at seal */
/* */
/* get_trans(lbm, 0) reuse safety: */
/* */
/* get_trans auto-queues a buffer raw (no seal) when */
/* free_space < log_len + FRAME_OVERHEAD. With */
/* log_len = 0, this triggers at free_space < 10. */
/* */
/* To prevent unsealed stream data from being sent */
/* raw, stream_write auto-seals at free_space <= 10. */
/* This guarantees that any unsealed stream buffer */
/* seen by get_trans always has free_space > 10, */
/* so get_trans returns it directly without queuing. */
/* ------------------------------------------------- */
BLE_LOG_IRAM_ATTR
void ble_log_lbm_stream_write(ble_log_lbm_t *lbm, ble_log_src_t src_code,
const uint8_t *data, size_t len)
{
while (len > 0) {
ble_log_prph_trans_t **trans = ble_log_lbm_get_trans(lbm, 0);
if (!trans) {
ble_log_stat_mgr_update(src_code, len, true);
return;
}
if ((*trans)->pos == 0) {
(*trans)->pos = BLE_LOG_FRAME_HEAD_LEN;
}
uint16_t available = BLE_LOG_TRANS_FREE_SPACE((*trans));
if (available <= BLE_LOG_FRAME_TAIL_LEN) {
ble_log_lbm_stream_seal(trans, src_code);
continue;
}
available -= BLE_LOG_FRAME_TAIL_LEN;
size_t to_write = (len < available) ? len : available;
BLE_LOG_MEMCPY((*trans)->buf + (*trans)->pos, data, to_write);
(*trans)->pos += to_write;
data += to_write;
len -= to_write;
if (BLE_LOG_TRANS_FREE_SPACE((*trans)) <= BLE_LOG_FRAME_OVERHEAD) {
ble_log_lbm_stream_seal(trans, src_code);
}
}
}
BLE_LOG_IRAM_ATTR
void ble_log_lbm_stream_flush(ble_log_lbm_t *lbm, ble_log_src_t src_code)
{
int trans_idx = lbm->trans_idx;
for (int i = 0; i < BLE_LOG_TRANS_BUF_CNT; i++) {
ble_log_prph_trans_t **trans = &(lbm->trans[trans_idx]);
if (!__atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE) &&
(*trans)->pos > BLE_LOG_FRAME_HEAD_LEN) {
ble_log_lbm_stream_seal(trans, src_code);
}
trans_idx = (trans_idx + 1) & (BLE_LOG_TRANS_BUF_CNT - 1);
}
}
#endif /* BLE_LOG_UART_REDIR_ENABLED */
BLE_LOG_STATIC void ble_log_emit_buf_util(ble_log_lbm_t *lbm, uint8_t lbm_id)
{
ble_log_buf_util_t util = {
.int_src_code = BLE_LOG_INT_SRC_BUF_UTIL,
.lbm_id = lbm_id,
.trans_cnt = BLE_LOG_TRANS_BUF_CNT,
.inflight_peak = (uint8_t)__atomic_load_n(
&lbm->trans_inflight_peak, __ATOMIC_RELAXED),
};
ble_log_write_hex(BLE_LOG_SRC_INTERNAL,
(const uint8_t *)&util, sizeof(ble_log_buf_util_t));
}
void ble_log_write_buf_util(void)
{
BLE_LOG_REF_COUNT_ACQUIRE(&lbm_ref_count);
if (!lbm_enabled) {
goto deref;
}
ble_log_emit_buf_util(&lbm_ctx->spin_task,
BLE_LOG_BUF_UTIL_MAKE_ID(BLE_LOG_BUF_UTIL_POOL_COMMON_TASK, 0));
for (int i = 0; i < BLE_LOG_LBM_ATOMIC_TASK_CNT; i++) {
ble_log_emit_buf_util(&lbm_ctx->atomic_pool_task[i],
BLE_LOG_BUF_UTIL_MAKE_ID(BLE_LOG_BUF_UTIL_POOL_COMMON_TASK, 1 + i));
}
ble_log_emit_buf_util(&lbm_ctx->spin_isr,
BLE_LOG_BUF_UTIL_MAKE_ID(BLE_LOG_BUF_UTIL_POOL_COMMON_ISR, 0));
for (int i = 0; i < BLE_LOG_LBM_ATOMIC_ISR_CNT; i++) {
ble_log_emit_buf_util(&lbm_ctx->atomic_pool_isr[i],
BLE_LOG_BUF_UTIL_MAKE_ID(BLE_LOG_BUF_UTIL_POOL_COMMON_ISR, 1 + i));
}
#if CONFIG_BLE_LOG_LL_ENABLED
ble_log_emit_buf_util(&lbm_ctx->lbm_ll_task,
BLE_LOG_BUF_UTIL_MAKE_ID(BLE_LOG_BUF_UTIL_POOL_LL, 0));
ble_log_emit_buf_util(&lbm_ctx->lbm_ll_hci,
BLE_LOG_BUF_UTIL_MAKE_ID(BLE_LOG_BUF_UTIL_POOL_LL, 1));
#endif
#if BLE_LOG_UART_REDIR_ENABLED
ble_log_lbm_t *redir_lbm = ble_log_prph_get_redir_lbm();
if (redir_lbm) {
ble_log_emit_buf_util(redir_lbm,
BLE_LOG_BUF_UTIL_MAKE_ID(BLE_LOG_BUF_UTIL_POOL_REDIR, 0));
}
#endif
deref:
BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count);
}
/* ------------------------ */
/* PUBLIC INTERFACE */
@@ -349,10 +520,9 @@ void ble_log_flush(void)
goto deref;
}
#if CONFIG_BLE_LOG_ENH_STAT_ENABLED
/* Write enhanced statistics before module disable */
ble_log_write_enh_stat();
#endif /* CONFIG_BLE_LOG_ENH_STAT_ENABLED */
ble_log_write_buf_util();
/* Write BLE Log flush log */
ble_log_info_t ble_log_info = {
@@ -378,12 +548,13 @@ void ble_log_flush(void)
for (int i = 0; i < BLE_LOG_LBM_CNT; i++) {
lbm = &(lbm_ctx->lbm_pool[i]);
int trans_idx = lbm->trans_idx;
for (int j = 0; j < BLE_LOG_TRANS_PING_PONG_BUF_CNT; j++) {
for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) {
trans = &(lbm->trans[trans_idx]);
if (!(*trans)->prph_owned && (*trans)->pos) {
if (!__atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE) &&
(*trans)->pos) {
ble_log_rt_queue_trans(trans);
}
trans_idx = !trans_idx;
trans_idx = (trans_idx + 1) & (BLE_LOG_TRANS_BUF_CNT - 1);
}
}
@@ -394,9 +565,9 @@ void ble_log_flush(void)
in_progress = false;
for (int i = 0; i < BLE_LOG_LBM_CNT; i++) {
lbm = &(lbm_ctx->lbm_pool[i]);
for (int j = 0; j < BLE_LOG_TRANS_PING_PONG_BUF_CNT; j++) {
for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) {
trans = &(lbm->trans[j]);
in_progress |= (*trans)->prph_owned;
in_progress |= __atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE);
}
}
if (in_progress) {
@@ -408,13 +579,15 @@ void ble_log_flush(void)
/* Reset statistics manager after all operations complete */
for (int i = 0; i < BLE_LOG_SRC_MAX; i++) {
BLE_LOG_MEMSET(stat_mgr_ctx[i], 0, sizeof(ble_log_stat_mgr_t));
#if CONFIG_BLE_LOG_ENH_STAT_ENABLED
/* Reinitialize enhanced statistics fields */
stat_mgr_ctx[i]->enh_stat.int_src_code = BLE_LOG_INT_SRC_ENH_STAT;
stat_mgr_ctx[i]->enh_stat.src_code = i;
#endif /* CONFIG_BLE_LOG_ENH_STAT_ENABLED */
}
for (int i = 0; i < BLE_LOG_LBM_CNT; i++) {
lbm = &(lbm_ctx->lbm_pool[i]);
__atomic_store_n(&lbm->trans_inflight, 0, __ATOMIC_RELAXED);
__atomic_store_n(&lbm->trans_inflight_peak, 0, __ATOMIC_RELAXED);
}
ble_log_prph_reset_util_counters();
/* Resume enable status */
lbm_enabled = lbm_enabled_copy;
@@ -430,12 +603,11 @@ bool ble_log_write_hex(ble_log_src_t src_code, const uint8_t *addr, size_t len)
goto exit;
}
/* Get transport */
/* Get transport from the best available pool */
size_t payload_len = len + sizeof(uint32_t);
ble_log_lbm_t *lbm = ble_log_lbm_acquire();
ble_log_prph_trans_t **trans = ble_log_lbm_get_trans(lbm, payload_len);
if (!trans) {
ble_log_lbm_release(lbm);
ble_log_lbm_t *lbm;
ble_log_prph_trans_t **trans;
if (!ble_log_lbm_acquire_trans(payload_len, &lbm, &trans)) {
goto failed;
}
@@ -452,11 +624,9 @@ bool ble_log_write_hex(ble_log_src_t src_code, const uint8_t *addr, size_t len)
return true;
failed:
#if CONFIG_BLE_LOG_ENH_STAT_ENABLED
if (lbm_inited) {
ble_log_stat_mgr_update(src_code, payload_len, true);
}
#endif /* CONFIG_BLE_LOG_ENH_STAT_ENABLED */
exit:
BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count);
return false;
@@ -487,14 +657,19 @@ void ble_log_write_hex_ll(uint32_t len, const uint8_t *addr,
}
bool omdata = flag & BIT(BLE_LOG_LL_FLAG_OMDATA);
/* Determine LBM by flag */
/* Determine LBM and get transport */
ble_log_lbm_t *lbm;
if (BLE_LOG_IN_ISR()) {
/* Reuse common LBM acquire logic */
lbm = ble_log_lbm_acquire();
ble_log_prph_trans_t **trans;
size_t payload_len;
if (BLE_LOG_IN_ISR()) {
/* os_mbuf_copydata is in flash and not safe to call from ISR */
omdata = false;
payload_len = len + len_append;
if (!ble_log_lbm_acquire_trans(payload_len, &lbm, &trans)) {
goto failed;
}
} else {
if (use_ll_task) {
lbm = &(lbm_ctx->lbm_ll_task);
@@ -506,14 +681,12 @@ void ble_log_write_hex_ll(uint32_t len, const uint8_t *addr,
}
#endif /* CONFIG_BLE_LOG_LL_HCI_LOG_PAYLOAD_LEN_LIMIT_ENABLED */
}
}
/* Get transport */
size_t payload_len = len + len_append;
ble_log_prph_trans_t **trans = ble_log_lbm_get_trans(lbm, payload_len);
if (!trans) {
ble_log_lbm_release(lbm);
goto failed;
payload_len = len + len_append;
trans = ble_log_lbm_get_trans(lbm, payload_len);
if (!trans) {
/* LL pools use LOCK_NONE, release is no-op */
goto failed;
}
}
/* Write transport */
@@ -524,11 +697,9 @@ void ble_log_write_hex_ll(uint32_t len, const uint8_t *addr,
return;
failed:
#if CONFIG_BLE_LOG_ENH_STAT_ENABLED
if (lbm_inited) {
ble_log_stat_mgr_update(src_code, payload_len, true);
}
#endif /* CONFIG_BLE_LOG_ENH_STAT_ENABLED */
exit:
BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count);
return;
@@ -550,7 +721,7 @@ void ble_log_dump_to_console(void)
for (int i = 0; i < BLE_LOG_LBM_CNT; i++) {
lbm = &(lbm_ctx->lbm_pool[i]);
trans_idx = lbm->trans_idx;
for (int j = 0; j < BLE_LOG_TRANS_PING_PONG_BUF_CNT; j++) {
for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) {
trans = lbm->trans[trans_idx];
BLE_LOG_FEED_WDT();
@@ -560,7 +731,7 @@ void ble_log_dump_to_console(void)
BLE_LOG_FEED_WDT();
}
}
trans_idx = !trans_idx;
trans_idx = (trans_idx + 1) & (BLE_LOG_TRANS_BUF_CNT - 1);
}
}
BLE_LOG_CONSOLE("\n:BLE_LOG_DUMP_END]\n\n");
+17 -5
View File
@@ -69,9 +69,8 @@ BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void ble_log_rt_task(void *pvParameters)
ble_log_rt_ts_trigger(NULL);
#endif /* CONFIG_BLE_LOG_TS_TRIGGER_TASK_EVENT */
#if CONFIG_BLE_LOG_ENH_STAT_ENABLED
ble_log_write_enh_stat();
#endif /* CONFIG_BLE_LOG_ENH_STAT_ENABLED */
ble_log_write_buf_util();
}
}
@@ -102,7 +101,7 @@ bool ble_log_rt_init(void)
/* CRITICAL:
* Queue must be initialized before creating task */
rt_queue_handle = xQueueCreate(BLE_LOG_LBM_CNT, sizeof(ble_log_prph_trans_t *));
rt_queue_handle = xQueueCreate(BLE_LOG_TRANS_TOTAL_CNT, sizeof(ble_log_prph_trans_t *));
if (!rt_queue_handle) {
goto exit;
}
@@ -172,9 +171,22 @@ void ble_log_rt_deinit(void)
BLE_LOG_IRAM_ATTR void ble_log_rt_queue_trans(ble_log_prph_trans_t **trans)
{
(*trans)->prph_owned = true;
__atomic_store_n(&(*trans)->prph_owned, true, __ATOMIC_RELAXED);
ble_log_lbm_t *lbm = (ble_log_lbm_t *)(*trans)->owner;
uint32_t inflight = __atomic_add_fetch(&lbm->trans_inflight, 1, __ATOMIC_RELAXED);
uint32_t peak = __atomic_load_n(&lbm->trans_inflight_peak, __ATOMIC_RELAXED);
while (inflight > peak) {
if (__atomic_compare_exchange_n(&lbm->trans_inflight_peak, &peak, inflight,
true, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) {
break;
}
}
if (BLE_LOG_IN_ISR()) {
xQueueSendFromISR(rt_queue_handle, trans, NULL);
BaseType_t woken = pdFALSE;
xQueueSendFromISR(rt_queue_handle, trans, &woken);
portYIELD_FROM_ISR(woken);
} else {
xQueueSend(rt_queue_handle, trans, portMAX_DELAY);
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -17,7 +17,6 @@ portMUX_TYPE ble_log_spin_lock = portMUX_INITIALIZER_UNLOCKED;
#endif /* !UNIT_TEST */
/* INTERNAL INTERFACE */
#if CONFIG_BLE_LOG_XOR_CHECKSUM_ENABLED
#include "esp_compiler.h"
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC BLE_LOG_INLINE
@@ -69,35 +68,3 @@ uint32_t ble_log_fast_checksum(const uint8_t *data, size_t len)
/* Step 6: Rotate the final result */
return ror32(checksum, start_offset_shift);
}
#else /* !CONFIG_BLE_LOG_XOR_CHECKSUM_ENABLED */
BLE_LOG_IRAM_ATTR
uint32_t ble_log_fast_checksum(const uint8_t *data, size_t len)
{
uint32_t sum = 0;
size_t i = 0;
/* Step 1: Sum up until 4-byte aligned */
while (((uintptr_t)(data + i) & 0x3) && (i < len)) {
sum += data[i++];
}
/* Step 2: Sum up 4-byte aligned blocks */
const uint32_t *p32 = (const uint32_t *)(data + i);
size_t blocks = (len - i) / 4;
for (size_t b = 0; b < blocks; b++) {
uint32_t v = p32[b];
sum += (v & 0xFF)
+ ((v >> 8) & 0xFF)
+ ((v >> 16) & 0xFF)
+ ((v >> 24) & 0xFF);
}
i += blocks * 4;
/* Step 3: Sum up remaining bytes */
while (i < len) {
sum += data[i++];
}
return sum;
}
#endif /* CONFIG_BLE_LOG_XOR_CHECKSUM_ENABLED */
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -16,6 +16,12 @@
#include "ble_log_prph.h"
#include "freertos/FreeRTOS.h"
#if defined(CONFIG_BLE_LOG_PRPH_UART_DMA) && (CONFIG_BLE_LOG_PRPH_UART_DMA_PORT == 0)
#define BLE_LOG_UART_REDIR_ENABLED (1)
#else
#define BLE_LOG_UART_REDIR_ENABLED (0)
#endif
#include "freertos/semphr.h"
/* ------------------------- */
@@ -43,7 +49,7 @@ typedef enum {
typedef struct {
int trans_idx;
ble_log_prph_trans_t *trans[BLE_LOG_TRANS_PING_PONG_BUF_CNT];
ble_log_prph_trans_t *trans[BLE_LOG_TRANS_BUF_CNT];
ble_log_lbm_lock_t lock_type;
union {
/* BLE_LOG_LBM_LOCK_NONE */
@@ -55,6 +61,8 @@ typedef struct {
/* BLE_LOG_LBM_LOCK_MUTEX */
SemaphoreHandle_t mutex;
};
uint32_t trans_inflight;
uint32_t trans_inflight_peak;
} ble_log_lbm_t;
/* --------------------------------------- */
@@ -80,7 +88,19 @@ enum {
BLE_LOG_LBM_ATOMIC_ISR_CNT)
#define BLE_LOG_LBM_COMMON_CNT (BLE_LOG_LBM_ATOMIC_CNT + BLE_LOG_LBM_SPIN_MAX)
#define BLE_LOG_LBM_CNT (BLE_LOG_LBM_COMMON_CNT + BLE_LOG_LBM_LL_MAX)
#define BLE_LOG_TRANS_CNT (BLE_LOG_LBM_CNT * BLE_LOG_TRANS_PING_PONG_BUF_CNT)
/* Derived per-buffer size from user-configured total-per-LBM budget */
#define BLE_LOG_TRANS_SIZE (CONFIG_BLE_LOG_LBM_TRANS_BUF_SIZE / BLE_LOG_TRANS_BUF_CNT)
#define BLE_LOG_TRANS_LL_SIZE (CONFIG_BLE_LOG_LBM_LL_TRANS_BUF_SIZE / BLE_LOG_TRANS_BUF_CNT)
/* Unified queue depth derivation */
#define BLE_LOG_TRANS_POOL_CNT (BLE_LOG_LBM_CNT * BLE_LOG_TRANS_BUF_CNT)
#if BLE_LOG_UART_REDIR_ENABLED
#define BLE_LOG_TRANS_REDIR_CNT BLE_LOG_TRANS_BUF_CNT
#else
#define BLE_LOG_TRANS_REDIR_CNT (0)
#endif
#define BLE_LOG_TRANS_TOTAL_CNT (BLE_LOG_TRANS_POOL_CNT + BLE_LOG_TRANS_REDIR_CNT)
/* ------------------------------------------ */
/* Log Buffer Manager Context Defines */
@@ -121,10 +141,30 @@ typedef struct {
};
} ble_log_lbm_ctx_t;
/* -------------------------------------------- */
/* Buffer Utilization Reporting Defines */
/* -------------------------------------------- */
typedef enum {
BLE_LOG_BUF_UTIL_POOL_COMMON_TASK = 0,
BLE_LOG_BUF_UTIL_POOL_COMMON_ISR = 1,
BLE_LOG_BUF_UTIL_POOL_LL = 2,
BLE_LOG_BUF_UTIL_POOL_REDIR = 3,
} ble_log_buf_util_pool_t;
typedef struct {
uint8_t int_src_code;
uint8_t lbm_id;
uint8_t trans_cnt;
uint8_t inflight_peak;
} __attribute__((packed)) ble_log_buf_util_t;
#define BLE_LOG_BUF_UTIL_MAKE_ID(pool, idx) (((pool) << 4) | ((idx) & 0x0F))
#define BLE_LOG_BUF_UTIL_GET_POOL(id) (((id) >> 4) & 0x0F)
#define BLE_LOG_BUF_UTIL_GET_INDEX(id) ((id) & 0x0F)
/* ---------------------------------------- */
/* Enhanced Statistics Data Defines */
/* ---------------------------------------- */
#if CONFIG_BLE_LOG_ENH_STAT_ENABLED
typedef struct {
uint8_t int_src_code;
uint8_t src_code;
@@ -133,16 +173,22 @@ typedef struct {
uint32_t written_bytes_cnt;
uint32_t lost_bytes_cnt;
} __attribute__((packed)) ble_log_enh_stat_t;
#endif /* CONFIG_BLE_LOG_ENH_STAT_ENABLED */
/* -------------------------------------- */
/* Log Statistics Manager Context */
/* -------------------------------------- */
typedef struct {
uint32_t frame_sn;
#if CONFIG_BLE_LOG_ENH_STAT_ENABLED
ble_log_enh_stat_t enh_stat;
#endif /* CONFIG_BLE_LOG_ENH_STAT_ENABLED */
/* Aligned live counters — updated by ble_log_stat_mgr_update(),
* snapshot by ble_log_write_enh_stat(). Natural 4-byte alignment
* ensures each load/store compiles to a single l32i/s32i on
* Xtensa/RISC-V, so individual field access is atomic without locks.
* The packed ble_log_enh_stat_t wire format is built on the stack
* only when serializing to UART. */
uint32_t written_frame_cnt;
uint32_t lost_frame_cnt;
uint32_t written_bytes_cnt;
uint32_t lost_bytes_cnt;
} ble_log_stat_mgr_t;
#define BLE_LOG_GET_FRAME_SN(VAR) __atomic_fetch_add(VAR, 1, __ATOMIC_RELAXED)
@@ -163,15 +209,39 @@ enum {
};
#endif /* CONFIG_BLE_LOG_LL_ENABLED */
/* ------------------------------- */
/* Compile-Time Guards */
/* ------------------------------- */
_Static_assert(CONFIG_BLE_LOG_LBM_TRANS_BUF_SIZE % BLE_LOG_TRANS_BUF_CNT == 0,
"Common LBM total buffer size must be a multiple of BLE_LOG_TRANS_BUF_CNT (4)");
#if CONFIG_BLE_LOG_LL_ENABLED
_Static_assert(CONFIG_BLE_LOG_LBM_LL_TRANS_BUF_SIZE % BLE_LOG_TRANS_BUF_CNT == 0,
"LL LBM total buffer size must be a multiple of BLE_LOG_TRANS_BUF_CNT (4)");
#endif
_Static_assert(CONFIG_BLE_LOG_LBM_TRANS_BUF_SIZE / BLE_LOG_TRANS_BUF_CNT >= BLE_LOG_FRAME_OVERHEAD,
"Common LBM per-buffer size too small for a single frame");
_Static_assert((BLE_LOG_TRANS_BUF_CNT & (BLE_LOG_TRANS_BUF_CNT - 1)) == 0,
"BLE_LOG_TRANS_BUF_CNT must be a power of 2");
_Static_assert(1 + BLE_LOG_LBM_ATOMIC_TASK_CNT <= 16,
"Common task pool exceeds lbm_id 4-bit index limit (max 15)");
_Static_assert(1 + BLE_LOG_LBM_ATOMIC_ISR_CNT <= 16,
"Common ISR pool exceeds lbm_id 4-bit index limit (max 15)");
_Static_assert(BLE_LOG_TRANS_BUF_CNT <= 255,
"BLE_LOG_TRANS_BUF_CNT must fit in uint8_t for ble_log_buf_util_t");
/* --------------------------- */
/* Internal Interfaces */
/* --------------------------- */
bool ble_log_lbm_init(void);
void ble_log_lbm_deinit(void);
ble_log_prph_trans_t **ble_log_lbm_get_trans(ble_log_lbm_t *lbm, size_t log_len);
void ble_log_lbm_enable(bool enable);
#if CONFIG_BLE_LOG_ENH_STAT_ENABLED
void ble_log_write_enh_stat(void);
#endif /* CONFIG_BLE_LOG_ENH_STAT_ENABLED */
void ble_log_write_buf_util(void);
#if BLE_LOG_UART_REDIR_ENABLED
void ble_log_lbm_stream_write(ble_log_lbm_t *lbm, ble_log_src_t src_code,
const uint8_t *data, size_t len);
void ble_log_lbm_stream_flush(ble_log_lbm_t *lbm, ble_log_src_t src_code);
ble_log_lbm_t *ble_log_prph_get_redir_lbm(void);
#endif
#endif /* __BLE_LOG_LBM_H__ */
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -15,17 +15,20 @@
/* TYPEDEF */
typedef struct {
volatile bool prph_owned;
bool prph_owned;
uint8_t *buf;
uint16_t size;
uint16_t pos;
/* Peripheral implementation specific context */
void *ctx;
/* Opaque back-reference to owning LBM, set once at init */
void *owner;
} ble_log_prph_trans_t;
#define BLE_LOG_TRANS_FREE_SPACE(trans) (trans->size - trans->pos)
#define BLE_LOG_TRANS_PING_PONG_BUF_CNT (2)
#define BLE_LOG_TRANS_BUF_CNT (4)
/* INTERFACE */
bool ble_log_prph_init(size_t trans_cnt);
@@ -33,5 +36,6 @@ void ble_log_prph_deinit(void);
bool ble_log_prph_trans_init(ble_log_prph_trans_t **trans, size_t trans_size);
void ble_log_prph_trans_deinit(ble_log_prph_trans_t **trans);
void ble_log_prph_send_trans(ble_log_prph_trans_t *trans);
void ble_log_prph_reset_util_counters(void);
#endif /* __BLE_LOG_PRPH_H__ */
@@ -130,7 +130,7 @@ bool ble_log_cas_acquire(volatile bool *cas_lock);
void ble_log_cas_release(volatile bool *cas_lock);
#endif /* UNIT_TEST */
#define BLE_LOG_VERSION (3)
#define BLE_LOG_VERSION (4)
/* TYPEDEF */
typedef enum {
@@ -139,6 +139,7 @@ typedef enum {
BLE_LOG_INT_SRC_ENH_STAT,
BLE_LOG_INT_SRC_INFO,
BLE_LOG_INT_SRC_FLUSH,
BLE_LOG_INT_SRC_BUF_UTIL,
BLE_LOG_INT_SRC_MAX,
} ble_log_int_src_t;
@@ -9,6 +9,7 @@
/* INCLUDE */
#include "ble_log_prph_dummy.h"
#include "ble_log_lbm.h"
/* INTERFACE */
bool ble_log_prph_init(size_t trans_cnt)
@@ -80,7 +81,16 @@ void ble_log_prph_trans_deinit(ble_log_prph_trans_t **trans)
*trans = NULL;
}
/* Dummy transport has no DMA/hardware -- recycle the buffer immediately
* so that ble_log_lbm_get_trans() can reuse it and ble_log_flush() does
* not hang waiting for prph_owned to clear. Real peripherals (UART DMA,
* SPI DMA) do the same work inside their asynchronous tx_done callbacks. */
void ble_log_prph_send_trans(ble_log_prph_trans_t *trans)
{
(void)trans;
trans->pos = 0;
ble_log_lbm_t *lbm = (ble_log_lbm_t *)trans->owner;
__atomic_fetch_sub(&lbm->trans_inflight, 1, __ATOMIC_RELAXED);
__atomic_store_n(&trans->prph_owned, false, __ATOMIC_RELEASE);
}
void ble_log_prph_reset_util_counters(void) {}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -9,6 +9,7 @@
/* INCLUDE */
#include "ble_log_prph_spi_master_dma.h"
#include "ble_log_lbm.h"
#include "esp_timer.h"
@@ -35,7 +36,9 @@ BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void spi_master_dma_tx_done_cb(spi_transaction_
/* Recycle transport */
ble_log_prph_trans_t *trans = (ble_log_prph_trans_t *)(spi_trans->user);
trans->pos = 0;
trans->prph_owned = false;
ble_log_lbm_t *lbm = (ble_log_lbm_t *)trans->owner;
__atomic_fetch_sub(&lbm->trans_inflight, 1, __ATOMIC_RELAXED);
__atomic_store_n(&trans->prph_owned, false, __ATOMIC_RELEASE);
}
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void spi_master_dma_pre_tx_cb(spi_transaction_t *spi_trans)
@@ -179,6 +182,10 @@ BLE_LOG_IRAM_ATTR void ble_log_prph_send_trans(ble_log_prph_trans_t *trans)
spi_trans->length = (trans->pos << 3);
spi_trans->rxlength = 0;
if (spi_device_queue_trans(dev_handle, spi_trans, 0) != ESP_OK) {
trans->prph_owned = false;
ble_log_lbm_t *lbm = (ble_log_lbm_t *)trans->owner;
__atomic_fetch_sub(&lbm->trans_inflight, 1, __ATOMIC_RELAXED);
__atomic_store_n(&trans->prph_owned, false, __ATOMIC_RELEASE);
}
}
void ble_log_prph_reset_util_counters(void) {}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -10,11 +10,10 @@
/* INCLUDE */
#include "ble_log_prph_uart_dma.h"
#include "ble_log.h"
#include "ble_log_lbm.h"
#if BLE_LOG_PRPH_UART_DMA_REDIR
#include "ble_log.h"
#include "ble_log_rt.h"
#include "ble_log_lbm.h"
#include "esp_timer.h"
#include "driver/uart.h"
@@ -27,7 +26,7 @@
#define BLE_LOG_UART_DMA_BURST_SIZE (32)
#if BLE_LOG_PRPH_UART_DMA_REDIR
#define BLE_LOG_UART_REDIR_BUF_SIZE (512)
#define BLE_LOG_UART_REDIR_FLUSH_TIMEOUT (100)
#define BLE_LOG_UART_REDIR_FLUSH_PERIOD_US (1000 * 1000)
#endif /* BLE_LOG_PRPH_UART_DMA_REDIR */
/* VARIABLE */
@@ -36,7 +35,6 @@ BLE_LOG_STATIC uhci_controller_handle_t dev_handle = NULL;
#if BLE_LOG_PRPH_UART_DMA_REDIR
BLE_LOG_STATIC bool uart_driver_inited = false;
BLE_LOG_STATIC ble_log_lbm_t *redir_lbm = NULL;
BLE_LOG_STATIC uint32_t redir_last_write_ts = 0;
BLE_LOG_STATIC esp_timer_handle_t redir_flush_timer = NULL;
#endif /* BLE_LOG_PRPH_UART_DMA_REDIR */
@@ -58,24 +56,26 @@ BLE_LOG_IRAM_ATTR BLE_LOG_STATIC bool uart_dma_tx_done_cb(
);
ble_log_prph_trans_t *trans = uart_trans_ctx->trans;
trans->pos = 0;
trans->prph_owned = false;
ble_log_lbm_t *lbm = (ble_log_lbm_t *)trans->owner;
__atomic_fetch_sub(&lbm->trans_inflight, 1, __ATOMIC_RELAXED);
__atomic_store_n(&trans->prph_owned, false, __ATOMIC_RELEASE);
return true;
}
#if BLE_LOG_PRPH_UART_DMA_REDIR
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void esp_timer_cb_flush_log(void)
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void esp_timer_cb_flush_log(void *arg)
{
uint32_t os_ts = pdTICKS_TO_MS(xTaskGetTickCount());
if ((os_ts - redir_last_write_ts) > BLE_LOG_UART_REDIR_FLUSH_TIMEOUT) {
xSemaphoreTake(redir_lbm->mutex, portMAX_DELAY);
int trans_idx = redir_lbm->trans_idx;
for (int i = 0; i < BLE_LOG_TRANS_PING_PONG_BUF_CNT; i++) {
ble_log_prph_trans_t **trans = &(redir_lbm->trans[trans_idx]);
if (!(*trans)->prph_owned && (*trans)->pos) {
ble_log_rt_queue_trans(trans);
}
trans_idx = !trans_idx;
}
(void)arg;
if (!prph_inited) {
return;
}
/* Non-blocking trylock: skip if mutex is held by a writer.
* The periodic timer will retry on the next tick.
* stream_flush is a no-op when buffer is empty. */
if (xSemaphoreTake(redir_lbm->mutex, 0) == pdTRUE) {
ble_log_lbm_stream_flush(redir_lbm, BLE_LOG_SRC_REDIR);
xSemaphoreGive(redir_lbm->mutex);
}
}
@@ -127,16 +127,18 @@ bool ble_log_prph_init(size_t trans_cnt)
goto exit;
}
BLE_LOG_MEMSET(redir_lbm, 0, sizeof(ble_log_lbm_t));
redir_lbm->lock_type = BLE_LOG_LBM_LOCK_MUTEX;
/* Transport initialization */
for (int i = 0; i < BLE_LOG_TRANS_PING_PONG_BUF_CNT; i++) {
for (int i = 0; i < BLE_LOG_TRANS_BUF_CNT; i++) {
if (!ble_log_prph_trans_init(&(redir_lbm->trans[i]),
BLE_LOG_UART_REDIR_BUF_SIZE)) {
goto exit;
}
redir_lbm->trans[i]->owner = (void *)redir_lbm;
}
/* Mutex initilaization */
/* Mutex initialization */
redir_lbm->mutex = xSemaphoreCreateMutex();
if (!redir_lbm->mutex) {
goto exit;
@@ -151,7 +153,7 @@ bool ble_log_prph_init(size_t trans_cnt)
/* Initialize periodic flush timer */
esp_timer_create_args_t timer_args = {
.callback = (esp_timer_cb_t)esp_timer_cb_flush_log,
.callback = esp_timer_cb_flush_log,
.dispatch_method = ESP_TIMER_TASK,
};
if (esp_timer_create(&timer_args, &redir_flush_timer) != ESP_OK) {
@@ -161,7 +163,7 @@ bool ble_log_prph_init(size_t trans_cnt)
prph_inited = true;
#if BLE_LOG_PRPH_UART_DMA_REDIR
esp_timer_start_periodic(redir_flush_timer, BLE_LOG_UART_REDIR_FLUSH_TIMEOUT);
esp_timer_start_periodic(redir_flush_timer, BLE_LOG_UART_REDIR_FLUSH_PERIOD_US);
#endif /* BLE_LOG_PRPH_UART_DMA_REDIR */
return true;
@@ -190,15 +192,15 @@ void ble_log_prph_deinit(void)
/* Release redirection LBM */
if (redir_lbm) {
/* Release mutex */
if (redir_lbm->mutex) {
xSemaphoreTake(redir_lbm->mutex, portMAX_DELAY);
ble_log_lbm_stream_flush(redir_lbm, BLE_LOG_SRC_REDIR);
xSemaphoreGive(redir_lbm->mutex);
vSemaphoreDelete(redir_lbm->mutex);
}
/* Release transport */
for (int i = 0; i < BLE_LOG_TRANS_PING_PONG_BUF_CNT; i++) {
for (int i = 0; i < BLE_LOG_TRANS_BUF_CNT; i++) {
ble_log_prph_trans_deinit(&(redir_lbm->trans[i]));
}
@@ -272,7 +274,9 @@ void ble_log_prph_trans_deinit(ble_log_prph_trans_t **trans)
BLE_LOG_IRAM_ATTR void ble_log_prph_send_trans(ble_log_prph_trans_t *trans)
{
if (uhci_transmit(dev_handle, trans->buf, trans->pos) != ESP_OK) {
trans->prph_owned = false;
ble_log_lbm_t *lbm = (ble_log_lbm_t *)trans->owner;
__atomic_fetch_sub(&lbm->trans_inflight, 1, __ATOMIC_RELAXED);
__atomic_store_n(&trans->prph_owned, false, __ATOMIC_RELEASE);
}
}
@@ -282,17 +286,8 @@ BLE_LOG_IRAM_ATTR BLE_LOG_STATIC
void ble_log_redir_uart_tx_chars(const char *src, size_t len)
{
xSemaphoreTake(redir_lbm->mutex, portMAX_DELAY);
ble_log_prph_trans_t **trans = ble_log_lbm_get_trans(redir_lbm, len);
if (trans) {
uint8_t *buf = (*trans)->buf + (*trans)->pos;
BLE_LOG_MEMCPY(buf, src, len);
(*trans)->pos += len;
redir_last_write_ts = pdTICKS_TO_MS(xTaskGetTickCount());
if (BLE_LOG_TRANS_FREE_SPACE((*trans)) <= BLE_LOG_FRAME_OVERHEAD) {
ble_log_rt_queue_trans(trans);
}
}
ble_log_lbm_stream_write(redir_lbm, BLE_LOG_SRC_REDIR,
(const uint8_t *)src, len);
xSemaphoreGive(redir_lbm->mutex);
}
@@ -326,4 +321,19 @@ int __wrap_uart_write_bytes_with_break(uart_port_t uart_num, const void *src, si
return __wrap_uart_write_bytes(uart_num, src, size);
}
}
ble_log_lbm_t *ble_log_prph_get_redir_lbm(void)
{
return redir_lbm;
}
#endif /* BLE_LOG_PRPH_UART_DMA_REDIR */
void ble_log_prph_reset_util_counters(void)
{
#if BLE_LOG_PRPH_UART_DMA_REDIR
if (redir_lbm) {
__atomic_store_n(&redir_lbm->trans_inflight, 0, __ATOMIC_RELAXED);
__atomic_store_n(&redir_lbm->trans_inflight_peak, 0, __ATOMIC_RELAXED);
}
#endif
}
@@ -282,104 +282,6 @@ config BT_LE_CONTROLLER_TASK_STACK_SIZE
This configures stack size of NimBLE controller task
menu "Controller debug features"
menuconfig BT_LE_CONTROLLER_LOG_ENABLED
bool "Controller log enable"
default n
help
Enable controller log
config BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
bool "Utilize BLE Log v2 for controller log"
depends on BLE_LOG_ENABLED
default y
help
Utilize BLE Log v2 for controller log
if !BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
config BT_LE_CONTROLLER_LOG_CTRL_ENABLED
bool "enable controller log module"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default y
help
Enable controller log module
config BT_LE_CONTROLLER_LOG_HCI_ENABLED
bool "enable HCI log module"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default y
help
Enable hci log module
config BT_LE_CONTROLLER_LOG_DUMP_ONLY
bool "Controller log dump mode only"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default y
help
Only operate in dump mode
config BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
bool "Output ble controller logs to SPI bus (Experimental)"
depends on BT_LE_CONTROLLER_LOG_ENABLED
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
select BT_BLE_LOG_SPI_OUT_ENABLED
default n
help
Output ble controller logs to SPI bus
config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
bool "Store ble controller logs to flash(Experimental)"
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
depends on BT_LE_CONTROLLER_LOG_ENABLED
default n
help
Store ble controller logs to flash memory.
config BT_LE_CONTROLLER_LOG_PARTITION_SIZE
int "size of ble controller log partition(Multiples of 4K)"
depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
default 65536
help
The size of ble controller log partition shall be a multiples of 4K.
The name of log partition shall be "bt_ctrl_log".
The partition type shall be ESP_PARTITION_TYPE_DATA.
The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY.
config BT_LE_LOG_CTRL_BUF1_SIZE
int "size of the first BLE controller LOG buffer"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default 4096
help
Configure the size of the first BLE controller LOG buffer.
config BT_LE_LOG_CTRL_BUF2_SIZE
int "size of the second BLE controller LOG buffer"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default 1024
help
Configure the size of the second BLE controller LOG buffer.
config BT_LE_LOG_HCI_BUF_SIZE
int "size of the BLE HCI LOG buffer"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default 4096
help
Configure the size of the BLE HCI LOG buffer.
endif
config BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE
bool "Enable wrap panic handler"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default n
help
Wrap esp_panic_handler to get controller logs when PC pointer exception crashes.
config BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE
bool "Enable esp_task_wdt_isr_user_handler implementation"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default n
help
Implement esp_task_wdt_isr_user_handler to get controller logs when task wdt issue is triggered.
config BT_LE_MEM_CHECK_ENABLED
bool "Enable memory allocation check"
default n
@@ -624,6 +624,7 @@ menu "Controller debug log Options (Experimental)"
depends on BT_CTRL_LE_LOG_EN
int "The level of BLE log"
range 0 5
default 2 if BT_LOG_CRITICAL_ONLY_CTRL
default 1
config BT_CTRL_LE_LOG_BUF1_SIZE
-124
View File
@@ -308,130 +308,6 @@ config BT_LE_CONTROLLER_TASK_STACK_SIZE
This configures stack size of NimBLE controller task
menu "Controller debug features"
menuconfig BT_LE_CONTROLLER_LOG_ENABLED
bool "Controller log enable"
default n
help
Enable controller log
config BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
bool "Utilize BLE Log v2 for controller log"
depends on BLE_LOG_ENABLED
default y
help
Utilize BLE Log v2 for controller log
if !BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
config BT_LE_CONTROLLER_LOG_CTRL_ENABLED
bool "enable controller log module"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default y
help
Enable controller log module
config BT_LE_CONTROLLER_LOG_HCI_ENABLED
bool "enable HCI log module"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default y
help
Enable hci log module
config BT_LE_CONTROLLER_LOG_DUMP_ONLY
bool "Controller log dump mode only"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default y
help
Only operate in dump mode
config BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
bool "Output ble controller logs to SPI bus (Experimental)"
depends on BT_LE_CONTROLLER_LOG_ENABLED
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
select BT_BLE_LOG_SPI_OUT_ENABLED
default n
help
Output ble controller logs to SPI bus
config BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
bool "Output ble controller logs via UART DMA (Experimental)"
depends on BT_LE_CONTROLLER_LOG_ENABLED
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
depends on !BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
select BT_BLE_LOG_UHCI_OUT_ENABLED
default y
help
Output ble controller logs via UART DMA
config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
bool "Store ble controller logs to flash(Experimental)"
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
depends on BT_LE_CONTROLLER_LOG_ENABLED
default n
help
Store ble controller logs to flash memory.
config BT_LE_CONTROLLER_LOG_PARTITION_SIZE
int "size of ble controller log partition(Multiples of 4K)"
depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
default 65536
help
The size of ble controller log partition shall be a multiples of 4K.
The name of log partition shall be "bt_ctrl_log".
The partition type shall be ESP_PARTITION_TYPE_DATA.
The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY.
config BT_LE_LOG_CTRL_BUF1_SIZE
int "size of the first BLE controller LOG buffer"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default 4096
help
Configure the size of the first BLE controller LOG buffer.
config BT_LE_LOG_CTRL_BUF2_SIZE
int "size of the second BLE controller LOG buffer"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default 1024
help
Configure the size of the second BLE controller LOG buffer.
config BT_LE_LOG_HCI_BUF_SIZE
int "size of the BLE HCI LOG buffer"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default 4096
help
Configure the size of the BLE HCI LOG buffer.
endif
config BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE
bool "Enable wrap panic handler"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default n
help
Wrap esp_panic_handler to get controller logs when PC pointer exception crashes.
config BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE
bool "Enable esp_task_wdt_isr_user_handler implementation"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default n
help
Implement esp_task_wdt_isr_user_handler to get controller logs when task wdt issue is triggered.
config BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL
int "The output level of controller log"
depends on BT_LE_CONTROLLER_LOG_ENABLED
range 0 5
default 1
help
The output level of controller log.
config BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH
hex "The switch of module log output"
depends on BT_LE_CONTROLLER_LOG_ENABLED
range 0 0xFFFFFFFF
default 0xFFFFFFFF
help
The switch of module log output, this is an unsigned 32-bit hexadecimal value.
config BT_LE_ERROR_SIM_ENABLED
bool "Enable controller features for internal testing"
default n
+5 -35
View File
@@ -63,10 +63,6 @@
#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#include "ble_log/ble_log_spi_out.h"
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#include "ble_log/ble_log_uhci_out.h"
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#endif /* CONFIG_BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2 */
/* Macro definition
@@ -210,9 +206,9 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer
const uint8_t *our_priv_key, uint8_t *out_dhkey);
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
#if !CONFIG_BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag);
#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void);
#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
@@ -285,20 +281,10 @@ esp_err_t esp_bt_controller_log_init(void)
}
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
if (ble_log_uhci_out_init() != 0) {
goto uhci_out_init_failed;
}
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
if (r_ble_log_init_simple(ble_log_spi_out_ll_write, ble_log_spi_out_ll_log_ev_proc) != 0) {
goto log_init_failed;
}
#elif CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
if (r_ble_log_init_simple(ble_log_uhci_out_ll_write, ble_log_uhci_out_ll_log_ev_proc) != 0) {
goto log_init_failed;
}
#else
uint8_t buffers = 0;
#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED
@@ -329,8 +315,6 @@ esp_err_t esp_bt_controller_log_init(void)
ctrl_level_init_failed:
#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
r_ble_log_deinit_simple();
#elif CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
r_ble_log_deinit_simple();
#else
r_ble_log_deinit_async();
#endif
@@ -339,10 +323,6 @@ log_init_failed:
ble_log_spi_out_deinit();
spi_out_init_failed:
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
ble_log_uhci_out_deinit();
uhci_out_init_failed:
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
return ESP_FAIL;
}
@@ -352,14 +332,8 @@ void esp_bt_controller_log_deinit(void)
ble_log_spi_out_deinit();
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
ble_log_uhci_out_deinit();
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
r_ble_log_deinit_simple();
#elif CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
r_ble_log_deinit_simple();
#else
r_ble_log_deinit_async();
#endif
@@ -1531,7 +1505,7 @@ void esp_ble_controller_log_dump_all(bool output)
ble_log_dump_to_console();
}
#else /* !CONFIG_BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2 */
#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag)
{
bool end = (flag & BIT(BLE_LOG_INTERFACE_FLAG_END));
@@ -1553,7 +1527,7 @@ static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, u
portEXIT_CRITICAL_SAFE(&spinlock);
#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
}
#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
void esp_ble_controller_log_dump_all(bool output)
{
@@ -1561,13 +1535,9 @@ void esp_ble_controller_log_dump_all(bool output)
ble_log_spi_out_dump_all();
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
ble_log_uhci_out_dump_all();
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
esp_bt_read_ctrl_log_from_flash(output);
#elif !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#elif !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL_SAFE(&spinlock);
esp_panic_handler_feed_wdts();
-124
View File
@@ -339,130 +339,6 @@ config BT_LE_CONTROLLER_TASK_STACK_SIZE
This configures stack size of NimBLE controller task
menu "Controller debug features"
menuconfig BT_LE_CONTROLLER_LOG_ENABLED
bool "Controller log enable"
default n
help
Enable controller log
config BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
bool "Utilize BLE Log v2 for controller log"
depends on BLE_LOG_ENABLED
default y
help
Utilize BLE Log v2 for controller log
if !BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
config BT_LE_CONTROLLER_LOG_CTRL_ENABLED
bool "enable controller log module"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default y
help
Enable controller log module
config BT_LE_CONTROLLER_LOG_HCI_ENABLED
bool "enable HCI log module"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default y
help
Enable hci log module
config BT_LE_CONTROLLER_LOG_DUMP_ONLY
bool "Controller log dump mode only"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default y
help
Only operate in dump mode
config BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
bool "Output ble controller logs to SPI bus (Experimental)"
depends on BT_LE_CONTROLLER_LOG_ENABLED
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
select BT_BLE_LOG_SPI_OUT_ENABLED
default n
help
Output ble controller logs to SPI bus
config BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
bool "Output ble controller logs via UART DMA (Experimental)"
depends on BT_LE_CONTROLLER_LOG_ENABLED
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
depends on !BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
select BT_BLE_LOG_UHCI_OUT_ENABLED
default y
help
Output ble controller logs via UART DMA
config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
bool "Store ble controller logs to flash(Experimental)"
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
depends on BT_LE_CONTROLLER_LOG_ENABLED
default n
help
Store ble controller logs to flash memory.
config BT_LE_CONTROLLER_LOG_PARTITION_SIZE
int "size of ble controller log partition(Multiples of 4K)"
depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
default 65536
help
The size of ble controller log partition shall be a multiples of 4K.
The name of log partition shall be "bt_ctrl_log".
The partition type shall be ESP_PARTITION_TYPE_DATA.
The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY.
config BT_LE_LOG_CTRL_BUF1_SIZE
int "size of the first BLE controller LOG buffer"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default 4096
help
Configure the size of the first BLE controller LOG buffer.
config BT_LE_LOG_CTRL_BUF2_SIZE
int "size of the second BLE controller LOG buffer"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default 1024
help
Configure the size of the second BLE controller LOG buffer.
config BT_LE_LOG_HCI_BUF_SIZE
int "size of the BLE HCI LOG buffer"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default 4096
help
Configure the size of the BLE HCI LOG buffer.
endif
config BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE
bool "Enable wrap panic handler"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default n
help
Wrap esp_panic_handler to get controller logs when PC pointer exception crashes.
config BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE
bool "Enable esp_task_wdt_isr_user_handler implementation"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default n
help
Implement esp_task_wdt_isr_user_handler to get controller logs when task wdt issue is triggered.
config BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL
int "The output level of controller log"
depends on BT_LE_CONTROLLER_LOG_ENABLED
range 0 5
default 1
help
The output level of controller log.
config BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH
hex "The switch of module log output"
depends on BT_LE_CONTROLLER_LOG_ENABLED
range 0 0xFFFFFFFF
default 0xFFFFFFFF
help
The switch of module log output, this is an unsigned 32-bit hexadecimal value.
config BT_LE_ERROR_SIM_ENABLED
bool "Enable controller features for internal testing"
default n
+5 -35
View File
@@ -67,10 +67,6 @@
#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#include "ble_log/ble_log_spi_out.h"
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#include "ble_log/ble_log_uhci_out.h"
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#endif /* CONFIG_BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2 */
/* Macro definition
@@ -224,9 +220,9 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer
const uint8_t *our_priv_key, uint8_t *out_dhkey);
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
#if !CONFIG_BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag);
#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void);
#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
@@ -300,20 +296,10 @@ esp_err_t esp_bt_controller_log_init(void)
}
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
if (ble_log_uhci_out_init() != 0) {
goto uhci_out_init_failed;
}
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
if (r_ble_log_init_simple(ble_log_spi_out_ll_write, ble_log_spi_out_ll_log_ev_proc) != 0) {
goto log_init_failed;
}
#elif CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
if (r_ble_log_init_simple(ble_log_uhci_out_ll_write, ble_log_uhci_out_ll_log_ev_proc) != 0) {
goto log_init_failed;
}
#else
uint8_t buffers = 0;
#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED
@@ -344,8 +330,6 @@ esp_err_t esp_bt_controller_log_init(void)
ctrl_level_init_failed:
#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
r_ble_log_deinit_simple();
#elif CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
r_ble_log_deinit_simple();
#else
r_ble_log_deinit_async();
#endif
@@ -354,10 +338,6 @@ log_init_failed:
ble_log_spi_out_deinit();
spi_out_init_failed:
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
ble_log_uhci_out_deinit();
uhci_out_init_failed:
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
return ESP_FAIL;
}
@@ -367,14 +347,8 @@ void esp_bt_controller_log_deinit(void)
ble_log_spi_out_deinit();
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
ble_log_uhci_out_deinit();
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
r_ble_log_deinit_simple();
#elif CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
r_ble_log_deinit_simple();
#else
r_ble_log_deinit_async();
#endif
@@ -1613,7 +1587,7 @@ void esp_ble_controller_log_dump_all(bool output)
ble_log_dump_to_console();
}
#else /* !CONFIG_BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2 */
#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag)
{
bool end = (flag & BIT(BLE_LOG_INTERFACE_FLAG_END));
@@ -1635,7 +1609,7 @@ static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, u
portEXIT_CRITICAL_SAFE(&spinlock);
#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
}
#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
void esp_ble_controller_log_dump_all(bool output)
{
@@ -1643,13 +1617,9 @@ void esp_ble_controller_log_dump_all(bool output)
ble_log_spi_out_dump_all();
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
ble_log_uhci_out_dump_all();
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
esp_bt_read_ctrl_log_from_flash(output);
#elif !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#elif !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL_SAFE(&spinlock);
esp_panic_handler_feed_wdts();
-124
View File
@@ -333,130 +333,6 @@ config BT_LE_CONTROLLER_TASK_STACK_SIZE
This configures stack size of NimBLE controller task
menu "Controller debug features"
menuconfig BT_LE_CONTROLLER_LOG_ENABLED
bool "Controller log enable"
default n
help
Enable controller log
config BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
bool "Utilize BLE Log v2 for controller log"
depends on BLE_LOG_ENABLED
default y
help
Utilize BLE Log v2 for controller log
if !BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
config BT_LE_CONTROLLER_LOG_CTRL_ENABLED
bool "enable controller log module"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default y
help
Enable controller log module
config BT_LE_CONTROLLER_LOG_HCI_ENABLED
bool "enable HCI log module"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default y
help
Enable hci log module
config BT_LE_CONTROLLER_LOG_DUMP_ONLY
bool "Controller log dump mode only"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default y
help
Only operate in dump mode
config BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
bool "Output ble controller logs to SPI bus (Experimental)"
depends on BT_LE_CONTROLLER_LOG_ENABLED
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
select BT_BLE_LOG_SPI_OUT_ENABLED
default n
help
Output ble controller logs to SPI bus
config BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
bool "Output ble controller logs via UART DMA (Experimental)"
depends on BT_LE_CONTROLLER_LOG_ENABLED
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
depends on !BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
select BT_BLE_LOG_UHCI_OUT_ENABLED
default y
help
Output ble controller logs via UART DMA
config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
bool "Store ble controller logs to flash(Experimental)"
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
depends on BT_LE_CONTROLLER_LOG_ENABLED
default n
help
Store ble controller logs to flash memory.
config BT_LE_CONTROLLER_LOG_PARTITION_SIZE
int "size of ble controller log partition(Multiples of 4K)"
depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
default 65536
help
The size of ble controller log partition shall be a multiples of 4K.
The name of log partition shall be "bt_ctrl_log".
The partition type shall be ESP_PARTITION_TYPE_DATA.
The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY.
config BT_LE_LOG_CTRL_BUF1_SIZE
int "size of the first BLE controller LOG buffer"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default 4096
help
Configure the size of the first BLE controller LOG buffer.
config BT_LE_LOG_CTRL_BUF2_SIZE
int "size of the second BLE controller LOG buffer"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default 1024
help
Configure the size of the second BLE controller LOG buffer.
config BT_LE_LOG_HCI_BUF_SIZE
int "size of the BLE HCI LOG buffer"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default 4096
help
Configure the size of the BLE HCI LOG buffer.
endif
config BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE
bool "Enable wrap panic handler"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default n
help
Wrap esp_panic_handler to get controller logs when PC pointer exception crashes.
config BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE
bool "Enable esp_task_wdt_isr_user_handler implementation"
depends on BT_LE_CONTROLLER_LOG_ENABLED
default n
help
Implement esp_task_wdt_isr_user_handler to get controller logs when task wdt issue is triggered.
config BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL
int "The output level of controller log"
depends on BT_LE_CONTROLLER_LOG_ENABLED
range 0 5
default 1
help
The output level of controller log.
config BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH
hex "The switch of module log output"
depends on BT_LE_CONTROLLER_LOG_ENABLED
range 0 0xFFFFFFFF
default 0xFFFFFFFF
help
The switch of module log output, this is an unsigned 32-bit hexadecimal value.
config BT_LE_ERROR_SIM_ENABLED
bool "Enable controller features for internal testing"
default n
+5 -35
View File
@@ -62,10 +62,6 @@
#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#include "ble_log/ble_log_spi_out.h"
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#include "ble_log/ble_log_uhci_out.h"
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#endif /* CONFIG_BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2 */
/* Macro definition
@@ -218,9 +214,9 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer
const uint8_t *our_priv_key, uint8_t *out_dhkey);
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
#if !CONFIG_BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag);
#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void);
#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
@@ -293,20 +289,10 @@ esp_err_t esp_bt_controller_log_init(void)
}
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
if (ble_log_uhci_out_init() != 0) {
goto uhci_out_init_failed;
}
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
if (r_ble_log_init_simple(ble_log_spi_out_ll_write, ble_log_spi_out_ll_log_ev_proc) != 0) {
goto log_init_failed;
}
#elif CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
if (r_ble_log_init_simple(ble_log_uhci_out_ll_write, ble_log_uhci_out_ll_log_ev_proc) != 0) {
goto log_init_failed;
}
#else
uint8_t buffers = 0;
#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED
@@ -337,8 +323,6 @@ esp_err_t esp_bt_controller_log_init(void)
ctrl_level_init_failed:
#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
r_ble_log_deinit_simple();
#elif CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
r_ble_log_deinit_simple();
#else
r_ble_log_deinit_async();
#endif
@@ -347,10 +331,6 @@ log_init_failed:
ble_log_spi_out_deinit();
spi_out_init_failed:
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
ble_log_uhci_out_deinit();
uhci_out_init_failed:
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
return ESP_FAIL;
}
@@ -360,14 +340,8 @@ void esp_bt_controller_log_deinit(void)
ble_log_spi_out_deinit();
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
ble_log_uhci_out_deinit();
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
r_ble_log_deinit_simple();
#elif CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
r_ble_log_deinit_simple();
#else
r_ble_log_deinit_async();
#endif
@@ -1563,7 +1537,7 @@ void esp_ble_controller_log_dump_all(bool output)
ble_log_dump_to_console();
}
#else /* !CONFIG_BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2 */
#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag)
{
bool end = (flag & BIT(BLE_LOG_INTERFACE_FLAG_END));
@@ -1585,7 +1559,7 @@ static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, u
portEXIT_CRITICAL_SAFE(&spinlock);
#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
}
#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
void esp_ble_controller_log_dump_all(bool output)
{
@@ -1593,13 +1567,9 @@ void esp_ble_controller_log_dump_all(bool output)
ble_log_spi_out_dump_all();
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
ble_log_uhci_out_dump_all();
#endif // CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED
#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
esp_bt_read_ctrl_log_from_flash(output);
#elif !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED && !CONFIG_BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
#elif !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL_SAFE(&spinlock);
esp_panic_handler_feed_wdts();