RTE在STM32中的应用

RTE简介

RTE 运行时环境

首先RTE的全称为,Runtime Environment。

定义​:指的是一套为应用程序提供核心支持的软件服务和资源的总和。它位于操作系统、硬件抽象层和应用程序之间,这里主要以数据为主,例如实时数据和参数设置。

​作用​:应用程序在运行时(Runtime)依赖于它来执行任务,例如任务调度、内存管理、中断处理和访问外设驱动;
并且这使得APP层可以与BSP层、硬件层完全解耦,使得APP的可移植性大大提高。
生成的宏定义还可以支持Matlab&Simulink的MBD编程,以完成复杂逻辑的功能实现。

在这里插入图片描述

RTE建立过程

  1. 使用EXECL表格来存放对应数据,如下图所示:
    在这里插入图片描述
  2. 通过VBA语言编写宏来生成对应的.c .h文件
    在这里插入图片描述
    以下是生成RTE.h的VBA代码示例,其他则先不展示,我会将源码提供给大家
Sub GenerateRTEDefineHeaderFile()
    On Error GoTo ErrorHandler
    
    ' 定义常量
    Const MAX_NAME_LENGTH As Integer = 40
    Dim filePath As String
    Dim fileNumber As Integer
    
    ' 1. 检查并准备文件
    If Not PrepareFileEnvironment(filePath, fileNumber) Then Exit Sub
    
    ' 2. 写入文件内容
    WriteHeaderFileContent filePath, fileNumber, MAX_NAME_LENGTH
    
    MsgBox "RTE_Define.h 文件已生成!" & vbCrLf & "路径: " & filePath, vbInformation
    Exit Sub
    
ErrorHandler:
    MsgBox "错误 " & Err.Number & ": " & Err.Description, vbCritical
    If fileNumber > 0 Then Close #fileNumber
End Sub

' 准备文件环境
Private Function PrepareFileEnvironment(ByRef filePath As String, ByRef fileNumber As Integer) As Boolean
    ' 检查目录
    If Len(Dir(ThisWorkbook.Path, vbDirectory)) = 0 Then
        MsgBox "无法访问当前目录", vbExclamation
        Exit Function
    End If
    
    ' 构建文件路径
    filePath = ThisWorkbook.Path & Application.PathSeparator & "RTE_Define.h"
    fileNumber = FreeFile()
    
    ' 尝试打开文件测试写入权限
    On Error Resume Next
    Open filePath For Output As #fileNumber
    If Err.Number <> 0 Then
        MsgBox "无法创建文件,请检查写入权限", vbExclamation
        Exit Function
    End If
    Close #fileNumber
    On Error GoTo 0
    
    PrepareFileEnvironment = True
End Function

' 写入文件内容
Private Sub WriteHeaderFileContent(ByVal filePath As String, ByVal fileNumber As Integer, ByVal maxNameLength As Integer)
    ' 打开文件
    Open filePath For Output As #fileNumber
    
    ' 写入文件头
    Print #fileNumber, "#ifndef _RTE_DEFINE_H"
    Print #fileNumber, "#define _RTE_DEFINE_H"
    Print #fileNumber, ""
    Print #fileNumber, "/* 自动生成的RTE_Define定义 */"
    Print #fileNumber, "/* 生成时间: " & Now & " */"
    Print #fileNumber, ""
    
    ' 写入工作表数据
    WriteWorksheetData fileNumber, maxNameLength
    
    ' 写入文件尾
    Print #fileNumber, "#endif /* _RTE_H */"
    
    ' 关闭文件
    Close #fileNumber
End Sub

' 写入工作表数据
Private Sub WriteWorksheetData(ByVal fileNumber As Integer, ByVal maxNameLength As Integer)
    Dim sheetNames As Variant
    Dim sheetIndex As Integer
    
    sheetNames = Array("参数类", "数据类")
    
    For sheetIndex = LBound(sheetNames) To UBound(sheetNames)
        WriteSingleWorksheet fileNumber, sheetNames(sheetIndex), maxNameLength
    Next sheetIndex
End Sub

