Debug System
Two debugging methods have been provided to debug applications.
Use log mechanism to trace code procedure and data.
Use ARM Keil MDK and J-Link for running control, add/delete breakpoints, access/trace memory and so on.
Log Mechanism
Debug Analyzer is designed to help trace application via printing messages and capturing BT data which could be analyzed by a 3rd party BT analyzing tool. Refer to Debug Analyzer User Guide for more details.
There is a dedicated log UART pin (P0_3 as default) to print log of application (Log function can be re-configured to another pin in application). It is connected to PC via UART-to-USB adapter, and log data shall be received from PC COM port.
Debug Analyzer
Follow the steps below to use Debug Analyzer.
Run
DebugAnalyzer.exe
, and click .

Main Interface of Debug Analyzer
Select the corresponding COM for Serial Port in the Settings window.
Select the corresponding
App.trace
file for App Trace File so that Debug Analyzer can parse log correctly. Note:App.trace
is created under the same directory ofApp.bin
after the compilation of each project.

Debug Analyzer Setting Page
Debug Analyzer also provides some advanced functions as below.
Save Raw File (it is recommended to check it): Save LOG to
xxx.bin
file, which can be used by Realtek to perform further analysis.Log Filter: Filter Display - a new window pops up to display the filtered logs only.
Keyword Search: Highlight the keyword in the log printing window.
Clear Trace: Clear the log in the display frame.
Note
Debug Analyzer will automatically save the log data as a file, which is named based on port number and creation date and time, such as COM5_2015-06-12_18-05-00.log
. The save location is in the DebugAnalyzer installation path DebugAnalyzer\DataFile
.
Basic Interface for Log Printing
Hardware has implemented a specialized GDMA channel for log printing, and the interface function prototype is.
DBG_BUFFER(T_LOG_TYPE type, T_LOG_SUBTYPE sub_type,..T_MODULE_ID module,uint8_t level, char* fmt, uint8_t param_num,...).
The parameter type is always TYPE_BEE4, and sub_type is always SUBTYPE_FORMAT. You may only pay attention to the parameters module and level.
There are several predefined modules in T_MODULE_ID, and they are used to indicate which module the log belongs to, and Debug Analyzer Tool will recognize and print the module name before log data.
There is also a concept named Debug Level, and this indicates what level the log is displayed in. Four levels are defined.
Debug Level |
Usage Scenario |
---|---|
LEVEL_ERROR |
Fatal, Procedure Cannot Advance (Log Token !!!) |
LEVEL_WARN |
Abnormal Condition Occurred, But Procedure Can Advance (Log Token !!*) |
LEVEL_INFO |
Important Notification (Log Token !**) |
LEVEL_TRACE |
Verbose Debug |
The DBG_BUFFER() API is flexible and powerful, but may be difficult to use. RTL87x2G SDK has wrapped the interface and provided some readable APIs in trace.h.
Wrapped Interfaces for Log Printing
There are several wrapped APIs to print specific logs, and all of them have a common syntax as.
{MODULE}_PRINT_{LEVEL}_{PARAMNUM}(...)
Parameter definition.
MODULE: defined in trace.h, such as APP/GAP/USB/FLASH…
LEVEL: 4 levels, such as ERROR/WARN/INFO/TRACE
PARAMNUM: 0 to 8, which means the number of parameters this log will print out.
For example, print a warning log with 2 parameters in an application.
APP_PRINT_WARN2("Test app: ID = %d, data = 0x%x", id, data);
Debug Analyzer displays the following log as follows:
0049410-13#17:06:45.994 087 02145 [APP] !!*Test app: ID = 3, data = 0xF0
Note
Do not exceed 8 parameters (Maximum 20 parameters if directly using DBG_BUFFER()).
Put all parameters into a single print if possible.
Auxiliary Interfaces
The DBG_BUFFER() API can only print a simple format like Integer (d, i, u, o, x), Character (c), and Pointer (p). Sometimes there is a need to print string, binary array, or BT Address; thus, three auxiliary interfaces are provided to do that.
- TRACE_STRING(char* data)Directly put string into log data, the conversion directive is %s.
- TRACE_BINARY(uint16_t length, uint8_t* data)Output binary stream in Hex format, the conversion directive is %b.
- TRACE_BDADDR(char* bd_addr)Output binary array in BT address format, the conversion directive is %s.For example:
Hex Array: 0xaa 0xbb 0xcc 0xdd 0xee 0xff –> Literal String: FF::EE::DD::CC::BB::AA
Note
TRACE_STRING: The maximum length of the string is 240 bytes.
TRACE_BINARY: The maximum length of the binary stream is 240 bytes.
TRACE_BDADDR: The maximum BT addresses numbers in a single log is 4.
Log Print Example
Below is an example to show the common use of log APIs and the corresponding output in Debug Analyzer Tool.
uint32_t n = 77777;
uint8_t m = 0x5A;
uint8_t bd1[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
uint8_t bd2[6] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
char* c1[10] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
char* c2[8] = {'a', 'b', 'C', 'd', 'E', 'F', 'g', 'H'};
char* s1 = "Hello world!";
char* s2 = "Log Test";
ADC_PRINT_TRACE1("ADC value is %d", n);
UART_PRINT_INFO3("Serial data: 0x%x, c1[%b], s1[%s]",..m, TRACE_BINARY(10, c1), TRACE_STRING(s1));
GAP_PRINT_WARN6("n[%d], m[%c] bd1[%s], bd2[%s], c2[%b], s2[%s]", n, m,..TRACE_BDADDR(bd1), TRACE_BDADDR(bd2),TRACE_BINARY(8, c2), TRACE_STRING(s2));
APP_PRINT_ERROR0("APP ERROR OCCURRED...");
Debug Analyzer displays the following log as follows:
00252 10-25#17:12:02.021 132 10241 [ADC] ADC value is 77777
00253 10-25#17:12:02.021 133 10241 [UART] !**Serial data:..0x5a, c1[31-32-33-34-35-36-37-38-39-30], s1[Hello world!]
00254 10-25#17:12:02.022 134 10241 [GAP] !!*n[77777], m[Z] bd1[55::44::33::22::11::00],bd2[FF::EE::DD::CC::BB::AA],c2[61-62-43-64-45-46-67-48], s2[Log Test]
00255 10-25#17:12:02.022 135 10241 [APP] !!!APP ERROR OCCURRED...
Log Control Interfaces
Sometimes you may decide to turn on some logs and turn off others. One method is to set the trace mask in Config Tool, and then burn the config file to RTL87x2G. However, this is not flexible enough as you may want to frequently change the log level, and it is not convenient to re-burn the config file every time. So, we provide three APIs to control the log of specific level of specific module.
log_module_trace_init()
log_module_trace_set_update ()
log_module_bitmap_trace_set()
Here are some sample scenarios to help understand how to use log control APIs in applications. Assume that log print is already enabled, and all the log trace masks have been set to 1 in Config Tool, which means all types of all levels of logs can be output.
- Scenario 1
Disable all trace level and info level logs of APP module.
int main(void) { log_module_trace_set_update(MODULE_APP, LEVEL_INFO, false); log_module_trace_set_update(MODULE_APP, LEVEL_TRACE, false); ... }
- Scenario 2
Only enable logs of PROFILE module.
int main(void) { uint64_t mask[LEVEL_NUM]; memset(mask, 0, sizeof(mask)); log_module_trace_init(mask); log_module_trace_set_update(MODULE_PROFILE, LEVEL_ERROR, true); log_module_trace_set_update(MODULE_PROFILE, LEVEL_WARN, true); log_module_trace_set_update(MODULE_PROFILE, LEVEL_INFO, true); log_module_trace_set_update(MODULE_PROFILE, LEVEL_TRACE, true); ... }
- Scenario 3
Disable trace level logs of PROFILE/PROTOCOL/GAP/APP modules.
int main(void) { log_module_bitmap_trace_set(MODULE_BIT_PROFILE | MODULE_BIT_PROTOCOL | MODULE_BIT_GAP | MODULE_BIT_APP, LEVEL_TRACE, false); ... }
- Scenario 4
Disable all trace level and info level logs except APP module, and also disable BT Snoop logs.
int main(void) { for (uint8_t i = 0; i < MODULE_NUM; i++) { log_module_trace_set_update((T_MODULE_ID)i, LEVEL_TRACE, false); log_module_trace_set_update((T_MODULE_ID)i, LEVEL_INFO, false); } log_module_trace_set_update(MODULE_APP, LEVEL_INFO, true); log_module_trace_set_update(MODULE_APP, LEVEL_TRACE, true); log_module_trace_set_update(MODULE_SNOOP, LEVEL_ERROR, false); ... }
Note
Debug Analyzer Tool can generate BT Snoop log file (*.cfa
) if the LEVEL_ERROR log of MODULE_SNOOP is enabled, in other words, if you turn off the log of MODULE_SNOOP, BT Snoop log file will not be generated, such as Scenario 2 and Scenario 4.
DBG_DIRECT
Invoking APIs based on DBG_BUFFER has less effect on system performance, but the log will not be printed in real-time, because logs printed by these APIs will be cached in buffer and sent to Log Uart when the system is idle.
DBG_DIRECT can be used to print real-time logs. This API has great influence on system performance as it will directly send Log to Log UART, and suspend execution of any program until log printing is completed, so it is strongly recommended that it is only used under specific situations as follows:
Before reboot
Scenario when real-time log is necessary
Log print code
DBG_DIRECT("ROM version: %s %s", __DATE__, __TIME__);
Corresponding result shown in Debug Analyzer
00002 12-22#19:19:32.573 004 00000 ROM version: Dec 22 2017 14:54:04
Debug with SWD
As shown in Debug and Trace port interface in RTL87x2G, RTL87x2G implements the SWD debug protocol. The SWD debug protocol supports basic debug functions such as run control, setting breakpoints, and accessing memory.

Debug and Trace port interface in RTL87x2G
Note
RTL87X2G supports SWD but does not support JTAG.
ARM Keil MDK SWD Debugging
Before using SWD, properly install and configure ARM Keil MDK and the SWD debugger.
Key debug features supported by RTL87x2G are introduced in the UI.
Running control buttons: Running/Reset/Step.
Breakpoints buttons: Add/Delete/Conditional.
Several functional windows for debugging.
Core registers window to view/modify MCU register values.
Disassembly window shows the program execution in assembly code, or intermixed with the source code.
Source code window to view C code, support breakpoints and variable value real-time display.
Variable watch window to trace interested variables added in.
Memory window to view/modify interested memory, support direct address input and variable address input.
Call stack and local variable window to show current call stack and local variables (variables in the stack).
Note
Sometimes you may encounter the problem that your image can not be successfully burned to flash, or Keil just can not find the SWD even if you have connected IC with J-Link properly. In these cases, checking the following configurations are helpful.
Change debug clock to a smaller value (e.g., from 2 MHz to 1 MHz), or just replace the SWD debug wire with a shorter one.
The IC may have entered DLPS mode. Reset the IC and the system will keep active for the first 5 seconds.
Check if the SWD feature is disabled in the application.
J-Link Commander SWD Debugging
In order to use J-Link Commander for programming, please add device support and configure the Flash algorithm before using it.
Create a folder in the J-Link installation directory (where
JLink.exe
is located):Devices\Realtek\RTL87x2G
.Find the files
RTL87x2G_FLASH.FLM
andRTL876x_LOG_TRACE.FLM
in the SDK (undersdk\tool\flash
directory) and copy them toDevices\Realtek\RTL87x2G
.Open the
JLinkDevices.xml
file in the J-Link installation directory and add the device download algorithm information.
<Device>
<ChipInfo Vendor="Realtek" Name="RTL87x2G" Core="JLINK_CORE_CORTEX_M33" WorkRAMAddr="0x00130000" WorkRAMSize="0x8000"/>
<FlashBankInfo Name="QSPI Flash" BaseAddr="0x04000000" MaxSize="0x01000000" Loader="Devices/Realtek/RTL87X2G/RTL87x2G_FLASH.FLM" LoaderType="FLASH_ALGO_TYPE_CMSIS" AlwaysPresent="1" />
<FlashBankInfo Name="QSPI Flash" BaseAddr="0x08000000" MaxSize="0x10400000" Loader="Devices/Realtek/RTL87X2G/RTL876x_LOG_TRACE.FLM" LoaderType="FLASH_ALGO_TYPE_CMSIS" AlwaysPresent="1" />
</Device>
Open the J-link Commander command window, and input commands connect, RTL87X2G and s as follows in turn. If you see the following command Cortex-M33 identified., it means that the connection is successful.

J-Link Commander SWD debugging 1

J-Link Commander SWD debugging 2
After successfully connecting to SWD, you can debug through the commands supported in J-link Commander, such as commonly used commands:
Command |
Description |
---|---|
h |
Halt cpu |
r |
Reset cpu |
g |
Go |
s |
Single-step operation |
setbp |
Set breakpoint |
mem32 |
Read the data of the specified address |
w4 |
Write data to the specified address |
erase |
Erase Flash |
loadbin |
Load *.bin file into target memory |
savebin |
Saves target memory into binary file |
? |
Directly input “?” to obtain all supported commands |

J-Link Commander SWD debugging 3