平台概述

SDK提供了示例应用程序,供开发人员在其开发套件上进行测试并验证设置是否正确。在完成这些测试后,开发人员可以使用这些示例作为开发自己的应用程序的基础。

为了开始使用SDK,提供快速入门,开发人员应首先熟悉该指南。

硬件架构

RTL87x2G的CPU为Real_M300V,可相当于ARM Cortex-M55,RTL87x2G硬件架构由以下部分组成:

  • 丰富的外设

  • 电源管理单元

  • 时钟管理单元

  • RF模块

../../../../_images/RTL87x2G_Hardware_Block.png

RTL87x2G硬件架构

软件架构

系统架构

RTL87x2G软件架构包括几个主要的部分:

  • Platform:包括OTA,flash,FTL等

  • IO Drivers:提供应用层访问RTL87x2G外设的接口

  • OSIF:实时操作系统的抽象层

  • GAP:应用程序和BLE协议栈交互的抽象层

../../../../_images/RTL87x2G_Software_Architecture.png

RTL87x2G软件架构

操作系统

RTL87x2G支持多种RTOS,默认使用FreeRTOS,版本为FreeRTOS V10.4.4,该系统运行在ROM上,包括以下几个模块:

  1. 任务管理

  2. 队列管理

  3. 中断管理

  4. 资源管理

  5. 内存管理

  6. 时间管理

OS接口

OSIF架构 如下图所示,OSIF层通过封装特定的RTOS接口来提供一层统一的接口。开发者可以基于OSIF层提供自定义的RTOS实现,而不需要在上层的软件做任何修改。所以,如果想要让APP可以跑在不同的RTOS,建议使用OSIF接口,而不是直接访问特定RTOS的接口。

../../../../_images/OSIF_Overview.png

OSIF架构

任务和优先级

系统创建了Timer Task,Idle Task,Flash Task,蓝牙协议栈会创建多个Task。应用程序可以根据实际的需求创建Task,其中APP Task优先级建议设定在1~4。

RTL87x2G任务描述

Task

Description

Priority

Timer

FreeRTOS实现的软件定时器

6

Lower stack

蓝牙HCI层以下的协议栈实现

6

Upper stack

蓝牙HCI层以上的协议栈实现

5

App

应用层功能的实现

1~4

Idle

后台空闲任务,包括低功耗的处理

0

备注

  1. 可以创建多个APP任务,同时内存资源也会被相应地分配。

  2. Idle任务和Timer任务是FreeRTOS创建的。

  3. 任务是配置成根据优先级抢占式的。

  4. 硬件中断服务例程(ISR)是由Vendor来实现的。

TrustZone

TrustZone是ARMv8-M处理器的基石。它提供了硬件的访问控制代码,内存和I/O,同时保留嵌入式应用程序的需求:实时响应,最小切换开销,受限的片上资源,便于软件开发。

ARMv8-M添加了一个额外的处理器状态的操作:安全的和不安全的执行状态。这些安全状态是正交于现有的线程和处理模式,从而在安全的和非安全状态两种模式间运行。

../../../../_images/TrustZone.png

TrustZone

TrustZone有如下特性:

  • 允许用户将内存划分为安全和非安全区域。

  • 允许在未经过身份验证时阻止调试安全代码/数据。

  • NVIC、MPU、SYSTICK、内核控制寄存器等也被备份到两个区域中,安全代码和非安全代码可以独立访问自己的资源。

  • 安全区和非安全区都有MSP和PSP堆栈指针。

  • 提出了Secure Gateway的概念,非安全代码可以通过Secure Gateway访问特定的安全代码,这也是非安全代码访问安全代码的唯一方式。

  • 提供了一个Stack Limit Checking(堆栈限制检查)功能,可以用于检测堆栈溢出的情况。在ARMv8.1-M架构中,每个堆栈指针都有相应的堆栈限制寄存器。

