- 博客(143)
- 资源 (29)
- 收藏
- 关注
原创 基于Vector Davinci SIP的标定实现方法
Vector协议栈生成的代码中,SWC调用标定数据接口的时候,是通过结构体指针来调用的,这个结构体指针默认指向的是Flash中的标定数据结构体,但这个指针是允许修改的,所以我们可以在RAM中划分一块标定RAM空间,在程序开始运行的时候,把Flash中的标定数据复制到标定RAM空间内,创建一个标定数据镜像,同时把标定数据指针指向这个镜像,这样当SWC想要使用标定数据的时候,就可以从RAM中取值。这样每个标定数据在Flash中的位置就取决于它在结构体中的位置,而它在结构体中的位置我们是可以通过代码来控制的。
2024-09-06 11:42:30
941
原创 电机控制——底软需求
ADC0组的触发方式采用硬件触发,使用上面配置的PWM参考通道所引用的TOM通道触发,即每个PWM周期中间位置会触发一次ADC采样。DMA最大通道最先被触发,然后以菊花链方式依次触发接下来的几个配置为菊花链的通道,直到某个通道没有被配置为菊花链,则会触发一个中断。使用GTM中的TOM通道触发PWM,GTM模块的主时钟为100M,PWM所引用的TOM通道时钟分频系数为1,即该通道的时钟也为100M。ADC中断处理方式配置为DMA,中断优先级就是DMA的通道,电流采样配置为最大DMA通道。
2023-12-25 08:52:45
1320
1
原创 Davinci NvM Block配置
且Fee Block的数量由NvM Block的类型决定,当NvM Block是Native时,会生成一个Fee Block;比如我们现在想读上面这个Block的第3组数据,先调用接口函数设置Dataset Index = 2(Index从0开始),然后调用NvM_ReadBlock接口,这时协议栈会用上面的方法计算Fee Block Number = 0x04 << 4 + 2 = 0x42,所以去读Block Number = 0x42的Fee Block的数据。
2023-10-17 08:26:40
2693
2
原创 Davinci 集成NvM协议栈的步骤
NvM中添加数据块,Fee中添加相应的数据块。Mcal如果使用EB生成,需要在EB中配置Fee,或Davinci中配置好之后把配置导入到EB中。在代码中添加NvM_ReadAll、NvM_WriteAll、NvM_WriteBlock等操作。在EcuMDriverInitItemsOne中添加Fls和Fee的Init函数。代码中添加数据块的RAM Block和ROM Block。NvM和Fee模块配置中不要启用Polling。Mcal添加Fls、Fee和Crc模块。BSW添加NvM和MemIf模块。
2023-10-13 09:06:45
1494
2
原创 电机控制——PID基础
本文来讲一下PID调节器。在实际的系统中,因为摩擦、阻力等外界因素的存在,系统的实际输出与我们期望的输出通常存在误差,。PID模块被周期性的调用,模块的输入是实际输出与期望输出之间的误差值,模块的输出是一个补偿,这个补偿输入给系统,使得系统的输出增大或减小,逐步贴近期望输出。这里需要注意一下,系统的输出不可能阶跃性的增加,是需要时间的,比如车辆提速、水位升高等。PID模块通过控制系统的输入,使得系统的输出在一个PID周期内增加所期望的补偿值。
2023-10-10 18:31:09
3377
1
原创 电机控制——高数基础
最近开始学习电机控制,将会写一个系列学习笔记,作为一个新手,肯定有理解不到位或错误的地方,仅供大家参考,欢迎交流指正。先复习一下微积分和自动控制原理,大学学的忘得一干二净。
2023-10-10 18:15:47
405
原创 英飞凌 Tricore 架构中断系统详解
只有当新的中断的优先级大于组内最高优先级的时候,中断才会被打断。总结可知,Tricore支持更高优先级的中断打断当前正在执行的中断,但如果新的中断优先级更低,CPU是直接丢弃还是在当前中断处理完成后再进行处理,没有找到具体的依据,但手册中是这样说的:以上原因会block the CPU from immediately responding to the interrupt request generated by the ICU,也就是说不能立即处理,感觉应该是条件满足的时候还是会处理。
2023-09-27 17:02:08
4449
9
原创 AUTOSAR Davinci Idle task 与 Init Task的配置
Init Task遇到的问题是,软件自动生成的Init Task是AutoStart的,StartOS之后自动运行,在Init Task中调用EcuM_StartupTwo()。我本来准备把自己想要放在Background运行的runnable直接放在自动生成的这个Idle Task里的,但是mapping上之后,生成代码时候提示Background类型的runnable必须mapping到优先级最低的task上,当前mapping的task不是优先级最低的task。
2023-09-05 11:16:53
1905
原创 基于ETAS ISOLAR创建多核Bsw工程的流程
EcuC中创建多个EcucPatition,然后生成Bsw的时候会给每个核生成一个EcuM模块。EcucPartition_0的BswModuleExcution设置为True,其余设置为False。OS 中创建多个OsApplication,OsApplication中引用EcucPartition。生成Bsw.System中创建多个EcuPatition,然后把Component mapping到Partition上。Ecu抽取创建OSTask并关联OsApplicationRunable
2023-09-04 09:16:40
1144
原创 AUTOSAR NvM Block的三种类型
举个例子:座椅位置是RAM中的一个数据,车上的座椅位置记忆功能支持记忆四个位置的数据,这四个位置数据存放在NvM中,可以由用户修改,还有座椅最前和最后两个位置的数据是固定的,存放于ROM中,不支持修改。这两个配置参数,NvMNvBlockNum代表NvM中存储的数据个数,可读可写,NvMRomBlockNum代表ROM中存储的数据个数,只可读,不可写,同时NvMRomBlockDataAddress 配置项中配置的ROMBlock数组的大小也要等于NvMRomBlockNum。
2023-08-17 18:00:33
1120
1
原创 AUTOSAR NvM协议栈集成方法
上文我们说过FlsTotalSize这个配置项代表用于模拟EEPROM的DFlash的大小,除此之外Fls模块中还需要配置一个FlsSector,TC234这几个配置项都是固定的,不允许改动,实测这里的FlsSectorSize没有作用,生成代码的时候是把FlsTotalSize/2作为每个Sector的大小。需要注意的是Fee中的FeeSector大小需要根据FlsSector的大小进行配置,即配置为FlsTotalSize/2,本次我配置的FlsTotalSize为0x18000。
2023-08-17 16:27:47
1110
原创 AUTOSAR NvM 同步机制
把Nv Block中的数据copy到NvM_DstPtr指向的RAM中,NvM_DstPtr可以是临时RAM,也可以是永久RAM(永久RAM即配置工具中配置的RAM Block)。如果NvM_DstPtr是NULL_PTR,且配置了永久RAM,那么数据会被copy到永久RAM中。
2023-05-16 15:14:27
3995
4
原创 NXP MCU CAN波特率(位时间)配置详解
1. 概述本文将会详细讲解如何设置NXP MCU的CAN波特率、位时间、采样点等属性。波特率即CAN总线传输频率,位时间是波特率的倒数,例如波特率是500K,那么位时间 = 1 / 500000 = 0.000002s = 2000ns。我们先来看一下S32K144单片机的EB中与CAN总线波特率相关的可配置参数有哪些:...
2022-01-20 12:02:09
8501
1
原创 AUTOSAR —— CAN网络管理(CanNm)
本文详细介绍了AUTOSAR CAN网络管理,包括状态转换、策略、时间参数等,读完本文可以对AUTOSAR网络管理有比较全面的认识。
2022-01-07 17:00:09
59899
32
原创 AUTOSAR —— S32K144 的 Fls 和 Fee 模块配置
本文来简要介绍一下如何在EB中配置AUTOSAR Fls和Fee模块。Fls模块是Flash的驱动,执行具体的Flash擦写读取等操作。Fee模块的全称是FlashEEPROMEmulation,即Flash模拟EEPROM,是为了解决Flash擦写寿命比较短的问题,通过算法实现各个Flash块的交替擦写,以延长寿命。1. Fls(1)FlashSector(扇区)Fls模块中最重要的一点就是配置FlsSector,如下图所示,一共配置了8个Sector,每个Sector可以选择对应的Flash物理扇
2021-12-23 18:48:43
13373
3
原创 NXP S32系列MCU官方AUTOSAR OS分析(二)
本文将会介绍S32系列MCU官方提供的AUTOSAR OS中各种对象的实现方法和EB中的配置方法,在开始之前先推荐一篇博客,详细介绍了AUTOSAR OS的各类对象:https://blog.youkuaiyun.com/AgingMoon/article/details/78945846(1)OS中的定时器AUTOSAR的定时器都叫做COUNTER,是OS的心脏,分为两种,一种是软件计数器(SWCOUNTER),一种是硬件计数器(HWCOUNTER),关于这两种COUNTER的区别建议参考下面这篇博客,介绍的很
2021-12-20 11:41:40
7013
3
原创 NXP S32系列MCU官方AUTOSAR OS分析(一)
1. 概述我之前介绍过如何用Keil编译NXP官方提供的AUTOSAR OS,想要了解的朋友可以去翻一下之前的文章,本文来简要介绍下AUTOSAR OS的代码实现。我使用的单片机时S32K144,AUTOSAR的版本是4.0.32. 源码分析(1)StartOSStartOS()函数是AUTOSAR OS的入口,在main函数中做一些硬件和应用层的初始化,之后进入StartOS。在这个函数中,会对各种对象(Object)进行初始化,如Application、Task、Alarm、ISR、Time
2021-12-15 17:44:01
9168
原创 S32K1XX系列单片机 ——用Keil编译官方提供的AUTOSAR OS
1. 概述NXP官方提供了AUTOSAR OS代码,并且可以用EB进行配置,但官方的例程不能直接适用于Keil,本文就来介绍下如何在Keil上编译官方的AUTOSAR OS源码。之前我们已经介绍过如何在Keil上编译S32系列的MCAL,需要的朋友可以翻一下我之前的文章,本文默认在Keil上已经可以编译调试S32的MCAL(只需要Port和Dio这俩基础模块)。2. AUTOSAR OS的安装可以从下面的连接下载NXP提供的AUTOSAR OS,如果要结合MCAL一起用的话,也要同时下载相同AUTO
2021-12-14 18:42:37
4843
3
原创 S32K1XX系列单片机 ——MCAL 的CAN模块配置
本文整理一下用EB配置S32K144单片机的CAN MCAL的时候遇到的问题及解决方案。1. Can Counter refCan Counter ref是定义CAN模块引用OS的哪个counter,当工程中没有OS的时候,可以置为空,并勾选:Can define loop as cycle即可解决该问题。2. Can Object ID (MB Handle)在配置CAN HardwareObject的时候,需要先配置HRH(Receive Object),再配置HTH(TransmitObj
2021-12-10 17:41:50
6810
7
原创 S32K1XX系列单片机 ——(2)用EB配置MCAL
1. 概述在下面的网址可以下载MCAL、OS和EBhttps://www.nxp.com/design/automotive-software-and-tools/autosar:AUTOSAR-HOMEEB和MCAL的安装我这里就不详细说了,网上有很多教程,本文着重说一下MCAL中Dio和Port模块的配置方法,以及如何在Keil工程中集成MCAL源代码和EB生成的配置代码。2. 新建EB工程新建时需要选择AUTOSAR版本:【注意:如果同时安装了多个版本的AUTOSAR,只有最高版本能被显示
2021-12-10 10:31:33
19686
14
原创 S32K1XX系列单片机 ——(1)开发环境搭建
本文介绍一下NXP S32系列单片机开发环境的搭建方法,分两种:S32DS和Keil。1. S32DSS32DS是NXP开发的一款IDE,编译器是GCC,支持Lauterbach、P&E和Jlink等调试器,集成了NXP芯片底层和一些中间层的SDK,还有AUTOSAR的MCAL可以免费试用。(1)安装软件下载链接如下:https://nxp.flexnetoperations.com/control/frse/download?agree=Accept&element=123670
2021-12-09 16:26:57
7531
9
原创 用Keil+CMSIS DAP调试NXP S32系列单片机时遇到的问题
(1)RDDI-DAP error我在Keil上用的是CMSIS-DAP调试器,SWD接口,最开始总是连不上,显示RDDI-DAP error,调了速率、Reset方式等都不好用,最终发现把连接调试器和单片机板子的杜邦线都掰开就好了。。杜邦线并在一起的时候容易互相干扰,产生通讯错误,分成一根一根的之后干扰会小很多。另外调试通讯速率要调低一点,10M有时就会有问题,1M/2M通常没问题。(2)调试引脚错误时连接Debugger的方法我在一次烧程序时,忘了把RESET引脚的用途设置成RESET,而是设
2021-12-09 16:23:09
8392
4
原创 AUTOSAR —— DCM模块简介
概述AUTOSAR的DCM模块是诊断通讯模块,只要遵循的协议就是ISO 14229-1,包括UDS会话层和应用层,对底层通讯协议没有要求,可以是CAN、Lin或以太网(DoIP)等。DCM模块里面主要有三个子模块:DSL、DSD和DSP:DSL-Diagnostic Session Layer诊断会话层主要有以下三个作用:处理诊断请求和响应数据流。管理诊断状态(会话状态和安全状态)。管理时间参数。DSD-Diagnostic Service Dispatcher诊断服务调度程序是 DS
2021-12-06 17:38:13
7572
原创 DoIP(五)—— UDSonIP
1. 概述当UDS被用于DoIP的时候,有一些针对以太网特有的规则,我们本文来介绍一下这些规则。UDSonIP的内容在ISO 14229-5中定义。2. UDS服务的特殊规定部分UDS服务在应用于DoIP的时候,由于以太网通信的特性,会有下文所述的一些特殊规则。(1)DiagnosticSessionControl (0x10) service诊断会话控制切换会导致TCP连接中断,在再次开始诊断前要重新建立TCP连接,并发送路由激活报文。(2)ECUReset (0x11) serviceEC
2021-12-01 17:28:40
10686
4
原创 DoIP(三)—— 通信流程
本文我们来梳理一下DoIP诊断通信的整个流程。1. 物理连接建立与车辆发现首先第一步是将外部诊断设备与车上的DoIP节点网络连接起来,有以下两种连接方法:(1)直接连接拓扑图如下图所示:(2)网络连接网络连接中,诊断设备和DoIP节点之间不再是直接连接,而是通过路由器进行连接不管是哪种连接方式,都要经历以下几个步骤:① 物理层连接与IP地址分配最先要做的是在诊断设备和DoIP节点间建立物理连接,即连接以太网线。之后采用DHCP协议进行IP地址分配。【目前车上的以太网节点还比较少,通常都
2021-12-01 10:54:09
15174
4
原创 DoIP(二)——报文类型
我们上一篇文章提到,DoIP报头中有两字节的数据类型(Payload Type),代表DoIP报文类型,本文就来详细介绍一下每一种报文类型。标准中对报文类型的定义如下:数据类型分为三部分,标绿的是节点管理报文,标黄的是状态信息获取报文,标蓝的是诊断报文。1. 节点管理报文节点管理报文的作用主要是获取DoIP节点的信息、建立连接、保持连接等。① 0x0000:Generic DoIP header negative acknowledge当DoIP节点收到的DoIP报文的报头不符合规则时,返回该
2021-11-30 17:28:57
32566
14
原创 DoIP(一)——基础概念
1. DoIP概述DoIP(Diagnostic communication over Internet Protocol)是基于车载以太网的诊断,在OSI 七层模型中属于传输层,其传输的诊断数据也是基于UDS,即DoIP是在以太网网络上传输UDS诊断数据的传输协议。DoIP带宽高,适合传输大量数据的场景,如车上的OTA软件升级。ISO 13400-1中给出的协议体系如下:2. DoIP报文格式DoIP报文也是基于TCP或UDP,但在其报文的Payload起始段添加了DoIP报头(首部),用来区分
2021-11-30 17:28:10
32507
4
原创 英飞凌 AURIX 系列单片机的HSM详解(5)——HSM硬件加速模块的使用
本系列的其它几篇文章:《英飞凌 AURIX 系列单片机的HSM详解(1)——何为HSM》《英飞凌 AURIX 系列单片机的HSM详解(2)——与HSM相关的UCB和寄存器》《英飞凌 AURIX 系列单片机的HSM详解(3)——开发方法》《英飞凌 AURIX 系列单片机的HSM详解(4)——Tricore核与HSM核之间的通信方法》1. 概述我们前文讲到过,HSM模块是专门用于实现加解密算法的,对于一些常见算法有硬件加速器,计算起来比软件要快。TC3XX系列MCU的HSM硬件加速模块包括:TRNG
2021-11-26 16:31:03
7463
2
原创 英飞凌 AURIX 系列单片机的HSM详解(4)——Tricore核与HSM核之间的通信方法
点击回顾之前的文章:《英飞凌 AURIX 系列单片机的HSM详解(1)——何为HSM》《英飞凌 AURIX 系列单片机的HSM详解(2)——与HSM相关的UCB和寄存器》英飞凌 AURIX 系列单片机的HSM详解(3)——开发方法因为HSM有单独的一个ARM核,实际使用过程中HSM核与主CPU Tricore核之间需要进行通信,本文就来介绍一下二者之间的通信方法。1. 中断HSM核可以向主核发送中断,支持两个中断,主Tricore核中断控制寄存器地址分别为:0xF0038870u 、0xF003
2021-11-26 14:16:23
11313
4
原创 英飞凌 AURIX 系列单片机的HSM详解(3)——开发方法
点击回顾之前的文章:《英飞凌 AURIX 系列单片机的HSM详解(1)——何为HSM》《英飞凌 AURIX 系列单片机的HSM详解(2)——与HSM相关的UCB和寄存器》本文以TC397为例,来介绍一下HSM的开发方法。1. 编译器HSM开发时分两个工程,一个工程是编译Tricore内核代码的,用到的编译器是Tasking for Tricore;另一个工程是编译HSM的ARM Cortex-M3内核的,用的是Tasking ARM for HSM。各个版本可以在下面Tasking的官网上找到
2021-11-24 17:15:46
11915
5
原创 英飞凌 AURIX 系列单片机的HSM详解(1)——何为HSM
1. 概述随着汽车上通信系统越来越复杂,云端远程通信的场景越来越多,信息安全变得越来越重要,在通信领域常用的AES、SHA、RSA等加密算法被越来越多地应用到汽车上。但通常这类加解密算法都需要大量的数学运算,需要消耗很多CPU时间和资源,汽车上的ECU又有比较高的实时性要求,为了节省主CPU的资源,HSM应运而生。HSM(Hardware Security Module),是MCU上专门用于实现加解密算法的一个外设,它一般会有一个独立的CPU,专门用来进行加解密运算,还有一些针对特定算法的硬件加速器(如
2021-11-23 15:47:52
37035
6
原创 英飞凌 AURIX 系列单片机的HSM详解(2)——与HSM相关的UCB和寄存器
1. UCBs1.1 UCB_HSMCFG1.1.1 地址1.1.2 定义1.1.3 读写规则由英飞凌出厂时填充内容。当Confirmation为unlocked时master(主核)可以写入数据,当Confirmation为unlocked时主核和HSM核都可以读取,当状态为confirmed或errored时,只有HSM核可读。1.1.4 涉及的寄存器DMU_HF_CONFIRM0状态被寄存器DMU_HF_CONFIRM0.PROINHSMCFG指示。1.2 UCB_HSMC
2021-11-22 17:37:58
12862
10
原创 关于RTOS中信号量、互斥量、邮箱、消息队列的一些理解
1. uCOSuCOS-II有邮箱和消息队列两个概念,都是Event的一种,对于邮箱来说,Event控制块中有一个指针直接指向数据地址,所以每次只能传递一个数据指针。而对消息队列来说,Event控制块中的指针指向一个消息队列,消息队列中的每一个节点包含一个数据地址,所以能同时传递多个数据地址。队列大小为1的消息队列与邮箱的作用是一样的。在uCOS-III中,取消了邮箱的概念,只有消息队列,在代码中,有OSCfg_MsgPool是一个消息池,每次2. rt-threadRTT中有邮箱和消息队列两个概念
2021-11-21 11:51:50
6899
原创 英飞凌 AURIX Development Studio工程移植到Hightec的方法
1. 软件简介AURIX™ Development Studio是英飞凌针对AURIX TC2XX/TC3XX系列单片机推出了一款免费的软件,集成了iLLD库,内置Tasking compiler和Tasking Debugger,但这两个模块只能用于非商业用途,可供学习和试用。iLLD库是英飞凌为TC2XX和TC3XX Tricore系列单片机提供的底层驱动库,有完善的使用手册,和较好的移植性。Hightec是一款可以用来开发Aurix系列单片机的编译器,有免费版,可商用,集成GCC编译器,可用UDE
2021-11-20 18:57:43
6074
5
原创 汽车UDS诊断详解及Vector相关工具链使用说明——5.5 CRC32算法
对于CRC32算法,汽车行业通常采用IEEE 802.3的规定,多项式为04C11DB7h,初始值为FFFFFFFFh,校验结果需和FFFFFFFFh按位进行异或计算。以下是我本次使用的CRC32算法代码,供大家参考:#include <stdio.h>#include <stdlib.h>typedef struct { unsigned long crc;} CRC32_CTX;static unsigned long crc32_tbl[256] = {
2021-11-17 18:42:59
1785
原创 汽车UDS诊断详解及Vector相关工具链使用说明——5.4 更新流程
基于UDS的BootLoader流程分为三步:预编程、主编程和后编程。我们分别来看一下这三个步骤。1.预编程预编程环节中主要有以下几步:① 进入扩展会话模式,以执行下面的操作。功能寻址发送给所有ECU。② 检查编程预条件:这一步主要是检查车辆是否静止、发动机是否停止、电池电压是否满足要求等,因为更新程序会使ECU正常功能失效,所以要确保安全后才能执行。③ 关闭DTC更新:该指令用功能寻址发送给所有ECU,因为当前ECU在更新过程中功能失效,可能会造成其他ECU记录故障码,所以暂时停掉所有ECU的
2021-11-17 18:42:02
1916
原创 汽车UDS诊断详解及Vector相关工具链使用说明——5.3 ECU启动流程
本文介绍一下有BootLoader的情况下,ECU是如何启动的1. ECU启动流程上面就是带BootLoader的ECU的上电启动流程以及诊断会话转换流程。这里涉及到了两个标志位,一个是外部更新请求标志位(其实这里就叫更新请求标志位就可以,之所以大家习惯加个外部,是因为原来老的更新机制里可能会在外部设置一个引脚来做更新请求标志位,用引脚电平的高低来判断是否需要更新,相当于硬件标志位,但现在大家都是用软件来实现这个标志位了),另一个是应用程序有效性标志位,在我的程序中是这样定义的:int huge
2021-11-17 18:32:52
1782
2
原创 汽车UDS诊断详解及Vector相关工具链使用说明——5.2 内存空间分配和Flash擦写操作
1. 内存分配将单片机整个Flash存储区域划分为三块,最低地址处用于存放BootLoader代码,上电自动执行本段代码。要注意的是某些型号的单片机上电默认从最高地址处开始执行代码,那么BootLoader代码存储区就应该放在最高地址处。BootLoader代码后的一小块区域用来存放数据和一些标志位,BootLoader代码和APP代码共用该部分空间。其余空间用于存放APP。英飞凌XC2300系列单片机有两块Flash,地址如下:因为单片机上电从0xC00000地址处开始执行代码,所以BootLoa
2021-11-17 18:11:53
1799
S32K144_MCAL_Keil_Demo1.zip
2021-12-10
S32K144_EB_Dio_Port_Demo1.zip
2021-12-10
树莓派boot文件,包含原生系统、uboot、rt-smart
2021-08-19
TC265_CAN_FD_例程
2020-10-19
英飞凌 Tricore TC26X(TC265/TC264等)单片机iLLD库
2020-10-19
英飞凌 TC264 单片机开发资料,包括iLLD库和使用例程
2020-10-19
3.2寸触摸屏驱动(屏幕驱动芯片ILI9341,触摸屏驱动芯片XPT2046)
2020-06-11
OV2640摄像头驱动程序
2020-06-11
飞秋-Windows下局域网内传输文件和文件夹的小工具
2020-06-08
Keil与Proteus联调驱动(C51&ARM)
2020-03-09
英飞凌XC2300系列Flash驱动代码
2019-11-05
Infineon_XC2300 系列Flash模拟EEPROM官方手册和代码
2019-11-05
ISO11898-1&2(2015 DIS版)
2019-11-05
ISO 15765-2(2015 DIS)&15765;-3(2004) 英文原版标准
2019-11-05
英飞凌XC2000系列单片机CAN_BSL实现例程源代码及使用手册(官方).rar
2019-09-06
使用OpenSSL实现RSA、AES、MD5算法-VS2017-C++.rar
2019-08-02
win10 VS2017 编译成功的openssl 32位和64位 动、静态链接库
2019-08-02
AES-128/192/256算法代码 C++ VS2017
2019-07-31
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人