AUTOSAR DLT (Diagnostic Log and Trace)

AUTOSAR DLT模块用于接收和传输来自DET、DEM、SW-Cs的日志及RTE的跟踪信息。Dlt通过通信总线发送数据,支持运行时配置和非冗长模式。它定义了消息格式、标准与扩展报头,并依赖于RTE、PDU Router等模块。Dlt命令用于运行时修改模块行为,与SW-Cs交互,支持多个实例的SessionId管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

AUTOSAR Dlt (Diagnostic Log and Trace) 模块主要用来接收来自DET、DEM、SW-Cs的日志信息(log information)或者来自RTE的跟踪信息(trace information)。Dlt模块通过通信总线传输这些数据,使这些日志和trace信息在ECU外部可见。

为此,Dlt模块会定义了用于在如何在通信总线上发送和接收这些专用的日志/跟踪信息的API。

此外也可以通过NvM模块来永久保存Dlt模块的更新过滤器设置。这使得ECU能够以期望的级别传输日志/跟踪信息,而不需要在每次ECU启动时从通信总线(通过日志工具)发出明确的设置请求。

Dlt模块位于PduR模块和RTE模块之间。

请注意:

Dlt消息格式、可用的Dlt命令和Dlt协议(用于与外部日志和跟踪工具通信)会定义在另一个单独的文档中 [1]。更多信息请参考 Dlt协议规范

术语和定义

术语描述
Log and trace message (日志和跟踪消息)日志和跟踪消息包含描述软件中日志和跟踪事件的所有数据和选项。日志和跟踪消息由头部(header)和有效报文内容(payload)组成。
Dlt User (Dlt用户)一个Dlt用户表示生成的Dlt消息的来源。可能的用户是SW-Cs、RTE(用于VFB跟踪)、DEM或DET。
Log Message (日志信息)日志信息(Log Message)包含调试信息,如状态变化或值变化。
Trace Message(跟踪消息)跟踪消息包含通过VFB传递的信息。
ECU IDECU id是ECU的名称,由4个8位ASCII字符(如ab0或COMB)组成。
Session (会话)

会话是日志或跟踪消息源的逻辑实体。

如果多次实例化一个应用程序/SW-C,那么每个实例将获得一个相对于应用程序/上下文ID的全局惟一的会话ID。

如果一个应用程序/ SWC有几个向Dlt开放的端口,那么它可能有几个同时的日志或跟踪会话。由于AUTOSAR中没有特别为SW-C指定会话ID,所以可以通过端口定义参数值实现。

Session ID会话ID是日志或跟踪会话的标识号。
Application ID应用程序ID 是Application/SW-C的缩写。它标识日志和跟踪消息的来源。Application ID由4个8位ASCII字符组成。
Context ID (上下文ID)

Context ID是用户定义的标识符,用于Application/SW-C生成的日志和跟踪消息进行分组。Context ID由4个8位ASCII字符组成。
必须符合以下的规则:

1. 每个Application ID可以拥有多个Context ID。

2. Context ID 按照Application Id分组。

3. Context ID在Application ID中应该是唯一的。

4. 日志和跟踪消息的源通过元信息的“ApplicationID”和“ContextId”来标识。

Message ID (消息ID)

消息ID是描述信息特征的标识符,通过消息本身进行传输。消息ID用来唯一地标识一种日志或跟踪消息。

它可用于标识消息的源(在源代码中),并可用于描述消息的有效负载。Message ID在开发或配置时是静态固定的。

Log level (日志级别)日志级别定义了日志消息的级别分类。
Trace status(跟踪状态)如果应该发送跟踪消息,则跟踪状态提供信息。
Log Channel一种物理通信总线,用于传输Dlt消息。
External client (外部客户端)外部客户端是使用Dlt模块控制、监视和存储ecu提供的日志/跟踪消息的工具。

使用场景

下面内容会对ECU如何使用Dlt的场景进行分类的描述

虽然Dlt协议与总线无关,但建议使用通信具有更高带宽的总线,如以太网。尽管如此,Dlt的协议并不局限于以太网的使用。

使用Dlt进行常规日志记录(General logging with Dlt)

  1. 应用程序 / SW-C生成一条日志消息。
  2. Log Message发送给Dlt模块。
  3. Dlt模块将日志消息发送到通信总线
  4. 外部Dlt客户端记录日志消息

