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.

Before_Decoding

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

  • CM_PM

  • WLAN_LMAC

  • WLAN_UMAC

  • WLAN_NETSTACK

  • BT_BLE_CTRL

  • BT_BLE_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. Before_Decoding

After_Decoding