SAU(Security Attribution Unit)和IDAU(Implementation Defined Attribution Unit)的作用是将内存空间划分为安全和不安全的空间。CPU发出的指令都会通过SAU来判断是否符合安全规则,其余Bus Master例如DMA,GPU,USB等发出的指令都会通过IDAU来判断是否符合安全规则。如果违反安全规则,例如non-secure code访问secure region,就会触发secure fault/hard fault。

以下是SAU默认的secure,non-secure划分,以Single Bank(OTA升级方式之一)为例,共设定了7种NS或者NSC区域:

NS/NSC区域说明

区域

说明

Region0

ROM中NSC区域,存放供NS程序调用的API

Region1, 2

部分ROM,ITCM1,DTCM0

Region3

Data ram,Buffer ram,以及Flash最开头的SOCV config和OEM config

Region4, 5

Flash区域

Region6

PSRAM,Peripheral等区域

备注

sdk中默认不开启TrustZone,所有code的执行都在secure区域。如需开启TrustZone需要额外维护一个secure app,可以参考sdk中trustzone_demo:rtl87x2g_sdk_xxxx\samples\trustzone_demo

启动流程

系统上电或者重启,会执行启动流程,启动流程包括:

  • eFuse校验

  • 根据eFuse进行安全控制

  • Flash image校验和执行

eFuse校验决定是否启用secure boot,如启用secure boot,image authentication会涉及签名、CMAC、secure version校验。

../../../../_images/Boot_Flow.png

启动流程图

启动流程图中,“Flash Image Check and Execute”表示对各种Flash Image检查和执行,具体流程如下:

  1. 检查OEM Data(Flash layout包含在此文件中)

  2. 检查是否存在有效的待升级文件

  3. 检查OTA Bank Header文件

  4. 检查OTA Bank中每一个Flash image

  5. 执行image

Flash Image校验和执行是以上流程的流程图。Image检查方式是SHA256完整性校验(关闭secure boot)或者签名验证(打开secure boot)。执行OTA bank内Flash image的顺序:Boot Patch,BT Stack Patch,Secure APP,System Patch,BT Host,APP。

../../../../_images/Flash_Image_Check_and_Execution.png

Flash Image校验和执行

Dual Bank启动流程图中的“Dual Bank Process”是针对切换Bank模式升级Image的处理,在一个旧版本上升级一个新版本,Bank0和Bank1中都会存在images,启动流程会优先校验版本号高的OTA Header,版本号相同则校验Bank0,如果校验和解密成功,则执行该Bank内images;如果校验不成功,会继续校验版本号低的OTA Header。

../../../../_images/Dual_Bank_Boot_Flow.png

Dual Bank启动流程图

应用程序

SDK目录

└── SDK
    ├── bin                   应用程序链接的二进制文件
    ├── bsp                   板级和硬件相关的文件
    ├── doc                   文档
    ├── include               提供接口定义的头文件
    ├── samples               配置好可直接使用的Keil和GCC实例工程
    ├── subsys                上层和硬件无关的软件协议
    └── tools                 工具集

示例工程

为了帮助创建应用程序,SDK中已经创建好了许多示例工程,例如ble_peripheral以及一些BLE相关的示例工程。通过学习示例工程,开发者可以很容易地熟悉SDK。所有的示例工程已经配置好,并且根据RTL87x2G SOC划分好内存,具体内存划分请参考 Memory指南

下面以ble_peripheral为例,展示如何通过示例工程来开发客制化应用程序。

../../../../_images/ble_peripheral_Sample_Project.png

ble_peripheral工程示例

ble_peripheral工程中的文件分为以下几个类别:

  1. Device目录:存放启动代码

  2. CMSIS目录:存放CMSIS文件

  3. CMSE Library:Non-secure callable library

  4. Lib目录:应用程序使用的所有二进制文件

  5. Peripheral目录:应用使用的所有外设驱动和模块代码

  6. Profile目录:应用使用的BLE profiles或者服务

  7. APP目录:ble peripheral应用的实现

RTL87x2G APP MCU基于ARMv8.1架构,支持 MVE 指令集,可高效处理单精度整数和浮点数运算。默认SDK中发布的lib和sample app project都是选用如下device。

