Platform Overview
The SDK offers example applications for developers to test on their development kits and verify proper setup. After performing these tests, developers can use the examples as a foundation for developing their own applications.
To begin using the SDK, Quick Start is provided, and developers should first familiarize themselves with this guide.
Hardware Architecture
The CPU of RTL87x2G is Real_M300V, which is equivalent to ARM Cortex-M55. The RTL87x2G Hardware Block consists of the following parts:
Rich peripherals
Power Management Unit
Clock Management Unit
RF module

RTL87x2G Hardware Block
Software Architecture
System Architecture
As shown in RTL87x2G Software Architecture, software architecture consists of several major components:
Platform: Includes OTA, flash, FTL, etc.
IO Drivers: Provide application layer access to the interface of RTL87x2G peripherals.
OSIF: Abstraction layer for real-time operating systems.
GAP: Abstraction layer through which user applications communicate with the BLE stack.

RTL87x2G Software Architecture
Operating System
RTL87x2G supports multiple RTOSs, with FreeRTOS being the default one. The version of FreeRTOS integrated into the RTL87x2G ROM code is FreeRTOS V10.4.4. It consists of the following components:
Task Management
Queue Management
Interrupt Management
Resource Management
Memory Management
Time Management
OS Interfaces
As depicted by OSIF Overview, the OSIF layer aims to provide a consistent and uniform RTOS API set by wrapping the specific RTOS interfaces. Vendors can also provide their own RTOS implementation inside the OSIF layer, but without any modifications from upper layer software components. So, it is strongly recommended to use the OSIF API in software development instead of accessing the specific RTOS interfaces.

OSIF Overview
Task and Priority
The system has created several tasks including timer task, idle task, and flash task. Additionally, the Bluetooth protocol stack will create Bluetooth Controller task and Bluetooth Host task. According to the application requirements, one or more tasks can be created. Setting the priority of the application tasks between 1 to 4 is recommended.
Task |
Description |
Priority |
---|---|---|
Timer |
implement software timer required by FreeRTOS |
6 |
Bluetooth Controller |
implement BT stack protocols below HCI |
6 |
Bluetooth Host |
implement BT stack protocols above HCI |
5 |
App |
handles user application requirements |
1~4 |
Flash |
flash suspend operation and FTL garbage collect |
1 |
Idle |
runs background tasks including DLPS |
0 |
Note
Multiple APP tasks can be created, and memory resources will be then allocated.
Idle task and timer task are provided by FreeRTOS.
Tasks have been configured as preemptive based on their priority.
Additionally, hardware interrupt service routines (ISR) are implemented by the vendor as well.
TrustZone
TrustZone is the cornerstone of the ARMv8-M processor. It provides hardware access control code, memory, and I/O, while retaining the needs of embedded applications: real-time response, minimal switching overhead, constrained on-chip resources, and easy software development.
ARMv8-M adds an additional manipulation of processor states: secure and non-secure execution states. These secure states are orthogonal to existing threading and processing models, allowing operation in both secure and non-secure states.

TrustZone
TrustZone has the following features:
Allows users to divide memory into secure and non-secure areas.
Allows prevention of debugging of secure code/data when not authenticated.
NVIC, MPU, SYSTICK, kernel control registers, etc. are also backed up in two areas, and secure code and non-secure code can independently access their own resources.
There are MSP and PSP stack pointers in both the security area and the non-security area.
Proposed the concept of Secure Gateway. Non-secure codes can access specific secure codes through Secure Gateway, which is the only way for non-secure codes to access secure codes.
Provides a Stack Limit Checking (stack limit check) function, which can be used to detect stack overflow. In the ARMv8.1-M architecture corresponding to Real-M300V, each stack pointer has a corresponding stack limit register.
The function of SAU (Security Attribution Unit) and IDAU (Implementation Defined Attribution Unit) is to divide the memory space into secure and non-secure spaces. The instructions issued by the CPU will be judged whether they comply with the safety rules through the SAU, and the instructions issued by other bus masters such as DMA, GPU, USB, etc. will be judged whether they comply with the safety rules through the IDAU. If the security rules are violated, such as non-secure code accessing the secure region, a secure fault/hard fault will be triggered.
The following is SAU’s default secure and non-secure divisions. Taking Single Bank (one of the OTA upgrade methods) as an example, a total of 7 Non-Secure or Non-Secure Callable areas are set:
Areas |
Description |
---|---|
Region0 |
Non-Secure Callable area in ROM, which stores APIs called by Non-Secure programs |
Region1, 2 |
part of ROM, ITCM1, DTCM0 |
Region3 |
Data SRAM, Buffer SRAM, and SOCV config and OEM config at the beginning of Flash |
Region4, 5 |
Flash area |
Region6 |
PSRAM, Peripheral and other areas |
Note
TrustZone is not enabled by default in the SDK, and all code is executed in the secure area. If needing to maintain an additional secure app to enable TrustZone, refer to trustzone_demo: rtl87x2g_sdk_xxxx\samples\trustzone_demo
in the SDK.
Boot Flow
When the system powers on or resets, the boot flow will be executed. The boot flow includes:
eFuse validation
Security Control according to eFuse value
Flash image Check and Execute
The eFuse verification determines whether to enable secure boot. If secure boot is enabled, image authentication will involve signature, CMAC, and secure version verification.