' 写入单个工作表数据
Private Sub WriteSingleWorksheet(ByVal fileNumber As Integer, _
                                ByVal sheetName As String, _
                                ByVal maxNameLength As Integer)
    Dim ws As Worksheet
    Dim dataRange As Range
    Dim dataArray As Variant
    Dim i As Long
    
    On Error Resume Next
    Set ws = ThisWorkbook.Sheets(sheetName)
    On Error GoTo 0
    
    If ws Is Nothing Then
        MsgBox "工作表 " & sheetName & " 不存在,已跳过", vbExclamation
        Exit Sub
    End If
    
    ' 写入工作表标题
    Print #fileNumber, "/* " & sheetName & " 信号定义 */"
    
    ' 获取数据
    Set dataRange = ws.Range("A2:H" & ws.Cells(ws.Rows.Count, "A").End(xlUp).Row)
    dataArray = dataRange.Value
    
    ' 写入数据行
    For i = LBound(dataArray, 1) To UBound(dataArray, 1)
        WriteDataRow fileNumber, dataArray, i, maxNameLength
    Next i
    
    ' 添加分隔空行
    Print #fileNumber, ""
End Sub

' 写入单行数据
Private Sub WriteDataRow(ByVal fileNumber As Integer, _
                        ByVal dataArray As Variant, _
                        ByVal rowIndex As Long, _
                        ByVal maxNameLength As Integer)
    Dim signalID As Integer
    Dim signalEnName As String
    Dim signalChName As String
    Dim paddingSpaces As String
    
    ' 获取数据
    signalID = dataArray(rowIndex, 1)
    signalEnName = dataArray(rowIndex, 2)
    signalChName = dataArray(rowIndex, 3)
    
    ' 跳过空行
    If signalEnName = "" Then Exit Sub
    
    ' 写入宏定义
    Print #fileNumber, "//" & signalChName
    paddingSpaces = String(maxNameLength - Len(signalEnName), " ")
    Print #fileNumber, "#define SET_" & signalEnName & "(u16Value)" & paddingSpaces & "SetRteVal(" & signalEnName & ", u16Value)"
    paddingSpaces = String(maxNameLength - (Len(signalEnName) - 8), " ")
    Print #fileNumber, "#define GET_" & signalEnName & "()" & paddingSpaces & "GetRteVal(" & signalEnName & ")"
    Print #fileNumber,
End Sub
  1. 添加生成的文件进入keil工程,生成代码如下

RTE.c

#include <RTE.h>
/* 自动生成的RTE信号数组 */
/* 生成时间: 2025/10/29 11:02:26 */

/* 参数类 信号定义 */
RTE_PARMS_SRTUCT rte_parms[] =
{
    //ParmsName                                        默认值		Max Value,	Min Value,	Zoom,	Offset,				//SignalChName
    {0x00 /*RTE_SET_PARMS_START_FLAG*/,                0,			65535,			0,			1,			0,			},//设置参数开始位置
    {0x00 /*RTE_SET_PARMS_1*/,                         0,			65535,			0,			1,			0,			},//设置参数1
    {0x00 /*RTE_SET_PARMS_2*/,                         0,			65535,			0,			1,			0,			},//设置参数2
    {0x00 /*RTE_SET_PARMS_3*/,                         0,			65535,			0,			1,			0,			},//设置参数3
    {0x00 /*RTE_SET_PARMS_4*/,                         0,			65535,			0,			1,			0,			},//设置参数4
    {0x00 /*RTE_SET_PARMS_5*/,                         0,			65535,			0,			1,			0,			},//设置参数5
    {0x00 /*RTE_SET_PARMS_6*/,                         0,			65535,			0,			1,			0,			},//设置参数6
    {0x00 /*RTE_SET_PARMS_7*/,                         0,			65535,			0,			1,			0,			},//设置参数7
    {0x00 /*RTE_SET_PARMS_8*/,                         0,			65535,			0,			1,			0,			},//设置参数8
    {0x00 /*RTE_SET_PARMS_END_FLAG*/,                  0,			65535,			0,			1,			0,			},//设置参数结束位置
};

