Logging User Guide#
This section describes the logging framework used to push important information on target logging interface in a compressed format.
The logging framework is designed to provide standard printf()
like experience to the developers without overloading the debug target(UART by default) with redundant information. The framework compresses the amount of log data that is pushed on to the target.
In order to achieve this compression,
SAPI and FW Logs follows strict Syntax rules.
A pre-build analyzer tool converts all static information(read-only component of SAPI and FW logs) in log description file placed in the build system.
A C framework embedded within SAPI and FW emits the dynamic components of logs along with an identifier and compressed timestamp(conditionally).
The compressed logs are processed offline by a decoder to regenerate the human readable log data.
Compression Numbers in different scenarios#
Scenario | Number of bytes emitted |
---|---|
No Debug Arguments, first 32 Debug IDs | 1 Byte |
No Debug Arguments, 32-4096 Debug IDs | 2 bytes |
Cost of Timestamp | 1 byte if temporal spacing between two consecutive logs is more than 1ms. 2 bytes if temporal spacing between two consecutive logs is more than 127ms |
Cost of each fixed length argument | Number of bytes in argument |
Cost of string | Length of string(Null terminated) |
SAPI Logging#
Enable/Disable SAPI Logs#
Compile time switch SAPI_LOGGING_ENABLE
should be enabled for SAPI logs to be active. If the compile switch SAPI_LOGGING_ENABLE
is not present, SAPI log instances are considered as void statements and shall not generate any code.
Syntax for SAPI Logging calls#
The calls to SAPI Logs should strictly follow below syntax.
SL_PRINTF(DEBUG_ELEMENT, COMPONENT, LOG_LEVEL, Format, <Arguments>);
DEBUG_ELEMENT#
The DEBUG_ELEMENT
is the unique identifier for a logging call. In order to add a new logging call, user is just required to mention a new DEBUG_ELEMENT in the fucntion call, user is not required to define this new DEBUG_ELEMENT. A pre-processing tool shall search for all occurences of SL_PRINTF
calls in the source files and prepare an enum with all unique DEBUG_ELEMENTS
.
COMPONENT#
The component the module to which the debug log belongs to. Currently supported list of components is:
BLE
BLUETOOTH
COMMON
CRYPTO
DRIVER
FW_UPDATE
NETWORK
WLAN
Log Levels#
The level of active logs can be controlled through compile switch CONFIG_DEBUG_LEVEL
present in rsi_user.h
. The compile switch define can be initialized with one of four possible enum values:
LOG_OFF
LOG_ERROR
LOG_WARNING
LOG_INFO
As the enums suggest, LOG_OFF
provides minimum logging and LOG_INFO
provides maximum logging.
Format#
Format defines how additional arguments in the logging call should be treated. The format is parsed by the pre-processing tool and information is stored in build system. The format information is latter used to display the decoded logs.
Important rules:
Each argument defination should be separated by ','
Each Argument defination should comprise of a Display Name and properties, separated by ':'
The display name is what will be visible in decoded output log against each argument.
sign should be used only to identify debug argument property. Number of % signs denotes number of arguments that are being pased in the debug log.
b stands for 1 byte argument which should be displayed in decimal format.
w stands for 2 byte argument which should be displayed in decimal format.
d stands for 4 byte argument which should be displayed in decimal format.
s stands for a variable length string which should always be terminated by NULL character.
%1x stands for 1 byte argument which should be displayed in Hexadecimal format.
%2x stands for 2 byte argument which should be displayed in Hexadecimal format.
%4x stands for 4 byte argument which should be displayed in Hexadecimal format.
The format is also used by pre-processing tool to identify number of arguments in given debug call and define SL_PRINTF
call for given DEBUG_ELEMENT
accordingly. There is no limit to number of times logging call is made with same DEBUG_ELEMNT
but the format should remain the same for each of these calls. The pre-processor tool shall throw error if any descripancy is found in format.
Arguments#
For a fixed length argument, parameters shall be passed by value. For strings, parameters shall be passed by reference.
>Note! The format and arguments fields are optional. SL_PRINTF
call shall have only three mandatory arguments(DEBUG_ELEMENT
, COMPONENT
and LOG_LEVEL
) if an argument is not required in the call.
Pre-Processing tool#
The pre-processing advanced_logs_generator.py
tool is a Python script present in utilities\advanced_logging\app_logging
folder. The tool a manifest.json
file present in same folder. The Json file comprises of metadata corresponding to all SAPI logging calls required at the time of decodding the logs. The tool also generates debug_auto_gen.h
file present in sapi\include
. The file comprises of all the enumerations and declarations required by the logging framework.
>Note! The pre-processing tool should be invoked mandatorily if a new(unique) SAPI logging call is introduced. The autogenerated files are already updated as part of release package for all existing SAPI logging calls.
Decoding SAPI Logs#
The decoder tool sapi_log_decoder.py
is a python tool present in the utilities\advanced_logging\app_logging
folder. The decoder tool takes the encoded logs as the input and searches for #@$
in the start of line. The tool expects the rest of the line to have heaxdecimal numbers which are then decoded to generate human readable text file.
Given below is an example of the SAPI logs, before and after decoding.
Firmware Logging#
Enable/Disable Firmware Logs#
Compile time switch FW_LOGGING_ENABLE
should be enabled for firmware logs to be active. If the compile switch FW_LOGGING_ENABLE
is not present, firmware log instances are considered as void statements and shall not generate any code.
Firmware Log Components#
The component to which the debug log belongs to. Current supported list of components is:
COMMON - common section among all protocols
CM_PM - Coex manager and power manager logs are used to debug issues involving multi protocols and power save.
WLAN_LMAC - LMAC logs are used to debug Transmit/Receive related issues
WLAN_UMAC - UMAC logs are used to debug Supplicant, SME, APME layers issues
WLAN_NETSTACK - Network stack logs are used to debug TCP/IP and application layers issues
BT_BLE_CTRL - Bluetooth and Bluetooth Low Power controller logs are used to debug issues in controller
BT_BLE_STACK - Bluetooth and Bluetooth Low Power controller logs are used to debug issues in stack
Firmware Logging Parameters#
Applications for which firmware logging has been enabled, contain parameters that can be configured according to the users requirements and constraints.
Component Log Levels#
The level of active logs of individual firmware components can be controlled through compile switches in application configuration files. The compile switch define can be initialized with one of five possible values:
FW_LOG_OFF
FW_LOG_ERROR
FW_LOG_WARN
FW_LOG_TRACE
FW_LOG_INFO
Log Buffer Size#
Determines the size of log packet recieved from firmware. The log buffer size can vary from a minimum of 2048 bytes to a maximum of 4096 bytes. The size can be varied with increments of 512 bytes. Any size below the minimum size or more than maximum size will be replaced with corresponding limits.
Log Queue Size#
Determines the number of elements in the firmware log queue. The log queue ensures that debug logs arriving from firmware are not lost when previously received logs are being processed. For a larger queue size, more debug logs can be stored in the queue. It has a minimum value of 1.
Increasing the log queue size increases the memory required by the firmware logging framework, during application initialization.
Decoding Firmware Logs#
The decoder tool fw_log_decoder.py
is a python tool present in the utilities\advanced_logging\firmware_logging
folder.
The decoder tool takes the encoded logs as the input and searches for &^$
in the start of line. The tool expects the rest of the line to have heaxdecimal numbers which are then decoded to generate human readable text file. Given below is an example of the firmware logs, before and after decoding.