VFB的跟踪(Tracing of VFB)

  1. RTE调用Dlt提供的宏,Dlt调用Dlt API接口生成跟踪的消息。
  2. Dlt模块将生成的跟踪消息发送到实现了Dlt通信模块接口。
  3. Dlt通信模块将跟踪消息转发到网络。
  4. 外部客户端接收并存储跟踪消息。

运行时配置Dlt(Runtime configuration of Dlt)

  1. 外部Dlt客户端设置日志和跟踪级别,并将更改发送给Dlt模块。
  2. Dlt模块相应地调整其过滤器设置的配置。
  3. Dlt模块通知应用程序新的日志级别。

非冗长模式(Non-verbose mode)

可以通过不发送通信总线上的变量的元数据减少总线上的流量。此时可以使用外部FIBEX文件保存如何解析有效负载(payload)内容的信息。外部Dlt客户端将这些FIBEX文件中定义的元数据与接收到的数据合并并保存。

  1. 调用Dlt模块以非冗长模式进行传输Dlt消息。
  2. Dlt模块过滤并生成Dlt消息。
  3. Dlt模块将Dlt消息发送到通信总线。
  4. 外部Dlt客户端从外部FIBEX文件中获取元信息。
  5. 合并后的信息由外部Dlt客户端存储。

协议规范(Protocol specification)

消息格式

对于调试数据和控制信息,只需使用相同的Dlt消息格式。

它由一个标准报头、一个可选的扩展报头和一个有效复杂段组成。

标准报头(Standard Header)

Dlt标准报头应由以下字段组成,顺序如下:

位置描述
字节0HTYP(报头类型)
字节1MCNT(消息计数器)
字节2-3LEN(长度)
字节4-7ECU (ECU ID)
字节8-11SEID(会话ID)
字节12-15TMSP(时间戳)

扩展报头(Extended Header)

如果标准报头的UEH位设置为' 1 ',则传输在Dlt扩展报头格式中定义的附加信息。Dlt扩展报头直接附加在Dlt标准报头字段之后。

Dlt扩展报头格式应由以下字段按以下顺序组成:

位置描述
字节0MSIN(消息信息)
字节1NOAR(参数的数量)
字节2-5APID(应用程序ID)
字节6-9CTID(上下文ID)

正文格式(Body/Payload format)

Dlt正文数据紧跟着Dlt头或者Dlt扩展头(如果使用的话)。Dlt正文数据包含被Log或Trace的参数,或者包含控制信息。

依赖的模块

RTE

RTE(包括VFB和BSW调度器),主要用于与SW-Cs交互,生成日志和跟踪消息,并循环调用Dlt模块的Tx函数。

PDU Router

为了在通信总线上传输Dlt消息,Dlt模块会与PDU Router进行交互。

NvM

为了加载和存储相关的配置,如过滤器设置和日志通道分配。NvM模块并不是必须,可以选用。

GPT

为了获得一个时间戳,GPT模块可以用于此目的。

StbM

为了以标准/扩展格式获取同步时间值。本地时间基数(Local Time Base)派生于全局时间基数(Global Time Base),StbM模块可用于此目的。

DET

为了能够报告默认错误并将DET错误转发给通信总线,Dlt模块必须与DET模块进行交互。然而,与DET的交互并不是必须,可以选用。

DEM

为了能够报告开发错误并在通信总线上传输DEM事件,Dlt模块必须与DEM模块进行交互。然而,与DEM的交互并不是必须,可以选用。

文件结构

功能定义

下面的内容会描述Dlt模块在与SW-Cs、PduR和外部日志设备(External client)交互时,需要的AUTOSAR特定数据和控制路径。

Dlt命令 (Dlt commands)

Dlt协议指定由唯一的Service id标识的各种Dlt命令。Dlt命令用于在运行时修改Dlt模块的行为,例如,获取关于当前Dlt配置的信息或更改过滤器设置。(PRS_Dlt_00635)