../../../../_images/app_project_device_select.png

app project device选择

../../../../_images/MCU_APP_supports_single-precision_integer_and_floating-point_MVE_instructions.png

MCU APP支持单精度的整数和浮点MVE指令

应用中的一些公共文件说明如下:

SDK公共文件说明

File name

Description

rom_uuid.h

UUID头文件是SDK用来识别ROM的,无需更改

ROM_NS.lib

ROM符号库,应用程序链接ROM中的符号

gap_utils.lib

实现BLE功能的GAP库

startup_rtl.c

RTL87x2G应用程序启动的C文件

system_rtl.c

RTL87x2G应用程序系统的C文件

board.h

配置引脚和DLPS的头文件

flash_map.h

Flash layout文件,此文件由Flashmap Generate Tool工具生成

mem_config.h

Memory配置相关的文件

示例工程可能会随着SDK一起更新。为了更好地使用最新的示例代码,建议把新增的用户代码组织起来模块化。每个示例工程的详细信息请参考对应示例工程的使用手册。

../../../../_images/APP_Flow.png

APP流程

APP初始化

Action

Description

board init

PINMUX和PAD初始化设定

gap init

GAP相关参数的初始化

profile init

BLE Profiles的初始化

power manager init

电源管理相关的初始化

SW timer init

软件定时器的初始化

app queue init

APP Queue的初始化

driver init

外设的初始化

系统是在main()函数中初始化,包括:Board、Peripherals、BT Stack、Profile、Power和Task等。

BT Stack,Profiles和外设驱动是在应用层任务中初始化,并且实现了IO消息机制。所有的功能都被封装成IO事件,这些事件是在相关的消息处理器中处理。

BT Stack消息也是被封装成BT IO事件,跟外设事件处理的方式一样。

../../../../_images/IO_Message_Handling_Flowchart.png

IO消息处理流程

消息和事件处理流程

  1. 原始消息的来源有通用IO Peripherals的ISR和BT Stack,处理流程如下。

    1. 来自通用IO Peripherals的MSG会被MSG分发器转发给IO MSG Handler处理。

    2. 来自蓝牙协议栈的MSG会被MSG分发器转发给BT状态机,BT状态机处理完MSG后,会封装成BT IO MSG发出,MSG分发器收到BT IO MSG后再转发给IO MSG Handler处理。

    3. IO MSG Handler收到MSG后再判断Event类别,进而调用对应的Event Handler处理。

  2. 用户程序负责以下事项。

    1. 实现IO Peripheral ISR,在ISR中完成初步处理,如果需要进一步处理则封装MSG发给APP。

    2. 维护IO MSG Handler,以便接收和处理用户定义的ISR MSG。

    3. 实现应用层相关的Event Handler。

  3. GAP层通知APP层是通过MSG和Event机制,而APP层可以直接调用GAP层的APIs。

IO消息

消息格式

typedef struct
{
    uint16_t type;
    uint16_t subtype;
    union
    {
        uint32_t  param;
        void     *buf;
    }u;
}T_IO_MSG;

消息类型定义

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;

消息子类型定义

以T_IO_MSG_UART为例,定义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;

用户自定义消息

APP开发者可以根据需求扩充定义Message Type以及自定义Subtype Message。

Pin设置

引脚的定义在board.h中定义。

#define KEY_0   P4_0
#define BEEP    P4_1
#define LED_0   P2_1
#define LED_1   P2_4

DLPS设置

详细请查阅 低功耗模式

存储

存储映射

RTL87x2G APP MCU内存包括ROM,RAM,Cache,Flash和eFuse,详情请查阅 Memory指南

Flash APIs

Flash操作的APIs如下所列,详细请查阅 Flash指南

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)是BT Stack和用户程序读写flash数据的抽象层,详情请查阅 Flash

eFuse

eFuse是一次编程的存储体,用来存储重要且固定的信息,例如:UUID,security key以及其它只会配置一次的信息。eFuse中每个bit不能从0改成1,并且也没有擦除的操作,所以更新eFuse要十分小心。Realtek提供MPTool更新eFuse。

