feat(ble_log): report build, lib and chip versions in a version info frame

Replace the 2-byte BLE Log info record with a 58-byte version info
frame (BLE_LOG_VERSION 5 -> 6; the abandoned branch that claimed the
version-6 slot frees it, so the overall bump stays 5 -> 6):

- idf build commit (12 bytes), injected at build time by
  register_ble_log_idf_commit() next to the other register_* helpers;
  the git probe is only trusted when the IDF tree itself is a
  repo/worktree, since rev-parse walks up parent directories
- controller, btdm_common, BLE Mesh and BLE Audio lib commits (10
  bytes each, zero-padded), every getter guarded by the exact
  condition that links its lib, so configs without the lib leave the
  field zero (no link errors)
- chip model and revision from esp_chip_info() at runtime

Lib strings are copied NUL-safely instead of assuming a fixed hash
length; the mesh commit is the substring after the last space of
bt_mesh_v11_commit_str. Frame layout is pinned by a static assert.

Verified on target: esp32, esp32c3, esp32c5 and esp32h4 boards (the
h4 run covers controller + btdm_common + mesh in one build); the
audio-enabled build is blocked by pre-existing esp_ble_audio compile
errors on this base (audio symbol verified with nm instead).
This commit is contained in:
Zhou Xiao
2026-08-21 22:35:46 +08:00
parent a9de6a4f30
commit 4dfb8568e7
4 changed files with 116 additions and 5 deletions

View File

@@ -119,6 +119,7 @@ if(CONFIG_BT_ENABLED)
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
register_ble_log_idf_commit()
register_bt_ctrl_libs()
set_bluedroid_host_compile_flags()
set_nimble_host_compile_flags()

View File

@@ -66,6 +66,35 @@ function(wrap_uart_log_tx_interface)
endif()
endfunction()
# Inject the ESP-IDF build commit into the bt component as a private compile
# definition (BLE_LOG_IDF_COMMIT), reported later in the BLE Log version info
# frame. Does nothing when the commit cannot be determined.
function(register_ble_log_idf_commit)
idf_build_get_property(idf_path IDF_PATH)
# "git rev-parse" walks up parent dirs; only trust it when the IDF tree
# itself is a repo/worktree. Release trees have no .git and must leave
# BLE_LOG_IDF_COMMIT undefined instead of picking up an enclosing repo.
if(NOT EXISTS "${idf_path}/.git")
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" rev-parse HEAD
WORKING_DIRECTORY "${idf_path}"
RESULT_VARIABLE ble_log_git_result
OUTPUT_VARIABLE ble_log_idf_commit
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
string(LENGTH "${ble_log_idf_commit}" ble_log_idf_commit_len)
# Take the first 12 chars of the full hash; --short=N may return a longer
# ambiguous abbreviation, so never rely on abbreviated output
if(ble_log_git_result EQUAL 0 AND ble_log_idf_commit_len EQUAL 40)
string(SUBSTRING "${ble_log_idf_commit}" 0 12 ble_log_idf_commit)
target_compile_definitions(${COMPONENT_LIB} PRIVATE
"BLE_LOG_IDF_COMMIT=\"${ble_log_idf_commit}\"")
endif()
endfunction()
set(bt_common_srcs "" PARENT_SCOPE)
set(bt_common_include_dirs "" PARENT_SCOPE)
set(bt_common_priv_include_dirs "" PARENT_SCOPE)

View File