Service IDDlt CommandDescription
0x01SetLogLevel设置日志级别
0x02SetTraceStatus启用/禁用跟踪消息
0x03GetLogInfo返回已注册SW-C的LogLevel
0x04GetDefaultLogLevel返回通配符的日志级别
0x05StoreConfiguration存储当前配置非易失性
0x06ResetToFactoryDefault将配置设置回默认值
0x0ASetMessageFiltering启用/禁用Dlt过滤器
0x11SetDefaultLogLevel设置通配符的日志级别
0x12SetDefaultTraceStatus启用/禁用通配符的跟踪消息
0x15GetDefaultTraceStatus获取通配符的当前TraceLevel
0x17GetLogChannelNames返回LogChannel的名称
0x1FGetTraceStatus获取当前跟踪状态(开启/关闭)
0x20SetLogChannelAssignment添加/删除给定的LogChannel作为输出路径
0x21SetLogChannelThreshold为给定的LogChannel设置过滤阈值
0x22GetLogChannelThreshold获取给定LogChannel的筛选器阈值
0x23BufferOverflowNotificationDLT模块内缓冲区溢出的指示

Dlt与软件组件的交互

Dlt模块为SW-C提供了可用于发送日志和跟踪消息的接口。

可选地,SW-C可以为日志级别阈值(log level threshold)和跟踪状态变更通知提供一个Port口。这些端口由Dlt模块提供,分别为了不同ApplicationId / ContextId的每个元组而定义。这些通知可以用来避免影响SW-C已经生成的日志和跟踪消息,而不是让它们稍后被Dlt模块过滤掉。

由于Dlt模块支持SW-C的多个实例,它们使用相同的ApplicationId/ContextId元组,一个额外的SessionId参数允许区分来自相同SW-C的不同实例的日志/跟踪消息。

分离那些互相SW-Cs技术,避免SW-Cs必须使用独特的SessionId调用SendLogMessage / SendTraceMessage(细节,见下一章节),Dlt模块提供了一个专用P-Port每SW-C配置(参见配置参数DltSwc) SessionId作为port-defined-argument管理。

如果已配置的SW-C被标记为对日志级别的通知和跟踪状态更改感兴趣,Dlt模块还提供相应的R-Port来通知相应的SW-C。

由SW-C负责ApplicationId/ContextId元组的信息,在运行时分别通过调用RegisterContext和UnregisterContext为SW-C配置和/或更新。

Dlt模块会为每个配置的SW-C提供一个接口DltService类型的P-Port。P-Port接口包含SessionId作为端口定义的参数。Dlt模块也会为每个配置的SW-C提供一个R-Port类型的接口LogTraceSessionControl(见第8章),其中配置参数DltSwcSupportLogLevelChangeNotification会被设置为TRUE。SW-C需要负责的ApplicationId / ContextId元组,因此在日志级别或跟踪状态更改时需要通知该元组,可以从配置参数DltSwcContext取得。

参考

  1. ^DLT Protocol Specification (PRS_DLTProtocol.pdf) https://www.autosar.org/fileadmin/user_upload/standards/foundation/1-0/AUTOSAR_PRS_DiagnosticLogAndTraceProtocol.pdf

二、DLT协议介绍

DLT消息包含三个部分:标准头、扩展头、有效载荷。如下图

Image

2.1 标准头

标准头有16个字节大小,分为6个部分。它们之间的名称和顺序如下图所示

Image

Byte0:Header Type,这里用来配置DLT的可选项,比如带不带ECU ID、Session ID、时间戳等,DLT协议版本号、大端优先。具体如下图所示:

Image

1为采用,0为不采用如果使用冗余模式,则UEH位必须为1

  • Byte1:Message Counter,从0开始最大255,可以在一定程度上识别丢失的消息。

  • Byte2-3:Length,这个字段指示整个DLT消息的长度,包括标准头、扩展头、有效载荷

  • Byte4-7:ECU ID,可选的ECU ID用于识别哪个ECU发送了Dlt消息。因此,强烈建议ECU ID在车辆内是唯一的。

  • Byte8-11:Session ID,可选的Session ID用于标识ECU中的日志或跟踪消息的来源。

  • Byte12-15:Timestamp,对产生的DLT消息添加时间信息。

2.2 扩展头

扩展头字段是紧跟在标准头后面的,如果标准头中‘UEH’位位1,则表示该DLT消息有扩展头。扩展图的结构如下图所示:

Image