Boot Flow
In Boot Flow, ‘Flash Image Check and Execute’ means checking all kinds of flash images and executing them. The process includes:
Check OEM Data (Flash layout is included in this file)
Check if a valid upgraded image exists in Flash
Check OTA Bank Header Files
Check every flash image in OTA Bank
Execute Image
Flash Image Check and Execution demonstrates the process above. The image check method is SHA256 integrity check (disable secure boot) or signature verification (enable secure boot). The order of the flash image execution is: Boot Patch, BT Stack Patch, Secure APP, System Patch, BT Host, APP.

Flash Image Check and Execution
The ‘Dual Bank Process’ in Dual Bank Boot Flow is for ‘bank switch’ image updates. If a new version is updated, images exist in both Bank0 and Bank1 (one bank with the old version, the other bank with the new version). The Dual Bank Process will check the OTA bank with the higher version first. If the images in the OTA bank are checked and decrypted successfully, it will continue to be executed. But if any image in the OTA bank is checked or decrypted unsuccessfully, the images in the other OTA bank will be checked.

Dual Bank Boot Flow
Application
SDK Directory
└── SDK
├── bin Binary files for user application to link
├── bsp Board level and hardware related files
├── doc SDK documents
├── include Header files which provide API definitions export from ROM
├── samples Sample projects that can be used directly
├── subsys Upper layer and hardware-independent software protocol
└── tools Toolchain
Sample Projects
To help create a user application, many sample projects in SDK have been created to start with, such as ble_peripheral and some BLE-related demo sample projects. Through studying sample projects, users can easily get familiar with SDK. All sample projects have been configured, and the memory layout in the scatter file is also modified to comply with the RTL87x2G SOC. For specific memory allocation, please refer to Memory.
Taking the ble_peripheral application as an example below, it shows how to start developing the customized user application by the sample project.

ble_peripheral Sample Project
Source files in the BLE Peripheral project are currently categorized into several groups as below:
Device directory: includes startup code
CMSIS directory: includes CMSIS header files
CMSE Library: Non-secure callable library
Lib directory: includes all binary symbol files that the user application is built on
Peripheral directory: includes all peripheral drivers and module code used by the application
Profile directory: includes BLE profiles or services used by the sample application
APP directory: includes the ble_peripheral user application implementation
The RTL87x2G MCU is based on the ARMv8.1 architecture, supports the MVE instruction set, and can efficiently handle single-precision integer and floating-point operations. The lib and sample app projects released in the default SDK all use the following devices.

app project device select

MCU APP supports single-precision integer and floating-point MVE instructions
The common files in sample applications are explained as follows:
File name |
Description |
---|---|
rom_uuid.h |
UUID header files provided by SDK to identify the ROM and no change needed |
ROM_NS.lib |
ROM symbol library file used by user application to link any ROM symbols |
gap_utils.lib |
GAP library file to implement BLE functions |
startup_rtl.c |
C file for RTL87x2G application startup |
system_rtl.c |
C file of RTL87x2G application system |
board.h |
Header file to configure pin and DLPS settings |
flash_map.h |
Flash layout file which is generated by Flashmap Generate Tool |
mem_config.h |
Memory Configuration file |
The sample project may upgrade together with the SDK, and to better utilize the upgraded sample code, newly added user code is suggested to be organized and modularized. More detailed information on each sample project could be found in its user manual.
Application Process Flow