@@ -14,10 +14,39 @@
#include "ble_log_lbm.h"
#include "esp_log.h"
#include "esp_chip_info.h"
/* MACRO */
#define TAG "ble_log_rt"
#if CONFIG_BT_CONTROLLER_ENABLED
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
extern const char *btdm_controller_get_compile_version(void);
#define BLE_LOG_CONTROLLER_GET_COMMIT() btdm_controller_get_compile_version()
#elif !CONFIG_BT_DUAL_MODE_ARCH || CONFIG_BT_CTRL_BLE_ENABLE
/* BR/EDR-only dual-mode builds do not link the BLE controller lib */
extern char *ble_controller_get_compile_version(void);
#define BLE_LOG_CONTROLLER_GET_COMMIT() ble_controller_get_compile_version()
#endif
#if CONFIG_BT_DUAL_MODE_ARCH
/* BTDM common lib (dual-mode arch only) */
extern const char *r_btdm_get_compile_version(void);
#define BLE_LOG_BTDM_COMMON_GET_COMMIT() r_btdm_get_compile_version()
#endif
#endif
#if CONFIG_BLE_MESH && CONFIG_BLE_MESH_V11_SUPPORT
/* "Bluetooth Mesh v1.1 commit: <hash>" */
extern const char bt_mesh_v11_commit_str[];
#endif
#if CONFIG_BT_AUDIO && CONFIG_SOC_BLE_AUDIO_SUPPORTED
extern const char *lib_audio_commit_get(void);
#endif
_Static_assert(sizeof(ble_log_version_info_t) == 58,
"Unexpected BLE Log version info frame size");
/* VARIABLE */
BLE_LOG_STATIC BLE_LOG_DRAM_ATTR uint32_t rt_inited = 0;
BLE_LOG_STATIC BLE_LOG_DRAM_ATTR volatile uint32_t rt_ref_count = 0;
@@ -35,6 +64,12 @@ BLE_LOG_STATIC void ble_log_rt_ts_trigger(void *arg);
#endif /* CONFIG_BLE_LOG_TS_ENABLED */
/* PRIVATE FUNCTION */
/* Copies a NUL-terminated commit string into a fixed-width zero-padded field */
BLE_LOG_STATIC void ble_log_commit_copy(uint8_t *dst, const char *src, size_t len)
{
BLE_LOG_MEMCPY(dst, src, strnlen(src, len));
}
BLE_LOG_STATIC void ble_log_rt_task(void *pvParameters)
{
(void)pvParameters;
@@ -56,12 +91,42 @@ BLE_LOG_STATIC void ble_log_rt_task(void *pvParameters)
}
last_hook_os_ts = curr_os_ts;
/* Write BLE Log info log */
ble_log_info_t ble_log_info = {
.int_src_code = BLE_LOG_INT_SRC_INFO,
/* Write version info: BLE Log version, idf commit (build-time),
* linked-in BLE lib commits, chip model/revision (efuse, runtime-only).
* Libs absent from the build leave their fields zero. */
ble_log_version_info_t version_info = {
.int_src_code = BLE_LOG_INT_SRC_VERSION_INFO,
.version = BLE_LOG_VERSION,
};
ble_log_write_hex(BLE_LOG_SRC_INTERNAL, (const uint8_t *)&ble_log_info, sizeof(ble_log_info_t));
#ifdef BLE_LOG_IDF_COMMIT
BLE_LOG_MEMCPY(version_info.idf_commit, BLE_LOG_IDF_COMMIT, BLE_LOG_IDF_COMMIT_LEN);
#endif
#if CONFIG_BT_CONTROLLER_ENABLED && defined(BLE_LOG_CONTROLLER_GET_COMMIT)
ble_log_commit_copy(version_info.controller_commit, BLE_LOG_CONTROLLER_GET_COMMIT(),
BLE_LOG_LIB_COMMIT_LEN);
#endif
#if CONFIG_BT_CONTROLLER_ENABLED && defined(BLE_LOG_BTDM_COMMON_GET_COMMIT)
ble_log_commit_copy(version_info.btdm_common_commit, BLE_LOG_BTDM_COMMON_GET_COMMIT(),
BLE_LOG_LIB_COMMIT_LEN);
#endif
#if CONFIG_BLE_MESH && CONFIG_BLE_MESH_V11_SUPPORT
/* The hash is the substring after the last space of the lib string */
const char *mesh_commit = strrchr(bt_mesh_v11_commit_str, ' ');
if (mesh_commit) {
ble_log_commit_copy(version_info.mesh_commit, mesh_commit + 1,
BLE_LOG_LIB_COMMIT_LEN);
}
#endif
#if CONFIG_BT_AUDIO && CONFIG_SOC_BLE_AUDIO_SUPPORTED
ble_log_commit_copy(version_info.audio_commit, lib_audio_commit_get(),
BLE_LOG_LIB_COMMIT_LEN);
#endif
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
version_info.chip_model = (uint16_t)chip_info.model;
version_info.chip_revision = chip_info.revision;
ble_log_write_hex(BLE_LOG_SRC_INTERNAL, (const uint8_t *)&version_info,
sizeof(version_info));
ble_log_write_enh_stat();
ble_log_write_buf_util();

View File

@@ -91,7 +91,10 @@ void ble_log_cas_release(volatile bool *cas_lock)
__atomic_store_n(cas_lock, false, __ATOMIC_RELEASE);
}
#define BLE_LOG_VERSION (5)
#define BLE_LOG_VERSION (6)
#define BLE_LOG_IDF_COMMIT_LEN (12)
/* Lib commit hashes are at most 10 hex chars; zero-padded when shorter */
#define BLE_LOG_LIB_COMMIT_LEN (10)
/* TYPEDEF */
typedef enum {
@@ -102,6 +105,7 @@ typedef enum {
BLE_LOG_INT_SRC_FLUSH,
BLE_LOG_INT_SRC_BUF_UTIL,
BLE_LOG_INT_SRC_FINAL_STAT,
BLE_LOG_INT_SRC_VERSION_INFO,
BLE_LOG_INT_SRC_MAX,
} ble_log_int_src_t;
@@ -110,6 +114,18 @@ typedef struct {
uint8_t version;
} __attribute__((packed)) ble_log_info_t;
typedef struct {
uint8_t int_src_code;
uint8_t version;
uint8_t idf_commit[BLE_LOG_IDF_COMMIT_LEN];
uint8_t controller_commit[BLE_LOG_LIB_COMMIT_LEN];
uint8_t btdm_common_commit[BLE_LOG_LIB_COMMIT_LEN];
uint8_t mesh_commit[BLE_LOG_LIB_COMMIT_LEN];
uint8_t audio_commit[BLE_LOG_LIB_COMMIT_LEN];
uint16_t chip_model;
uint16_t chip_revision;
} __attribute__((packed)) ble_log_version_info_t;
/* INTERFACE */
uint32_t ble_log_fast_checksum(const uint8_t *data, size_t len);