中断

Nested Vectored Interrupt Controller (NVIC)

NVIC特性
  • 16个Real-M300V异常,96条可屏蔽的中断通道

  • 8个可编程的中断优先级

  • 支持Secure和Non-secure向量表的重映射

  • 低延迟异常和中断处理

  • 系统控制寄存器(System Control Registers)的实现

NVIC和处理器内核接口紧密耦合,使得低延迟中断处理和高效处理晚抵达中断都成为可能。所有的中断包括内核异常都由NVIC管理。中断向量表用于管理和处理不同类型的中断。它是存储在内存中的一个数据结构,包含了中断处理程序的入口地址。中断向量表机制提供了一种灵活的方式来处理不同的中断类型。通过在中断向量表中存储中断处理程序的入口地址,系统可以快速定位并调用与中断类型相关的处理程序,从而提高系统的响应速度和效率。
RTL87x2G支持两种方式来更新中断向量表:
  • RamVectorTableUpdate_ext API:允许在中断服务例程中运行XIP代码。但这将带来额外的4us入口和3.6us出口的CPU开销。

  • RamVectorTableUpdate API:需要确保中断服务例程运行RAM代码,没有额外的CPU开销。

RTL87x2G引入flash suspend和resume机制,该机制需要保证中断服务例程中禁止访问flash,因此在中断中加了一层wrapper。建议使用RamVectorTableUpdate_ext API,如果想要中断响应时间快,建议使用RamVectorTableUpdate API。

中断向量表

中断向量表

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

Watch Dog Timer interrupt

18

[2]

Internal use

19

[3]

Internal use

20

[4]

Zigbee_ISR

zigbee interrupt

21

[5]

BTMAC_ISR

BTMAC interrupt

22*

[6]

Pe ripheral_ISR

See Below Table: Peripheral ISR

(an Extension of interrupt)

23

[7]

RSVD

24

[8]

RTC

RealTime 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 channel7 global interrupt

43

[27]

DMA_Channel8

RTK-DMA channel8 global interrupt

44

[28]

DMA_Channel9

RTK-DMA channel9 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

Peripheral ISR

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

中断优先级

RTL87x2G中断支持3个固定最高优先级和8个可编程优先级。优先级数字代表的优先级高低如下。

0 > 1 > 2 > 3 > 4 > 5 > 6 > 7

中断优先级

Priority

Usage

-3

Reset Handler

-2

NMI

-1

Hard Fault

0~1

用于实时性要求非常高的中断

(注意:此优先级的中断不会被FreeRTOS的临界区屏蔽,但是中断处理函数内不能调用任何FreeRTOS的API)

2~6

通用的中断

7

SysTick和PendSV

电源模式管理

RTL87x2G支持四种功耗模式。

  • CPU Active

在Power active的模式下,如果程序没有进入到idle task,CPU 处于Active状态,CPU Clock会处于高速状态,默认是40M Clock。

  • CPU Sleep

在Power active的模式下,程序进入idle task,CPU 进入sleep状态,此时CPU clock会自动降速。如果CPU工作模式下处于40M Clock,CPU sleep时clock降低到625KHz。如果有使用PLL clock,slow clock 与 PLL Clock source的选择有关。

  • DLPS (Deep Low Power State)

系统休眠模式,较低的功耗,以及较快的进出时间,同时RAM内容保持。

  • Power Down

极致低功耗模式。此模式下RAM内容不保持,从Power Down模式退出执行重启流程,较DLPS模式耗时更长。只有LPC和PAD(关闭debounce)可以唤醒Power Down。

RTL87x2G会在满足特定的条件时进入低功耗模式,并且可以通过PAD、BT中断、RTC中断和OS software timer到期唤醒,详情请查阅 低功耗模式

调试

调试应用程序有以下两种方式,详情请查阅 调试指南

  1. 使用log机制跟踪代码的执行和数据。

  2. 使用Keil MDK或J-Link Commander和SWD进行调试,增加/删除断点以及访问/追踪memory等。