/* 数据类 信号定义 */
RTE_REAL_DATA_SRTUCT rte_real_data[] =
{
    //ParmsName                                        默认值		//SignalChName
    {0x00 /*RTE_REAL_DATA_START_FLAG*/,                0x00,		},//实时数据开始位置
    {0x00 /*RTE_REAL_DATA_1*/,                         0x00,		},//实时数据1
    {0x00 /*RTE_REAL_DATA_2*/,                         0x00,		},//实时数据2
    {0x00 /*RTE_REAL_DATA_3*/,                         0x00,		},//实时数据3
    {0x00 /*RTE_REAL_DATA_4*/,                         0x00,		},//实时数据4
    {0x00 /*RTE_REAL_DATA_5*/,                         0x00,		},//实时数据5
    {0x00 /*RTE_REAL_DATA_6*/,                         0x00,		},//实时数据6
    {0x00 /*RTE_REAL_DATA_7*/,                         0x00,		},//实时数据7
    {0x00 /*RTE_REAL_DATA_8*/,                         0x00,		},//实时数据8
    {0x00 /*RTE_REAL_DATA_9*/,                         0x00,		},//实时数据9
    {0x00 /*RTE_REAL_DATA_END_FLAG*/,                  0x00,		},//实时数据结束位置
};


RTE.h

#ifndef _RTE_H
#define _RTE_H

/* 自动生成的RTE信号定义 */
/* 生成时间: 2025/10/29 11:02:25 */

/* RTEDataStruct.txt 内容 */
#include "main.h"

#pragma pack(1)
typedef struct
{
	uint16_t SignalVal;			//数据
	uint16_t Zoom;			//精度
	uint16_t OffSet;			//偏移量
}RTE_REAL_DATA_SRTUCT;

typedef struct
{
	uint16_t SignalVal;			//数据
	uint16_t DefaultVal;			//默认值
	uint16_t MaxVal;			//最大值
	uint16_t MinVal;			//最小值
	uint16_t Zoom;			//精度
	uint16_t OffSet;			//偏移量
}RTE_PARMS_SRTUCT;
#pragma pack()

/* 参数类 信号定义 */
#define 		RTE_SET_PARMS_START_FLAG                (0)   /* 设置参数开始位置 */
#define 		RTE_SET_PARMS_1                         (1)   /* 设置参数1 */
#define 		RTE_SET_PARMS_2                         (2)   /* 设置参数2 */
#define 		RTE_SET_PARMS_3                         (3)   /* 设置参数3 */
#define 		RTE_SET_PARMS_4                         (4)   /* 设置参数4 */
#define 		RTE_SET_PARMS_5                         (5)   /* 设置参数5 */
#define 		RTE_SET_PARMS_6                         (6)   /* 设置参数6 */
#define 		RTE_SET_PARMS_7                         (7)   /* 设置参数7 */
#define 		RTE_SET_PARMS_8                         (8)   /* 设置参数8 */
#define 		RTE_SET_PARMS_END_FLAG                  (9)   /* 设置参数结束位置 */

/* 数据类 信号定义 */
#define 		RTE_REAL_DATA_START_FLAG                (0)   /* 实时数据开始位置 */
#define 		RTE_REAL_DATA_1                         (1)   /* 实时数据1 */
#define 		RTE_REAL_DATA_2                         (2)   /* 实时数据2 */
#define 		RTE_REAL_DATA_3                         (3)   /* 实时数据3 */
#define 		RTE_REAL_DATA_4                         (4)   /* 实时数据4 */
#define 		RTE_REAL_DATA_5                         (5)   /* 实时数据5 */
#define 		RTE_REAL_DATA_6                         (6)   /* 实时数据6 */
#define 		RTE_REAL_DATA_7                         (7)   /* 实时数据7 */
#define 		RTE_REAL_DATA_8                         (8)   /* 实时数据8 */
#define 		RTE_REAL_DATA_9                         (9)   /* 实时数据9 */
#define 		RTE_REAL_DATA_END_FLAG                  (10)   /* 实时数据结束位置 */

#endif /* _RTE_H */

RTE_Define.h

#ifndef _RTE_DEFINE_H
#define _RTE_DEFINE_H

/* 自动生成的RTE_Define定义 */
/* 生成时间: 2025/10/29 11:02:27 */