-Byte0:Message Info,该字节的字段非常重要,设计到dlt消息的类型分类,用来区分是日志消息、跟踪消息、网络消息、控制消息。字段结构如下图所示:

Image

VERB为1时表示有效载荷必须按冗余模式传输MSTP表示DLT的类型,一共分四种:日志消息、跟踪消息、网络消息、控制消息MTIN表示不同类型DLT消息各自的下级分类

一图胜千言

Image

  • Byte1:Number of Arguments:参数数量表示一条Dlt消息的有效负载段中连续参数的数量。在冗余模式有效,非冗余模式此字段因为0x00

  • Byte2-5:Application ID,应用程序ID是应用程序的缩写,它生成Dlt消息。

  • Byte6-9:Context ID,Context ID是用户定义的ID,用于(逻辑上)对应用程序生成的Dlt消息进行分组。

2.3 有效载荷2.3.1 非冗余模式非冗余模式下的的有效载荷就比较简单,只传输参数值(不需要任何关于它们的元信息),以及其他属性(如参数名称或类型),为了允许在接收到的Dlt消息中正确地分解所包含的参数值,将向有效负载添加专用的message ID。非冗余模式需要外部解析文件,用来解析Message ID通过消息ID和外部描述的组合,以下信息应该是可恢复的:类型信息:Type Length、Data Type、String Coding 、Variable Info 、Fixed Point考虑到MCU的处理能力,非冗余模式只传送dlt消息中的非静态数据,而每条dlt消息中的静态数据通过外部解析文件与Message ID进行关联,非冗余模式DLT消息结构如下:

Image

2.3.1.1 非冗余模式dlt消息示例

通过下面的例子,我们来看下非静态数据是如何组装,传输和解析的。

假设下面这条日志消息将要传送给外部DLT客户端:

  • 静态文本:“Temperature measurement”

  • 8位uint:measurement_point = 1 (no unit)

  • 32位浮点型:reading = 22.1 Kelvin

  • 在源代码中的这个特定位置上有一个唯一的消息ID,用来表示这个日志消息调用。以下信息与这个消息ID相关联:

  • 源码位置:source file “temp_meas.c”, line number 42

  • 静态文本:“Temperature measurement”

  • 值位8位无符号整数。变量名=“measurement_point” , 单位 = “”

  • 值位32位浮点型,变量名= “reading”,单位=“Kelvin”

  • 所有的静态数据已经与message ID关联了,所以只用传输非静态数据,这条dlt消息的非静态数据如下所示:

根据消息ID,接收方可以重新组合此Dlt消息的所有静态数据(源代码中的位置、静态文本、变量名和单元)。非静态数据将被一致地打包传输。可以通过使用与消息ID相关联的信息进行解释。此外,参数的顺序与消息ID相关联。

2.3.1.2 非冗余模式被传输数据的解析格式外部文件像ASAM Fibex文件,保存着如何解析有效载荷的信息。应用程序或中间件的软件供应商应提供此描述文件。由于Dlt可以有多个日志或跟踪消息源(多个应用程序或诊断模块),因此可以将提供的描述文件合并到给定ECU的一个文件中。每个用于描述非详细消息的Fibex描述文件只对应于一个ECU的日志或跟踪消息。这是因为每个ECU的消息id是唯一的。此外,ECU的软件版本号必须由描述文件提供。原则上,每个日志或跟踪消息都相当于某些网络协议中已知的PDU。在这里,日志或跟踪消息的描述应该等同于Fibex指定的CAN-Frame。来自Extended Header的信息被另外放入FRAME-TYPE xml元素中的xml元素中。非静态数据由PDU和SIGNAL xml元素描述。从用户的角度来看,日志或跟踪消息有几个参数。这些参数可以是静态文本或非静态变量。只传输非静态变量的数据。为了用所有参数重新组合整个消息,一个FRAME xml元素应该包含一些空的PDU xml元素,这些元素用静态文本表示参数。此文本应置于PDU xml元素的DESC xml元素中。

  • 一条日志或追踪消息必须是一个Fibex XML元素框架表示

  • 消息ID必须是<FRAME>XML元素的ID属性

  • 下面的示例显示了FIBEX XML中示例Dlt消息的描述。

<fx:FRAME
 ID="ID_1"> <ho:SHORT-NAME>Dlt Message with 
