mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(ble): update log compression for bluedroid
(cherry picked from commit 05783fafd7)
Co-authored-by: luoxu <luoxu@espressif.com>
This commit is contained in:
@@ -997,6 +997,17 @@ if(CONFIG_BLE_COMPRESSED_LOG_ENABLE)
|
|||||||
if(LOG_COMPRESSION_TARGET)
|
if(LOG_COMPRESSION_TARGET)
|
||||||
set(srcs ${LOG_COMPRESS_SRCS})
|
set(srcs ${LOG_COMPRESS_SRCS})
|
||||||
set(include_dirs ${LOG_COMPRESS_INCLUDE_DIRS})
|
set(include_dirs ${LOG_COMPRESS_INCLUDE_DIRS})
|
||||||
|
# LOG_COMPRESS_FILES_WITH_FLAGS format: "file_path|compile_flags"
|
||||||
|
if(LOG_COMPRESS_FILES_WITH_FLAGS)
|
||||||
|
foreach(file_entry ${LOG_COMPRESS_FILES_WITH_FLAGS})
|
||||||
|
# Split by '|' to get file path and flags
|
||||||
|
string(REPLACE "|" ";" file_parts "${file_entry}")
|
||||||
|
list(GET file_parts 0 file_path)
|
||||||
|
list(GET file_parts 1 compile_flags)
|
||||||
|
set_source_files_properties(${file_path}
|
||||||
|
PROPERTIES COMPILE_FLAGS "${compile_flags}")
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
list(APPEND include_dirs ${LOG_COMPRESS_INCLUDE_DIRS})
|
list(APPEND include_dirs ${LOG_COMPRESS_INCLUDE_DIRS})
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -175,16 +175,18 @@ if(LOG_COMPRESSED_MODULE)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# List of files with their compile flags: format "file_path|flag1;flag2;..."
|
||||||
|
set(FILES_WITH_COMPILE_FLAGS "")
|
||||||
|
|
||||||
function(add_flags_if_in_list file file_list compile_flags)
|
function(add_flags_if_in_list file file_list compile_flags)
|
||||||
set(PROCESSED OFF PARENT_SCOPE)
|
set(PROCESSED OFF PARENT_SCOPE)
|
||||||
foreach(item IN LISTS file_list)
|
foreach(item IN LISTS file_list)
|
||||||
if(item STREQUAL file)
|
if(item STREQUAL file)
|
||||||
set_source_files_properties("${LOG_COMPRESSED_SRCS_DIR}/${file}"
|
set(abs_file_path "${LOG_COMPRESSED_SRCS_DIR}/${file}")
|
||||||
PROPERTIES
|
# Append to global list with format: "file_path|compile_flags"
|
||||||
GENERATED TRUE
|
list(APPEND FILES_WITH_COMPILE_FLAGS "${abs_file_path}|${compile_flags}")
|
||||||
COMPILE_FLAGS "${compile_flags}"
|
set(FILES_WITH_COMPILE_FLAGS "${FILES_WITH_COMPILE_FLAGS}" PARENT_SCOPE)
|
||||||
OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/ble_log_compression"
|
message("set pro ${LOG_COMPRESSED_SRCS_DIR}/${file} ${compile_flags}")
|
||||||
)
|
|
||||||
set(PROCESSED ON PARENT_SCOPE)
|
set(PROCESSED ON PARENT_SCOPE)
|
||||||
break()
|
break()
|
||||||
endif()
|
endif()
|
||||||
@@ -240,6 +242,7 @@ if(LOG_COMPRESSED_MODULE)
|
|||||||
set(LOG_COMPRESSION_TARGET ble_log_compression PARENT_SCOPE)
|
set(LOG_COMPRESSION_TARGET ble_log_compression PARENT_SCOPE)
|
||||||
# set(LOG_COMPRESSION_TARGET "" PARENT_SCOPE)
|
# set(LOG_COMPRESSION_TARGET "" PARENT_SCOPE)
|
||||||
set(LOG_COMPRESS_SRCS "${compressed_srcs_with_abs_path};${uncompressed_srcs}" PARENT_SCOPE)
|
set(LOG_COMPRESS_SRCS "${compressed_srcs_with_abs_path};${uncompressed_srcs}" PARENT_SCOPE)
|
||||||
|
set(LOG_COMPRESS_FILES_WITH_FLAGS "${FILES_WITH_COMPILE_FLAGS}" PARENT_SCOPE)
|
||||||
if(NOT BLE_COMPRESSED_LIB_LOG_BUILD)
|
if(NOT BLE_COMPRESSED_LIB_LOG_BUILD)
|
||||||
list(APPEND include_dirs "common/ble_log/extension/log_compression/include")
|
list(APPEND include_dirs "common/ble_log/extension/log_compression/include")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
# SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
# The current project needs to support environments before Python 3.9,
|
# The current project needs to support environments before Python 3.9,
|
||||||
@@ -283,7 +283,7 @@ class LogCompressor:
|
|||||||
for node in log_nodes:
|
for node in log_nodes:
|
||||||
try:
|
try:
|
||||||
log_info = self._process_log_node(node, function_boundaries)
|
log_info = self._process_log_node(node, function_boundaries)
|
||||||
if log_info:
|
if log_info and log_info['hexify']:
|
||||||
logs.append(log_info)
|
logs.append(log_info)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOGGER.error(f'Error processing log node: {e}\n{traceback.format_exc()}')
|
LOGGER.error(f'Error processing log node: {e}\n{traceback.format_exc()}')
|
||||||
@@ -339,13 +339,23 @@ class LogCompressor:
|
|||||||
# Parse format tokens
|
# Parse format tokens
|
||||||
tokens = parse_format_string(f'"{log_fmt}"')
|
tokens = parse_format_string(f'"{log_fmt}"')
|
||||||
tokens_tuple_map: list[int] = []
|
tokens_tuple_map: list[int] = []
|
||||||
|
need_args = 0
|
||||||
for idx, tk in enumerate(tokens):
|
for idx, tk in enumerate(tokens):
|
||||||
if isinstance(tk, tuple):
|
if isinstance(tk, tuple):
|
||||||
tokens_tuple_map.append(idx)
|
tokens_tuple_map.append(idx)
|
||||||
|
need_args = need_args + 1
|
||||||
|
if tk[4] == '*': # dynamic width
|
||||||
|
need_args = need_args + 1
|
||||||
|
log_info['hexify'] = False
|
||||||
|
return log_info
|
||||||
|
if tk[5] == '*': # dynamic precision
|
||||||
|
need_args = need_args + 1
|
||||||
|
log_info['hexify'] = False
|
||||||
|
return log_info
|
||||||
|
|
||||||
arguments: list[Node] = valid_arg_childrn[1:]
|
arguments: list[Node] = valid_arg_childrn[1:]
|
||||||
|
|
||||||
if len(arguments) != len(tokens_tuple_map):
|
if len(arguments) != need_args:
|
||||||
raise SyntaxError(f'LogSyntaxError:{node.text.decode("utf-8")}')
|
raise SyntaxError(f'LogSyntaxError:{node.text.decode("utf-8")}')
|
||||||
|
|
||||||
# Process each argument
|
# Process each argument
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
# SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
# ruff: noqa: UP007
|
# ruff: noqa: UP007
|
||||||
"""
|
"""
|
||||||
@@ -11,7 +11,7 @@ import struct
|
|||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
|
|
||||||
def parse_format_string(format_str: str) -> list[Union[str, tuple[int, int, str, str, str, str, str]]]:
|
def parse_format_string(format_str: str) -> list[Union[str, tuple[int, int, str, str, str, str, str, str]]]:
|
||||||
"""
|
"""
|
||||||
Parse a format string into tokens.
|
Parse a format string into tokens.
|
||||||
|
|
||||||
@@ -20,8 +20,9 @@ def parse_format_string(format_str: str) -> list[Union[str, tuple[int, int, str,
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List of tokens (strings or format spec tuples)
|
List of tokens (strings or format spec tuples)
|
||||||
|
Tuple format: (start, end, full_spec, flags, width, precision, length, conv_char)
|
||||||
"""
|
"""
|
||||||
tokens: list[Union[str, tuple[int, int, str, str, str, str, str]]] = []
|
tokens: list[Union[str, tuple[int, int, str, str, str, str, str, str]]] = []
|
||||||
i = 0
|
i = 0
|
||||||
n = len(format_str)
|
n = len(format_str)
|
||||||
|
|
||||||
@@ -42,36 +43,51 @@ def parse_format_string(format_str: str) -> list[Union[str, tuple[int, int, str,
|
|||||||
flags += format_str[i]
|
flags += format_str[i]
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
# Parse width
|
# Parse width (including dynamic width '*')
|
||||||
width = ''
|
width = ''
|
||||||
while i < n and format_str[i].isdigit():
|
if i < n and format_str[i] == '*':
|
||||||
width += format_str[i]
|
width = '*'
|
||||||
i += 1
|
i += 1
|
||||||
|
else:
|
||||||
|
while i < n and format_str[i].isdigit():
|
||||||
|
width += format_str[i]
|
||||||
|
i += 1
|
||||||
|
|
||||||
# Parse precision
|
# Parse precision (including dynamic precision '*')
|
||||||
precision = ''
|
precision = ''
|
||||||
if i < n and format_str[i] == '.':
|
if i < n and format_str[i] == '.':
|
||||||
i += 1
|
i += 1
|
||||||
while i < n and format_str[i].isdigit():
|
if i < n and format_str[i] == '*':
|
||||||
precision += format_str[i]
|
precision = '*'
|
||||||
i += 1
|
i += 1
|
||||||
|
else:
|
||||||
|
while i < n and format_str[i].isdigit():
|
||||||
|
precision += format_str[i]
|
||||||
|
i += 1
|
||||||
|
|
||||||
# Parse length modifier
|
# Parse length modifier (supports h, hh, l, ll, j, z, t)
|
||||||
length = ''
|
length = ''
|
||||||
if i < n and format_str[i] in 'zhl':
|
if i < n and format_str[i] in 'jzt':
|
||||||
|
# j, z, t are single-character length modifiers
|
||||||
length += format_str[i]
|
length += format_str[i]
|
||||||
i += 1
|
i += 1
|
||||||
# Handle double length (e.g., ll)
|
elif i < n and format_str[i] in 'hl':
|
||||||
if i < n and format_str[i] == 'l' and length == 'l':
|
length += format_str[i]
|
||||||
length += 'l'
|
i += 1
|
||||||
|
# Handle double length (e.g., hh, ll)
|
||||||
|
if i < n and format_str[i] == length[0]:
|
||||||
|
length += format_str[i]
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
if i < n and format_str[i] in 'diuoxXfcsplL':
|
# Parse conversion character
|
||||||
|
# Supports: d, i, u, o, x, X, f, F, e, E, g, G, a, A, c, s, p, n, L
|
||||||
|
if i < n and format_str[i] in 'diuoxXfFeEgGaAcspnL':
|
||||||
conv_char = format_str[i]
|
conv_char = format_str[i]
|
||||||
i += 1
|
i += 1
|
||||||
full_spec = format_str[start:i]
|
full_spec = format_str[start:i]
|
||||||
tokens.append((start, i, full_spec, flags, width, length, conv_char))
|
tokens.append((start, i, full_spec, flags, width, precision, length, conv_char))
|
||||||
else:
|
else:
|
||||||
|
# Invalid format spec, treat as literal text
|
||||||
tokens.append(format_str[start:i])
|
tokens.append(format_str[start:i])
|
||||||
else:
|
else:
|
||||||
# Regular text
|
# Regular text
|
||||||
@@ -201,7 +217,7 @@ def parse_compressed_arguments(byte_sequence: bytes, format_str: str) -> str:
|
|||||||
|
|
||||||
for token in tokens:
|
for token in tokens:
|
||||||
if isinstance(token, tuple):
|
if isinstance(token, tuple):
|
||||||
start, end, flags, width, precision, length_mod, conv_char = token
|
start, end, full_spec, flags, width, precision, length_mod, conv_char = token
|
||||||
|
|
||||||
if conv_char == '%':
|
if conv_char == '%':
|
||||||
output.append('%')
|
output.append('%')
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ def gen_compressed_stmt(
|
|||||||
stmt += '\\\n'
|
stmt += '\\\n'
|
||||||
return ' ' + generate_bluedroid_log_prefix(func_name, stmt)
|
return ' ' + generate_bluedroid_log_prefix(func_name, stmt)
|
||||||
size_str = ', '.join([arg['size_type'] for arg in args])
|
size_str = ', '.join([arg['size_type'] for arg in args])
|
||||||
args_str = ', '.join([arg['name'] for arg in args]).replace('\n', '')
|
args_str = ', '.join([arg['name'] for arg in args]).replace('\\\n', '').replace('\n', '')
|
||||||
stmt = f' ble_log_compressed_hex_print({module_id},{log_index}, {len(args)}, {size_str}, {args_str});'
|
stmt = f' ble_log_compressed_hex_print({module_id},{log_index}, {len(args)}, {size_str}, {args_str});'
|
||||||
for idx, buffer_arg in enumerate(buffer_args):
|
for idx, buffer_arg in enumerate(buffer_args):
|
||||||
stmt += '\\\n'
|
stmt += '\\\n'
|
||||||
|
|||||||
Reference in New Issue
Block a user