/* 参数类 信号定义 */
//设置参数开始位置
#define SET_RTE_SET_PARMS_START_FLAG(u16Value)                SetRteVal(RTE_SET_PARMS_START_FLAG, u16Value)
#define GET_RTE_SET_PARMS_START_FLAG()                        GetRteVal(RTE_SET_PARMS_START_FLAG)

//设置参数1
#define SET_RTE_SET_PARMS_1(u16Value)                         SetRteVal(RTE_SET_PARMS_1, u16Value)
#define GET_RTE_SET_PARMS_1()                                 GetRteVal(RTE_SET_PARMS_1)

//设置参数2
#define SET_RTE_SET_PARMS_2(u16Value)                         SetRteVal(RTE_SET_PARMS_2, u16Value)
#define GET_RTE_SET_PARMS_2()                                 GetRteVal(RTE_SET_PARMS_2)

//设置参数3
#define SET_RTE_SET_PARMS_3(u16Value)                         SetRteVal(RTE_SET_PARMS_3, u16Value)
#define GET_RTE_SET_PARMS_3()                                 GetRteVal(RTE_SET_PARMS_3)

//设置参数4
#define SET_RTE_SET_PARMS_4(u16Value)                         SetRteVal(RTE_SET_PARMS_4, u16Value)
#define GET_RTE_SET_PARMS_4()                                 GetRteVal(RTE_SET_PARMS_4)

//设置参数5
#define SET_RTE_SET_PARMS_5(u16Value)                         SetRteVal(RTE_SET_PARMS_5, u16Value)
#define GET_RTE_SET_PARMS_5()                                 GetRteVal(RTE_SET_PARMS_5)

//设置参数6
#define SET_RTE_SET_PARMS_6(u16Value)                         SetRteVal(RTE_SET_PARMS_6, u16Value)
#define GET_RTE_SET_PARMS_6()                                 GetRteVal(RTE_SET_PARMS_6)

//设置参数7
#define SET_RTE_SET_PARMS_7(u16Value)                         SetRteVal(RTE_SET_PARMS_7, u16Value)
#define GET_RTE_SET_PARMS_7()                                 GetRteVal(RTE_SET_PARMS_7)

//设置参数8
#define SET_RTE_SET_PARMS_8(u16Value)                         SetRteVal(RTE_SET_PARMS_8, u16Value)
#define GET_RTE_SET_PARMS_8()                                 GetRteVal(RTE_SET_PARMS_8)

//设置参数结束位置
#define SET_RTE_SET_PARMS_END_FLAG(u16Value)                  SetRteVal(RTE_SET_PARMS_END_FLAG, u16Value)
#define GET_RTE_SET_PARMS_END_FLAG()                          GetRteVal(RTE_SET_PARMS_END_FLAG)


/* 数据类 信号定义 */
//实时数据开始位置
#define SET_RTE_REAL_DATA_START_FLAG(u16Value)                SetRteVal(RTE_REAL_DATA_START_FLAG, u16Value)
#define GET_RTE_REAL_DATA_START_FLAG()                        GetRteVal(RTE_REAL_DATA_START_FLAG)

//实时数据1
#define SET_RTE_REAL_DATA_1(u16Value)                         SetRteVal(RTE_REAL_DATA_1, u16Value)
#define GET_RTE_REAL_DATA_1()                                 GetRteVal(RTE_REAL_DATA_1)

//实时数据2
#define SET_RTE_REAL_DATA_2(u16Value)                         SetRteVal(RTE_REAL_DATA_2, u16Value)
#define GET_RTE_REAL_DATA_2()                                 GetRteVal(RTE_REAL_DATA_2)

//实时数据3
#define SET_RTE_REAL_DATA_3(u16Value)                         SetRteVal(RTE_REAL_DATA_3, u16Value)
#define GET_RTE_REAL_DATA_3()                                 GetRteVal(RTE_REAL_DATA_3)

//实时数据4
#define SET_RTE_REAL_DATA_4(u16Value)                         SetRteVal(RTE_REAL_DATA_4, u16Value)
#define GET_RTE_REAL_DATA_4()                                 GetRteVal(RTE_REAL_DATA_4)