ID_1</ho:SHORT-NAME> 
<fx:BYTE-LENGTH>1</fx:BYTE-LENGTH> 
<fx:FRAME-TYPE>OTHER</fx:FRAME-TYPE> 
<fx:PDU-INSTANCES> <fx:PDU-INSTANCE ID="P_1_0"> 
<fx:PDU-REF ID-REF="PDU_1_0"/> 
<fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER> 
</fx:PDU-INSTANCE> <fx:PDU-INSTANCE ID="P_1_1"> 
<fx:PDU-REF ID-REF="PDU_1_1"/> 
<fx:SEQUENCE-NUMBER>1</fx:SEQUENCE-NUMBER> 
</fx:PDU-INSTANCE> <fx:PDU-INSTANCE ID="P_1_2"> 
<fx:PDU-REF ID-REF="PDU_1_2"/> 
<fx:SEQUENCE-NUMBER>2</fx:SEQUENCE-NUMBER> 
</fx:PDU-INSTANCE> </fx:PDU-INSTANCES> 
<fx:MANUFACTURER-EXTENSION> 
<MESSAGE_TYPE>DLT_TYPE_LOG</MESSAGE_TYPE> 
<MESSAGE_INFO>DLT_LOG_DEBUG</MESSAGE_INFO> 
<APPLICATIONID>APPI</APPLICATIONID> 
<CONTEXTID>CONI</CONTEXTID> 
<MESSAGE_SOURCE_FILE>demo.c</MESSAGE_SOURCE_FILE> 
<MESSAGE_LINE_NUMBER>72</MESSAGE_LINE_NUMBER> 
</fx:MANUFACTURER-EXTENSION> </fx:FRAME> 
<!--=============== 1. Parameter ==================-->
<fx:PDU
 ID="PDU_1_0"> <ho:SHORT-NAME></ho:SHORT-NAME> 
<ho:DESC>Temperature measurement</ho:DESC> 
<fx:BYTE-LENGTH>0</fx:BYTE-LENGTH> 
<fx:PDU-TYPE>OTHER</fx:PDU-TYPE> </fx:PDU>
<!--=============== 2. Parameter ==================--> 
<fx:PDU
 ID="PDU_1_1"> 
<ho:SHORT-NAME>measurement_point</ho:SHORT-NAME> 
<fx:BYTE-LENGTH>1</fx:BYTE-LENGTH> 
<fx:PDU-TYPE>OTHER</fx:PDU-TYPE> <fx:SIGNAL-INSTANCES>
 <fx:SIGNAL-INSTANCE ID="S_1_0"> 
<fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER> <fx:SIGNAL-REF
 ID-REF="S_UINT8"/> </fx:SIGNAL-INSTANCE> 
</fx:SIGNAL-INSTANCES> </fx:PDU> 
<!--=============== 3. Parameter ==================--> 
<fx:PDU
 ID="PDU_1_2"> <ho:SHORT-NAME>reading</ho:SHORT-NAME> 
<fx:BYTE-LENGTH>1</fx:BYTE-LENGTH> 
<fx:PDU-TYPE>OTHER</fx:PDU-TYPE> <fx:SIGNAL-INSTANCES>
 <fx:SIGNAL-INSTANCE ID="S_1_0"> 
<fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER> <fx:SIGNAL-REF
 ID-REF="FLOA32"/> </fx:SIGNAL-INSTANCE> 
</fx:SIGNAL-INSTANCES> </fx:PDU>
2.3.2 冗余模式

DLT的冗余模式相对于非冗余模式,显而易见,传递的数据更加全面完整,如果ECU的内存和带宽都够,建议使用冗余模式传输DLT消息。

冗余模式下的DLT消息结构如下图所示:

Image

数据负载包含变量的值(即应用程序或中间件的调试信息),它将在通信总线上传输。除了变量值本身之外,还需要提供变量的大小和类型等信息。该信息包含在Type Info字段中。-Type Info:32位,表示元数据信息。

Image