APP Flow
Action |
Description |
---|---|
board init |
contains initialization of pinmux settings and pad settings |
gap init |
contains initialization of GAP related parameters |
profile init |
contains initialization of BLE profiles |
power manager init |
contains initialization of power management related |
SW timer init |
contains initialization of software timers |
app queue init |
contains initialization of app queue |
driver init |
contains initialization of peripherals |
System is initialized in the main() function, including Board, Peripherals, BT Stack, Profile, Power Mechanism, Task, etc. BT Stack, Profiles, and Peripheral drivers are initialized in the application layer task and implement an IO messaging mechanism. All functionalities are encapsulated as IO events, which are processed in the corresponding message handlers.

IO Message Handling Flowchart
MSG and Event Handling Flow
An original MSG is sent from universal Peripherals’ ISR or BT Stack. The processing flow is as follows.
MSG from Peripherals is forwarded by MSG Distributor to IO MSG Handler for handling.
MSG from BT Stack is forwarded by MSG Distributor to BT State Machine. BT State Machine handles MSG and sends a BT IO MSG. MSG Distributor receives the BT IO MSG and then forwards it to IO MSG Handler for handling.
After a message is received, IO MSG Handler shall make a judgment and call the related Event Handler.
Developer programs shall:
Implement Peripheral ISR, complete preliminary processing in ISR, and package MSG to send to APP if further processing is required.
Maintain IO MSG Handler to receive and handle MSGs defined by the developer.
Implement Event Handler for the application.
GAP layer notifies the APP layer with MSG and Event mechanism, while the APP layer calls GAP layer functions by APIs.
IO MSG
Message Format
typedef struct { uint16_t type; uint16_t subtype; union { uint32_t param; void *buf; }u; }T_IO_MSG;
Message Type Definition
typedef enum { IO_MSG_TYPE_BT_STATUS, IO_MSG_TYPE_KEYSCAN, IO_MSG_TYPE_QDECODE, IO_MSG_TYPE_UART, IO_MSG_TYPE_KEYPAD, IO_MSG_TYPE_IR, IO_MSG_TYPE_GDMA, IO_MSG_TYPE_ADC, ... }T_IO_MSG_TYPE;
Message Subtype Definition
Taking T_IO_MSG_UART for example, developers can define subtypes of UART.
typedef enum { IO_MSG_UART_RX = 1, IO_MSG_UART_RX_TIMEOUT = 2, IO_MSG_UART_RX_OVERFLOW = 3, IO_MSG_UART_RX_TIMEOUT_OVERFLOW = 4, IO_MSG_UART_RX_EMPTY = 5, }T_IO_MSG_UART;
User Message Definition
Developers can expand message types and customize message subtypes if needed.
Pin Settings
Pin configuration can be set in board.h.
#define KEY_0 P4_0 #define BEEP P4_1 #define LED_0 P2_1 #define LED_1 P2_4
DLPS Settings
Please refer to Low Power Mode for details.
Memory
Memory Map
RTL87x2G MCU memory includes ROM, RAM, Cache, Flash and eFuse. Refer to Memory for details.
Flash APIs
Flash operation APIs are listed as follows, refer to Flash for more details.
FLASH_NOR_RET_TYPE flash_nor_read_locked( uint32_t addr, uint8_t* data, uint32_t len); FLASH_NOR_RET_TYPE flash_nor_write_locked( uint32_t addr, uint8_t* data, uint32_t len); FLASH_NOR_RET_TYPE flash_nor_erase_locked( uint32_t addr, FLASH_NOR_ERASE_MODE mode); FLASH_NOR_RET_TYPE flash_nor_try_high_speed_mode(FLASH_NOR_IDX_TYPE idx, FLASH_NOR_BIT_MODE bit_mode);
FTL
FTL (Flash Transport Layer) is used as an abstraction layer for BT stack and user application to read/write data in flash. Refer to Flash for details.
eFuse
eFuse is a block of one-time programming memory which is used to store important and fixed information, such as UUID, security key, and other one- time programming configurations. A single bit of eFuse cannot be changed from 0 to 1, and there is no erase operation in eFuse, so be careful when updating eFuse. Realtek offers MPTool to update certain eFuse sections.
Interrupt
Nested Vectored Interrupt Controller (NVIC)
NVIC features
16 Real-M300V exceptions, 96 maskable interrupt channels.
Programmable priority levels.
Support vector table relocation.
Low-latency exception and interrupt handling.
Implementation of System Control Registers.
The interrupt vector table is used to manage and handle different types of interrupts. It is a data structure stored in memory that contains the entry addresses of interrupt handler routines. The interrupt vector table mechanism offers the advantage of flexible handling of different interrupt types. By storing the entry addresses of the interrupt handler routines in the interrupt vector table, the system can quickly locate and call the relevant routine based on the interrupt type, improving system responsiveness and efficiency.
RTL87x2G supports two ways to update the interrupt vector table:
RamVectorTableUpdate_ext()
API allows XIP code to be run in the interrupt service routine, but this will bring additional CPU overhead of 4us entry and 3.6us exit.
RamVectorTableUpdate()
API should ensure that the interrupt service routine runs RAM code without additional CPU overhead.
The RTL87x2G introduces flash suspend and resume mechanisms, which must ensure that Flash is not accessed in interrupt service routines. To achieve this, a wrapper needs to be added in the interrupt. By default, it is recommended to use the RamVectorTableUpdate_ext()
API to ensure system stability and compatibility. For scenarios with strict requirements on interrupt response time, the RamVectorTableUpdate()
API is recommended to achieve faster interrupt response times.
Interrupt Vector Table
Exception Number |
NVIC Number |
Exception Type |
Description |
---|---|---|---|
1 |
Reset |
Reset |
|
2 |
NMI |
Nonmaskable interrupt The WDG is linked to the NMI vector |
|
3 |
Hard Fault |
All fault conditions if the corresponding fault handler is not enabled |
|
4 |
MemManage Fault |
||
5 |
Bus Fault |
||
6 |
Usage Fault |
||
7~10 |
RSVD |
||
11 |
SVC |
Supervisor Call |
|
12 |
Debug Monitor |
Debug monitor (breakpoints, watchpoints, or external debug requests) |
|
13 |
RSVD |
||
14 |
PendSV |
Pendable Service Call |
|
15 |
SYSTICK |
System Tick Timer |
|
16 |
[0] |
System_ISR |
Interrupt CPU when system wakeup by GPIO |
17 |
[1] |
WDT |
Watchdog Timer interrupt |
18 |
[2] |
Internal use |
|
19 |
[3] |
Internal use |
|
20 |
[4] |
Zigbee_ISR |
Zigbee interrupt |
21 |
[5] |
BTMAC_ISR |
BTMAC interrupt |
22* |
[6] |
Peripheral_ISR |
See Below Table: Peripheral ISR (an extension of interrupt) |
23 |
[7] |
RSVD |
|
24 |
[8] |
RTC |
Real-Time Counter interrupt |
25 |
[9] |
GPIO_A0 |
GPIO_A0 interrupt (GPIO_A corresponds to GPIO0 in Address Map sheet) |
26 |
[10] |
GPIO_A1 |
GPIO_A1 interrupt (GPIO_A corresponds to GPIO0 in Address Map sheet) |
27 |
[11] |
GPIO_A[2:7] |
GPIO_A[2:7] interrupt (GPIO_A corresponds to GPIO0 in Address Map sheet) |
28 |
[12] |
GPIO_A[8:15] |
GPIO_A[8:15] interrupt (GPIO_A corresponds to GPIO0 in Address Map sheet) |
29 |
[13] |
GPIO_A[16:23] |
GPIO_A[16:23] interrupt (GPIO_A corresponds to GPIO0 in Address Map sheet) |
30 |
[14] |
GPIO_A[24:31] |
GPIO_A[24:31] interrupt (GPIO_A corresponds to GPIO0 in Address Map sheet) |
31 |
[15] |
GPIO_B[0:7] |
GPIO_B[0:7] interrupt (GPIO_B corresponds to GPIO1 in Address Map sheet) |
32 |
[16] |
GPIO_B[8:15] |
GPIO_B[8:15] interrupt (GPIO_B corresponds to GPIO1 in Address Map sheet) |
33 |
[17] |
GPIO_B[16:23] |
GPIO_B[16:23] interrupt (GPIO_B corresponds to GPIO1 in Address Map sheet) |
34 |
[18] |
GPIO_B[24:31] |
GPIO_B[24:31] interrupt (GPIO_B corresponds to GPIO1 in Address Map sheet) |
35 |
[19] |
DMA_Channel0 |
RTK-DMA channel0 global interrupt |
36 |
[20] |
DMA_Channel1 |
RTK-DMA channel1 global interrupt |
37 |
[21] |
DMA_Channel2 |
RTK-DMA channel2 global interrupt |
38 |
[22] |
DMA_Channel3 |
RTK-DMA channel3 global interrupt |
39 |
[23] |
DMA_Channel4 |
RTK-DMA channel4 global interrupt |
40 |
[24] |
DMA_Channel5 |
RTK-DMA channel5 global interrupt |
41 |
[25] |
DMA_Channel6 |
RTK-DMA channel6 global interrupt |
42 |
[26] |
DMA_Channel7 |
RTK-DMA channel 7 global interrupt |
43 |
[27] |
DMA_Channel8 |
RTK-DMA channel 8 global interrupt |
44 |
[28] |
DMA_Channel9 |
RTK-DMA channel 9 global interrupt |
45 |
[29] |
PPE |
pixel process engine interrupt |
46 |
[30] |
I2C0 |
I2C0 interrupt |
47 |
[31] |
I2C1 |
I2C1 interrupt |
48 |
[32] |
I2C2 |
I2C2 interrupt |
49 |
[33] |
I2C3 |
I2C3 interrupt |
50 |
[34] |
RTK UART0 |
normal interrupt |
51 |
[35] |
RTK UART1 |
normal UART interrupt |
52 |
[36] |
RTK UART2 |
normal UART interrupt |
53 |
[37] |
RTK UART3 |
normal UART interrupt |
54 |
[38] |
RTK UART4 |
normal UART interrupt |
55 |
[39] |
RTK UART5 |
normal UART interrupt |
56 |
[40] |
SPI 3Wire |
SPI 3Wire interrupt |
57 |
[41] |
SPI0 |
SPI0 interrupt |
58 |
[42] |
SPI1 |
SPI1 interrupt |
59 |
[43] |
SPI Slave |
SPI Slave interrupt |
60 |
[44] |
Timer_0 |
Timer interrupt |
61 |
[45] |
Timer_1 |
Timer interrupt |
62 |
[46] |
Timer_2 |
Timer interrupt |
63 |
[47] |
Timer_3 |
Timer interrupt |
64 |
[48] |
Timer_4 |
Timer interrupt |
65 |
[49] |
Timer_5 |
Timer interrupt |
66 |
[50] |
Timer_6 |
Timer interrupt |
67 |
[51] |
Timer_7 |
Timer interrupt |
68 |
[52] |
Enhanced_Timer_0 |
Enhanced timer interrupt |
69 |
[53] |
Enhanced_Timer_1 |
Enhanced timer interrupt |
70 |
[54] |
Enhanced_Timer_2 |
Enhanced timer interrupt |
71 |
[55] |
Enhanced_Timer_3 |
Enhanced timer interrupt |
72 |
[56] |
HR-ADC |
HR-ADC interrupt |
73 |
[57] |
ADC |
ADC interrupt |
74 |
[58] |
KEYSCAN |
keyscan interrupt |
75 |
[59] |
AON Q-decode |
Qdec in AON domain interrupt |
76 |
[60] |
IR |
IR module global interrupt |
77 |
[61] |
SDHC |
Secure Digital IO interrupt |
78 |
[62] |
ISO7816 |
ISO7816 (Smart Card Standards) interrupt |
79 |
[63] |
Display |
Display interrupt |
80 |
[64] |
I2S0 RX |
I2S0 RX interrupt |
81 |
[65] |
I2S0 TX |
I2S0 TX interrupt |
82 |
[66] |
I2S1 RX |
I2S1 RX interrupt |
83 |
[67] |
I2S1 TX |
I2S1 TX interrupt |
84 |
[68] |
SHA256 |
SHA256 family interrupt |
85 |
[69] |
Public key engine |
Public key engine interrupt |
86 |
[70] |
Internal use |
|
87 |
[71] |
SegCom_CTL |
SegCom_CTL interrupt |
88 |
[72] |
CAN |
CAN interrupt |
89 |
[73] |
ETHERNET |
Ethernet interrupt |
90 |
[74] |
IMDC |
IMDC interrupt |
91 |
[75] |
Internal use |
|
92 |
[76] |
Internal use |
|
93 |
[77] |
USB |
USB IP interrupt |
94 |
[78] |
USB_SUSPEND_N |
USB Suspend/Resume interrupt |
95 |
[79] |
USB_Endp_Muti_Proc |
USB_Endp_Muti_Proc interrupt |
96 |
[80] |
USB_IN_EP_0 |
USB IN End Point 0 interrupt |
97 |
[81] |
USB_IN_EP_1 |
USB IN End Point 1 interrupt |
98 |
[82] |
USB_IN_EP_2 |
USB IN End Point 2 interrupt |
99 |
[83] |
USB_IN_EP_3 |
USB IN End Point 3 interrupt |
100 |
[84] |
USB_IN_EP_4 |
USB IN End Point 4 interrupt |
101 |
[85] |
USB_IN_EP_5 |
USB IN End Point 5 interrupt |
102 |
[86] |
USB_OUT_EP_0 |
USB OUT End Point 0 interrupt |
103 |
[87] |
USB_OUT_EP_1 |
USB OUT End Point 1 interrupt |
104 |
[88] |
USB_OUT_EP_2 |
USB OUT End Point 2 interrupt |
105 |
[89] |
USB_OUT_EP_3 |
USB OUT End Point 3 interrupt |
106 |
[90] |
USB_OUT_EP_4 |
USB OUT End Point 4 interrupt |
107 |
[91] |
USB_OUT_EP_5 |
USB OUT End Point 5 interrupt |
108 |
[92] |
USB_Sof |
USB Start Of Frame interrupt |
109 |
[93] |
Internal use |
|
110 |
[94] |
Internal use |
|
111 |
[95] |
Internal use |
Exception Number |
NVIC Number |
Exception Type |
Description |
---|---|---|---|
0 |
[6] |
SPIC0 |
SPI Device (Flash) Controller 0 Interrupt |
1 |
[6] |
SPIC1 |
SPI Device (Flash) Controller 1 Interrupt |
2 |
[6] |
SPIC2 |
SPI Device (Flash) Controller 2 Interrupt |
3 |
[6] |
TRNG |
True Random Number Generator Interrupt |
4 |
[6] |
LPC |
Low Power Comparator Interrupt |
5 |
[6] |
SPI_PHY1 |
SPI_PHY1 Interrupt |
6 |
[6] |
RSVD |
Interrupt Priority
RTL87x2G supports three fixed highest-priority levels and 4 levels of programmable priority. The priority with numbers is below.
0 > 1 > 2 > 3 > 4 > 5 > 6 > 7
Priority |
Usage |
---|---|
-3 |
Reset Handler |
-2 |
NMI |
-1 |
Hard Fault |
0~1 |
It is used for interrupts with very high real-time requirements. (Note: Interrupts of this priority will not be masked by the critical section of FreeRTOS but the interrupt handler cannot call any FreeRTOS API) |
2~6 |
Normal ISR |
7 |
SysTick and PendSV |
Power Management
RTL87x2G supports four power modes.
CPU Active
This mode enables all features for ultimate performance. In Power active mode, if the program does not enter the idle task, the CPU remains in an Active state, and the CPU clock will be in high-speed mode, with a default clock speed of 40MHz.
CPU Sleep
In Power active mode, when the system enters into the idle task, the CPU goes into sleep mode, and the CPU clock will automatically slow down. If the CPU is operating at a 40MHz clock, the clock speed will reduce to 625KHz when the CPU is in sleep mode. If a PLL clock is being used, the selection of slow clock depends on the configuration of the PLL clock source.
DLPS (Deep Low Power State)
This mode offers proper low power consumption and quick exit and restore time. In DLPS mode, the content of RAM is retained.
Power Down
This mode has extremely low power consumption. However, in power down mode, the content of RAM is not retained. Exiting from Power Down mode requires a reboot process, which takes more time. Only LPC and PAD (without debounce) can wake up the Power Down mode.
RTL87x2G will enter DLPS mode when certain conditions are met and be woken up when it needs to work normally. Refer to Low Power Mode for more details.
Debug System
Two debugging methods have been provided to debug applications. Please refer to Debug System for more details.
Use log mechanism to trace your code procedure and data.
Use Keil MDK and J-Link to do the running control, add/delete breakpoints, access/trace memory and so on.