//实时数据5
#define SET_RTE_REAL_DATA_5(u16Value)                         SetRteVal(RTE_REAL_DATA_5, u16Value)
#define GET_RTE_REAL_DATA_5()                                 GetRteVal(RTE_REAL_DATA_5)

//实时数据6
#define SET_RTE_REAL_DATA_6(u16Value)                         SetRteVal(RTE_REAL_DATA_6, u16Value)
#define GET_RTE_REAL_DATA_6()                                 GetRteVal(RTE_REAL_DATA_6)

//实时数据7
#define SET_RTE_REAL_DATA_7(u16Value)                         SetRteVal(RTE_REAL_DATA_7, u16Value)
#define GET_RTE_REAL_DATA_7()                                 GetRteVal(RTE_REAL_DATA_7)

//实时数据8
#define SET_RTE_REAL_DATA_8(u16Value)                         SetRteVal(RTE_REAL_DATA_8, u16Value)
#define GET_RTE_REAL_DATA_8()                                 GetRteVal(RTE_REAL_DATA_8)

//实时数据9
#define SET_RTE_REAL_DATA_9(u16Value)                         SetRteVal(RTE_REAL_DATA_9, u16Value)
#define GET_RTE_REAL_DATA_9()                                 GetRteVal(RTE_REAL_DATA_9)

//实时数据结束位置
#define SET_RTE_REAL_DATA_END_FLAG(u16Value)                  SetRteVal(RTE_REAL_DATA_END_FLAG, u16Value)
#define GET_RTE_REAL_DATA_END_FLAG()                          GetRteVal(RTE_REAL_DATA_END_FLAG)


#endif /* _RTE_H */

RTE相关函数实现

实现以下功能:

  • 参数读取
  • 参数写入
  • 上电初始化
  • 参数恢复出厂
/****************************************************************************************
* @file         rteDateParse.c
* @brief        rte数据相关操作
* @author       lwz
* @date         2025/10/29
* @version      V1.0.0
* @note         1、数据初始化
                2、数据读取和写入
                3、数据恢复出厂
****************************************************************************************/

/*头文件添加区*/
#include "rteDateParse.h"
#include "RTE.h"
/*宏定义定义区*/

/*全局变量定义区*/

/*外部变量引用区*/
extern RTE_PARMS_SRTUCT rte_parms[] ;           //参数类RTE数据
extern RTE_REAL_DATA_SRTUCT rte_real_data[];    //数据类RTE数据

/*函数声明区*/

/*函数定义区*/

/***************************************************************************************
* @brief        设置RTE信号
* @param        rteSigId 要设置的信号ID 
*               date_t 传入的数据
* @retval       void
* @note         
***************************************************************************************/
void SetRteVal(uint16_t rteSigId, uint16_t date)
{
    uint16_t date_t = (date * rte_parms[rteSigId].Zoom) + rte_parms[rteSigId].OffSet;
    
    if(rteSigId > RTE_SET_PARMS_START_FLAG && rteSigId < RTE_SET_PARMS_END_FLAG)
    {
        if(rte_parms[rteSigId].MinVal <= date_t && rte_parms[rteSigId].MaxVal >= date_t)
        {
            rte_parms[rteSigId].SignalVal = date_t;
            //数据写入存储芯片以便永久保存 如EEPROM
        }
    }
    else if(rteSigId > RTE_REAL_DATA_START_FLAG && rteSigId < RTE_REAL_DATA_END_FLAG)
    {//数据类没有上下限,且无需存放在芯片中,掉电丢失
        rte_real_data[rteSigId].SignalVal = date_t;
    }
    else
    {
        //ERROR
    }
}

/***************************************************************************************
* @brief        读取RTE信号
* @param        rteSigId 要读取的信号ID 
* @retval       ret RTE的值
* @note         
***************************************************************************************/
uint16_t GetRteVal(uint16_t rteSigId)
{
    uint16_t ret = 0;
    
    if(rteSigId > RTE_SET_PARMS_START_FLAG && rteSigId < RTE_SET_PARMS_END_FLAG)
    {
        ret = rte_parms[rteSigId].SignalVal;
    }
    else if(rteSigId > RTE_REAL_DATA_START_FLAG && rteSigId < RTE_REAL_DATA_END_FLAG)
    {
        ret = rte_real_data[rteSigId].SignalVal;
    }
    else
    {
        //ERROR
        ret = 0;
    }
    
    return ret;
}