从上图可以看出,Type Info主要描述“Data payload”类型信息。

  • Type Length(TYLE):Type Length指定标准数据类型的长度。比如:规定BOOL型为8位,SINT和UINT为8位、16位、32位、64位、128位,FLOA型为16位、32位、64位、128位。

  • Variable Info(VARI): 如果设置了变量信息(VARI),则可以添加变量的名称和单位。两者都包含一个长度信息字段和一个带有文本(名称或单元)的字段。长度字段包含关联的名称或单元字段的字符数。只在某些数据类型中添加单元信息。

  • Fixed Point(FIXP):如果使用定点值,则应设置定点(FIXP)位。比数据字段表示一个固定点变量的物理值。为了解释不动点变量,必须计算这个变量的逻辑值。逻辑值由不动点变量的物理值、量化值q和偏移量o来计算。逻辑值Lv和物理值Pv之间的关系是Lv=Pv*q + O不动点必须是整型数据

  • String Coding(SCOD): String Coding 仅对String 类型(STRG)的字符串数据进行编码。所有其他字符串,如参数名称、单元和描述都是用8位ASCII格式编码的。

  • Bool:如果数据是布尔型,1就代表True,0代表False。

  • Signed and Unsigned:整型和无符号整型数据。该位设置时,代表Data payload里的数据是整型和无符号整型数据。

  • FLOA:浮点型,该位置1时,代表Data payload里的数据时浮点型数据

  • String(STRG):字符串,该位置1时,代表Data payload里的数据是字符串

  • Array(ARAY): 该位置1时,代表Data payload里的数据是数组。

  • Struct(STRU):该位置1时,代表Data payload里的数据是数组。

  • Raw(RAWD):该位置1时,代表Data payload里的数据是原始数据。

  • Trace Info(TRAI):该位置1时,跟踪信息(如模块名/函数)应在参数中传递。在数据有效负载的起始,一个16位无符号整数应指定跟踪数据字符串的长度,以字节为单位,包括终止字符。介绍了那么多,来个示例解释下自然数据类型参数是如何表示的吧下面这个示例展示了如何在冗余模式VARI置1的情况下,将一个8位无符号整型数据组装起来。Type Info是描述数据的32位字段。在这个例子中,它定义了变量类型(无符号整数)、它的长度(8位)和描述变量名称和单位的variable Info (VARI)的存在。Variable Info后面跟着两个16位无符号整数,描述变量的Name和Unit的长度。后面跟着两个以空结束的字符串,它们描述了Name和Unit。最后,变量值紧随其后。Data字段的长度是8位。

介绍了那么多,来个示例解释下自然数据类型参数是如何表示的吧下面这个示例展示了如何在冗余模式VARI置1的情况下,将一个8位无符号整型数据组装起来。Type Info是描述数据的32位字段。在这个例子中,它定义了变量类型(无符号整数)、它的长度(8位)和描述变量名称和单位的variable Info (VARI)的存在。Variable Info后面跟着两个16位无符号整数,描述变量的Name和Unit的长度。后面跟着两个以空结束的字符串,它们描述了Name和Unit。最后,变量值紧随其后。Data字段的长度是8位。

Image

Type Info字段各个位之间的组合表

Image

下表显示了根据使用的变量类型的强制(标记x)和可选(标记o)设置:

Image

为了识别日志或跟踪消息的来源,需要在Dlt消息中添加一些在源代码中找到位置的信息。因此,Dlt消息中的前两个参数应为:

源文件的名称(字符串)代码行(无符号整数)日志或跟踪消息的第一个参数应该是一个字符串参数,其中字段“Name”(在Variable Info中)包含字符串“source_file”,数据字段包含源文件的URL。

日志或跟踪消息的第二个参数应该是UINT参数(32位),其中字段“Name”(在Variable Info中)包含字符串“line_number”,数据字段包含发送日志或跟踪消息的源文件中的行号。

2.4 DLT服务(命令)

以下章节将介绍已定义的Dlt命令,包括唯一标识(Service ID)、格式和所需参数。下面的表格表示DLT支持的服务命令:

Image

三、时序图

  • DLT 数据消息传输时序图(Transmission of Dlt Data Message)

Image

  • 设置日志登记过滤器(Set LogLevel Filter)

Image

  • 缓存溢出(Buffer Overflow)

Image

四、术语解析

Image

 https://mp.weixin.qq.com/s/FavHldlMaakMjCmUIQ2BLwicon-default.png?t=N7T8https://mp.weixin.qq.com/s/FavHldlMaakMjCmUIQ2BLw

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值