/***************************************************************************************
* @brief        rte上电初始化
* @param        void
* @retval       void
* @note         数据类全为0,参数类从EEPROM中读取
***************************************************************************************/
void rteInit(void)
{
    for(uint16_t i=RTE_SET_PARMS_START_FLAG; i<RTE_SET_PARMS_END_FLAG; i++)
    {
        rte_parms[i].SignalVal = 0;//此处应为从EEPROM中读取对应参数数据 暂时先写0
    }
    
    for(uint16_t i=RTE_REAL_DATA_START_FLAG; i<RTE_REAL_DATA_END_FLAG; i++)
    {
        rte_parms[i].SignalVal = 0;
    }
}

/***************************************************************************************
* @brief        rte参数回复默认值
* @param        void
* @retval       void
* @note         数据类不操作,参数类改为使用默认值
***************************************************************************************/
void rteRecovery(void)
{
    for(uint16_t i=RTE_SET_PARMS_START_FLAG; i<RTE_SET_PARMS_END_FLAG; i++)
    {
        rte_parms[i].SignalVal = rte_parms[i].DefaultVal;
    }
}

小结

使用RTE该架构,可是使得项目开发进度大大加快,使得各个功能之间相互解耦,各功能仅依赖于RTE所提供的数据即可运行,使得app的跨平台性、可移植性大幅提高,且多人团队开发更高效,非常值得尝试。

### STM32 RTE和HAL使用教程 #### 一、STM32CubeMX与HAL库简介 STM32CubeMX是ST意法半导体推出的用于简化基于STM32微控制器项目创建过程的应用程序。该应用程序不仅能够自动生成初始化代码,还允许开发者通过图形界面轻松配置外设功能以及中间件组件,极大地方便了开发人员的工作流程[^1]。 对于初学者来说,理解并掌握如何利用STM32CubeMX配合HAL库进行编程是非常重要的。HAL(Hardware Abstraction Layer)即硬件抽象层,旨在提供统一的操作接口给不同型号的STM32芯片,从而实现跨平台应用的最大化可移植性。 #### 二、安装必要的工具链 为了更好地理解和实践STM32 HAL库的功能,在开始之前需确保已正确设置了如下环境: - 安装最新版本的Keil MDK (Microcontroller Development Kit),这是目前广泛使用的ARM Cortex-M系列处理器集成开发环境之一; - 下载并安装STM32CubeMX软件; - 获取目标板对应的固件包(Firmware Package)。 #### 三、创建第一个基于HAL库的工程实例 下面将以点亮LED灯为例来展示具体步骤: ##### 步骤说明: 1. 打开STM32CubeMX,新建一个工程项目,选择合适的MCU型号。 2. 配置时钟树(Clock Configuration),使能所需外设(如GPIO端口)。 3. 利用Pinout & Configuration模块设置相应的引脚为输出模式(Output Mode)。 4. 导入生成的初始化文件到Keil IDE中继续编写业务逻辑部分。 5. 编写简单的C语言函数控制指定IO状态变化以达到闪烁效果。 ```c #include "main.h" int main(void){ /* 初始化全局变量 */ HAL_Init(); /* 系统时钟配置 */ SystemClock_Config(); /* GPIO初始化 */ MX_GPIO_Init(); while (1){ HAL_Delay(500); // 延迟500ms HAL_GPIO_TogglePin(GPIOA, LED_PIN); // 反转PA8引脚电平 } } ``` 上述代码片段展示了如何调用`HAL_GPIO_TogglePin()` API 来切换特定I/O的状态,进而驱动外部设备工作。值得注意的是,所有这些API都封装得很好,使得即使是对底层细节不太熟悉的程序员也能快速上手。 #### 四、深入学习资源推荐 除了官方提供的文档和支持之外,网络上有许多优质的开源社区可以作为进一步探索的好去处。例如GitHub上的各种案例分享可以帮助加深对实际应用场景的理解;而像Bilibili这样的视频平台上也有不少高质量的教学课程可供参考。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小李学不懂C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值