- 博客(50)
- 收藏
- 关注
原创 Linux内核驱动——驱动基本概念
本文介绍了基于u-boot2016.03、kernel4.1.15和busybox的嵌入式系统开发要点。主要内容包括:1)驱动分类与编译方式(字符/块/网络设备驱动,静态/动态编译);2)u-boot编译流程(配置、交叉编译);3)内核编译与裁剪方法(通过menuconfig调整);4)根文件系统制作(使用busybox构建基础系统,添加库文件,配置启动脚本)。文章还对比了驱动静态编译(直接集成到内核)和动态编译(生成模块文件)的优缺点,并详细说明了系统启动流程中的关键配置文件和脚本。
2025-11-18 17:22:13
868
原创 Linux内核驱动——系统移植
摘要: Linux系统移植到IMX6ULL开发板需要完成U-Boot、内核镜像(zImage)和根文件系统(rootfs)的烧写。IMX6ULL支持USB、SD卡和EMMC三种启动方式,其启动流程包括BotROM初始化、DDR配置、U-Boot加载、内核引导和根文件系统挂载等步骤。驱动开发分为静态编译(直接编入内核)和动态编译(生成.ko模块)两种方式。系统移植关键点包括U-Boot功能(bootcmd/bootargs参数设置)、内核编译裁剪、根文件系统制作及自启动脚本配置等。开发板硬件资源包括512MB
2025-11-12 00:08:13
970
原创 嵌入式硬件——基于IMX6ULL的I2C实现
本文详细介绍了I.MX6ULL处理器的I2C总线开发技术,涵盖I2C基础概念、硬件特性、通信时序和寄存器操作。主要内容包括:I2C总线采用两根信号线(SDA/SCL)实现多设备半双工通信,具有主从架构特点;详细解析了起始/停止信号、数据传输、应答等时序单元;重点阐述了I2C控制器的寄存器配置和读写函数实现流程;并以LM75温度传感器为例,展示了完整的I2C驱动开发过程,包括温度数据读取和解析方法。文章还总结了关键注意事项,如时钟分频计算、应答判断等,为I.MX6ULL平台的I2C设备开发提供了实用指导。
2025-10-04 23:55:01
1682
1
原创 嵌入式硬件——基于IMX6ULL的UART(通用异步收发传输器)
本文详细介绍了I.MX6ULL处理器UART1串口通信的实现方法,包括硬件配置、寄存器初始化和收发功能实现。主要内容包括:1)UART1引脚复用配置与电气属性设置;2)关键寄存器(UCR1/UCR2/UFCR等)配置步骤;3)波特率计算与设置(115200bps);4)基于状态检测的字符/字符串收发函数实现;5)与PC串口调试助手通信的示例代码。重点强调了引脚复用正确性、波特率匹配和状态位检查等关键注意事项,为嵌入式系统串口通信开发提供了完整解决方案。
2025-10-04 17:29:28
1152
原创 嵌入式硬件——基于IMX6ULL的GPT(通用定时器)实现
本文介绍了基于i.MX6ULL芯片的GPT(通用定时器)模块实现高精度延时功能的方法。主要内容包括:GPT的核心特性(32位向上计数器、自由运行模式、1MHz计数频率的配置原理);初始化步骤(复位、时钟源选择、分频器设置);高精度延时函数实现(delayus和delayms),重点处理了计数器溢出的特殊情况;以及使用时的注意事项(系统时钟配置要求、溢出处理必要性)。通过GPT的精确计时功能,可实现微秒级和毫秒级的高精度延时,为裸机开发提供精准的时间控制。
2025-10-04 17:13:44
1199
1
原创 嵌入式硬件——I.MX6ULL EPIT(增强型周期中断定时器)
摘要:EPIT是I.MX6ULL的核心定时器外设,支持32位向下计数、多种时钟源选择和12位分频。其工作模式包括set-and-forget模式和free-running模式,通过比较中断实现精准定时控制。完整使用流程包括初始化配置(时钟源、分频值、工作模式等)、中断处理(检查标志、执行任务、清除中断)以及定时周期计算。代码实现涵盖初始化函数、中断服务函数和主函数调用。关键注意事项包括中断标志清除方式、工作模式选择和定时周期调整方法。EPIT广泛应用于LED控制、按键消抖和任务调度等场景。
2025-09-28 10:15:00
984
原创 嵌入式硬件——IMX6ULL时钟配置
文章摘要:本文详细介绍了嵌入式系统时钟初始化配置流程,包括六个关键步骤:1)系统初始化准备,关闭Cache/MMU等模块;2)配置ARM内核PLL实现528MHz主频,通过临时切换24MHz时钟源确保稳定性;3)设置PLL2/PLL3的8路PFD分频器提供352-720MHz外设时钟源;4)配置AHB(132MHz)、IPG(66MHz)、PERCLK(66MHz)三级时钟分频;5)外设时钟使能策略;6)软硬件验证方法。配置过程涉及CCM、ANALOG等多个寄存器组的精确操作,并附核心代码实现参考。
2025-09-28 00:02:21
7481
原创 嵌入式硬件——基于I.MX6ULL(MINI)的按键中断控制LED与蜂鸣器
本文介绍了基于i.MX6处理器的嵌入式系统中断处理与按键消抖实现方案。系统通过GPIO中断检测按键(KEY0)按下,结合EPIT定时器实现10ms硬件消抖,避免误触发。硬件配置包括GPIO1_IO18(按键)、GPIO1_IO03(LED)和GPIO5_IO01(蜂鸣器)的引脚映射与电气特性设置。软件流程涵盖:1)系统初始化(时钟、GIC中断控制器、异常向量表);2)按键GPIO配置为下降沿触发中断;3)EPIT定时器实现消抖逻辑;4)中断服务函数处理按键事件并控制外设。关键点包括GIC中断优先级配置、GP
2025-09-21 20:34:37
872
原创 嵌入式硬件——I.MX6U-Mini 蜂鸣器(BEEP)模块
本文介绍了开发板蜂鸣器控制的硬件原理与软件实现。硬件采用有源蜂鸣器,通过三极管电路隔离控制,由GPIO5_IO01引脚输出电平控制通断。软件部分包含内核驱动、GPIO驱动和蜂鸣器控制模块,实现了蜂鸣器初始化、开关、状态翻转等功能。主程序通过循环调用状态翻转和延时函数实现蜂鸣器周期性鸣响。关键配置包括引脚复用、电气属性设置和时钟使能等。系统上电后依次完成初始化,进入循环控制蜂鸣器工作状态。
2025-09-15 23:51:41
449
原创 嵌入式硬件——IMX6ULL 裸机LED点亮实验
本文详细介绍了基于IMX6ULL开发板实现LED周期性闪烁的完整流程。主要内容包括:1)开发环境搭建(FileZilla、交叉编译工具链、VSCode);2)硬件原理分析(GPIO控制逻辑);3)代码实现(汇编初始化、C语言LED控制);4)编译配置(Makefile编写);5)程序烧写(imxdownload工具使用);6)实验验证与常见问题排查。重点阐述了GPIO配置、交叉编译环境搭建以及SD卡烧写等关键步骤,为嵌入式开发初学者提供了从环境配置到功能实现的完整指导方案。
2025-09-15 18:00:00
2725
原创 ARM处理器与S3C2440芯片
核心作用(关闭前):实现虚拟地址到物理地址的映射、内存权限控制(如禁止用户模式访问内核内存)、内存保护(防止非法地址访问)- 逻辑运算:与、或、非、异或等位操作(如寄存器值按位清零、比较)全称:Memory Management Unit。- 算术运算:加减乘除等数值计算(如寄存器间加法、减法)S3C2440(三星ARM920T内核嵌入式SoC)共13个,编号范围为R0~R12。- 核心功能:执行两类基础操作。- 模块类型:内核计算核心。S3C2440采用ARM标准的。
2025-09-08 22:44:25
856
原创 嵌入式单片机---串口通信及相关通信技术
通常指“异步串口通信(UART)”,是串行通信的一种,通过1根发送线(TX)和1根接收线(RX)实现双向数据传输,靠“波特率同步”,广泛用于短距离设备交互(如单片机与电脑、传感器与控制器),属于异步串行全双工通信方式。
2025-09-05 21:51:07
1111
原创 51单片机:中断、定时器与PWM整合手册
51单片机定时器本质是“可编程计数器”,基于机器周期(1机器周期=12晶振周期)实现定时或计数功能,核心包含工作原理、控制寄存器及实战代码。中断系统是单片机实现实时处理的核心机制,用于响应内外紧急事件,核心包含定义、源、流程、嵌套、向量表及控制寄存器六大模块。,处理完高优先级中断后,返回继续执行低优先级中断,最终恢复原程序,本质是“优先级抢占”机制。中断的使能、类型(电平/边沿触发)需通过专用寄存器配置,核心寄存器包括。,相当于CPU的“中断导航目录”,用于快速定位服务程序。,支持两种工作模式,需通过。
2025-09-04 18:05:40
896
原创 单片机(89C51)---基础知识
外设寄存器是硬件外设(如GPIO、UART、TIMER)与软件的交互接口,本质是一块具有固定地址的高速存储单元,用于存储“控制指令”或“硬件状态数据”,相当于硬件的“控制开关面板”。寄存器(外设):是指能够操作硬件的,具有固定地址的内存空间GPIO是单片机/MCU上的通用引脚接口,可通过软件灵活配置工作模式,是嵌入式开发中最基础、最常用的外设接口。
2025-09-03 17:54:10
581
原创 Linux网络编程——数据存储与SQLite数据库
本文介绍了SQLite数据库的核心特性与基本操作。SQLite是一种轻量级关系型数据库,具有开源免费、跨平台、容量大(最大2T)等特点。文章详细说明了SQLite3的安装方法(Linux环境)和常用命令,包括创建表、增删改查等基本SQL语法。同时介绍了SQLite3的C/C++ API接口,如sqlite3_open打开数据库、sqlite3_exec执行SQL语句以及查询结果回调函数的使用方法。还对比了数据存储结构(内存/硬盘)和数据库分类(关系型/非关系型)的特点。最后提供了SQLite可视化工具的安装
2025-08-29 17:55:57
1091
原创 Linux网络编程——IO多路复用---EPOLL
摘要:本文对比了select、poll和epoll三种I/O多路复用机制的核心特点,重点分析了epoll的实现原理和使用方法。在性能对比方面,epoll采用红黑树存储文件描述符,支持无上限监测且无需反复拷贝数据,同时提供高效的边沿触发模式;而select/poll存在1024个fd限制且需遍历返回集合。文章详细介绍了epoll的三个核心函数(epoll_create、epoll_ctl、epoll_wait)及其数据结构,并通过终端/管道和网络套接字的实际代码示例,展示了epoll在事件驱动编程中的典型应用
2025-08-28 17:07:43
503
原创 Linux网络编程——服务器类型与TCP并发服务器构建(SELECT)
本文介绍了TCP并发服务器的四种实现方案:1)多进程模型通过fork()创建子进程处理请求,资源开销大但安全性高;2)多线程模型采用pthread_create创建线程,开销低于进程;3)线程池模型预先创建线程处理任务队列,避免频繁线程创建销毁;4)IO多路复用通过select/poll/epoll监控多个文件描述符,单进程即可处理多客户端。重点解析了select实现流程:定义fd集合、添加关注fd、内核监控事件、处理触发事件,并提供了详细代码示例,比较了各方案的资源开销和并发能力差异。
2025-08-27 19:49:56
1126
原创 Linux网络编程——TCP与HTTP协议以及爬虫
本文摘要: 文章系统介绍了TCP和HTTP协议的核心内容。TCP部分详细解析了头部标志位功能(SYN、ACK等)和可靠传输机制(三次握手、滑动窗口等);HTTP部分阐述了万维网通信要素、报文格式及状态码分类。最后简述了网络爬虫"请求-解析-存储"的工作流程,并附有创建TCP连接、发送HTTP请求的代码示例。全文从协议原理到实际应用,完整呈现了网络通信的关键技术体系。
2025-08-25 19:15:23
3331
原创 Linux网络编程——TCP网络协议
本文摘要: 本文对比了UDP和TCP协议的核心特性:UDP无连接、高效但不可靠,通过降速或应答机制避免丢包;TCP需建立连接、可靠但开销大,采用三次握手建立连接和四次挥手断开连接。重点分析了TCP粘包问题及解决方法(调整速率、固定大小、分隔符、自定义数据帧)。介绍了Wireshark抓包工具的使用步骤,并提供了TCP客户端和服务端的编程示例代码,包含关键函数connect/send/listen/accept/recv的说明。重难点包括协议差异、连接机制和网络编程流程。
2025-08-24 15:36:07
848
2
原创 Linux 网络编程——网络编程基础
本文主要介绍了网络通信的基本概念和UDP协议编程实现。首先阐述了网络通信的目的和基本要素,包括IP地址、MAC地址和端口号的作用。接着详细讲解了OSI七层模型和TCP/IP四层/五层模型,重点分析了各层的功能和协议。然后详细介绍了IP协议,包括IPv4地址分类、子网掩码、网段号等概念。在UDP编程部分,讲解了套接字创建、数据发送接收等核心函数,并提供了C语言实现的UDP客户端和服务端示例代码,展示了网络字节序转换、地址绑定等关键技术点。全文系统性地介绍了从网络基础到实际编程的全过程。
2025-08-22 19:19:59
1111
原创 Linux应用编程——进程间通信 信号与共享内存
摘要:本文介绍了进程间通信的信号机制和共享内存方法。信号通过软中断实现异步通信,系统提供多种预设信号(如SIGINT、SIGKILL等)和自定义信号。信号处理方式包括默认处理、忽略和捕获,使用signal()函数注册信号。文中还详细说明了共享内存的原理和操作流程,包括创建IPC key、建立内存映射、数据读写等步骤。最后给出了两个代码示例:一个演示父子进程通过信号交互,另一个展示通过共享内存实现进程间的数据共享和打印功能。
2025-08-19 19:06:09
501
原创 Linux应用编程——线程间同步机制与进程间通信
本文摘要介绍了代码设计和进程/线程管理的核心概念。代码设计强调低耦合、高内聚原则;线程同步重点讲解了信号量机制及其操作步骤,并分析了死锁的四个必要条件与解决方法。进程间通信部分对比了管道(无名/有名)、信号、共享内存等传统IPC方式与网络Socket通信的特性及实现方法。文中还提供了常用系统函数如memset的说明,涵盖了从代码结构到并发控制的软件开发关键技术点。
2025-08-18 19:16:48
1010
原创 Linux应用编程——线程
本文摘要: 线程是轻量级进程,作为操作系统任务调度的最小单位,与进程共享堆区、数据区等资源。线程创建需分配8M栈区空间,调度呈现"宏观并行,微观串行"特点。相比进程,线程资源开销小但安全性较低。编程实现包括创建(pthread_create)、退出(pthread_exit)和回收(pthread_join)操作,支持分离/非分离属性设置。线程间通信通过共享全局变量实现,互斥访问采用互斥锁机制(pthread_mutex系列函数)解决资源竞争问题。文中提供了线程创建、互斥锁使用等典型代码
2025-08-17 16:11:41
887
原创 Linux应用编程——子进程资源回收与线程相关概念
本文总结了进程与线程的核心知识点。在进程管理方面,介绍了wait/waitpid函数回收子进程资源的策略,以及exec函数族执行新程序的方法。在线程方面,阐述了线程作为轻量级进程的特点,包括创建(pthread_create)、调度、消亡(pthread_exit)等机制,并对比了进程与线程在资源消耗、通信方式、安全性等方面的区别。文章还提供了线程编程的代码示例,展示了线程创建、ID获取(pthread_self)和资源回收(pthread_join)的基本用法。这些知识为理解操作系统多任务处理机制提供了基
2025-08-15 18:29:31
608
原创 Linux应用编程——多任务(进程 并发)基础
本文摘要:进程是运行中的程序,占用内存和CPU资源。程序是静态文件,进程是其动态执行实例。进程创建时分配0-4G虚拟内存空间,包含栈、堆、数据段等区域。进程调度采用时间片轮转等算法,具有就绪、运行和阻塞三态。Linux进程状态还包括暂停态、僵尸态等。进程通过return或exit()终止,需避免僵尸进程产生。常用命令如ps、top、kill等用于进程管理。编程中通过fork()创建子进程,父子进程内存空间独立。进程回收使用wait()/waitpid(),孤儿进程由系统进程接管。
2025-08-14 17:52:53
477
原创 Linux应用编程——文件IO
文件IO是Linux内核为应用层提供的文件操作接口,属于系统调用,仅适用于Linux系统,移植性较弱,且无缓冲区,主要用于硬件操作,也可操作普通文件。
2025-08-12 19:16:41
978
原创 Linux应用编程——标准IO与文件操作相关
文章摘要:本文系统介绍了C语言标准I/O库函数的使用方法。主要内容包括:1)标准I/O与系统调用的区别;2)字符/行操作函数(fgets、gets等)的特性与安全风险;3)默认文件流(stdin/stdout/stderr)说明;4)数据块读写函数(fread/fwrite)的参数和返回值;5)流定位接口(fseek/ftell/rewind)的功能和用法;6)字符串截取函数strtok的实现原理。通过具体代码示例,详细展示了文件读写、定位和字符串处理等常见操作的实际应用场景。
2025-08-12 18:59:29
441
原创 Linux应用编程——文件操作与标准IO操作
本文系统介绍了Linux操作系统核心编程模块,重点解析了文件操作相关内容。首先阐述了Linux"一切皆文件"的理念和7种文件类型,详细说明了文件权限表示方法。文章重点讲解了文件操作的标准流程和两种操作方法:标准IO(C库函数)和文件IO(系统调用),并提供了fopen、fgets/fputs等常用函数的原型和使用说明。此外还介绍了主函数传参机制,并通过多个示例代码(如文件打开、读写、拷贝等)直观展示了文件操作的具体实现。这些内容为Linux系统编程中的文件处理提供了实用指导。
2025-08-10 16:28:24
497
原创 数据结构——二叉树、GDB调试工具
本文摘要:文章系统介绍了树和二叉树的基本概念,包括定义、术语(度、叶结点、深度等)以及特殊类型(斜树、满/完全二叉树)。重点讲解了二叉树的遍历方式(前序、中序、后序)及其C语言实现,并提供了GDB调试工具的使用方法(断点设置、执行控制等)。此外,对比分析了常见排序算法的时间复杂度、空间复杂度及稳定性,最后通过二叉树创建的代码示例演示了数据结构和调试技术的实际应用。
2025-08-08 19:35:22
1108
原创 数据结构——哈希表(散列表)
哈希表通过哈希函数实现数据的快速查找,时间复杂度可达O(1)。其核心原理是建立关键字与存储位置的映射关系,常见哈希函数包括取余法和线性函数法。当发生哈希冲突时,可采用开放地址法或链地址法解决。代码示例展示了基于链地址法的哈希表实现,包括插入、查找、遍历和销毁操作,其中通过首字母哈希函数将数据分配到26个字母槽位。相比遍历O(n)和二分查找O(logn),哈希表在理想情况下能实现接近常数的查找效率。
2025-08-07 19:15:40
254
原创 数据结构——栈结构与队列结构
本文摘要:介绍了指针、内核链表、内存分区等核心概念。重点讲解了二级指针的三种应用场景、内核链表的实现原理(offset_of和container_of宏)、程序内存分区(文本区、数据区、堆栈区)。详细分析了栈(FILO)和队列(FIFO)的存储结构、分类及实现方式,包括顺序栈/队列和链式栈/队列的操作方法。提供了循环队列和链式队列的完整C语言实现代码,涵盖创建、入队、出队、遍历、销毁等核心功能。最后补充了"出参"的概念,即通过指针参数返回函数结果的技术实现。
2025-08-07 18:51:04
557
原创 数据结构 ----- Makefile文件与双向链表
摘要: 本文介绍了make工具和Makefile的基本概念及使用方法。make是一款自动化构建工具,通过读取Makefile定义的规则,基于时间戳机制只重新编译修改过的文件。Makefile包含目标文件、依赖文件和编译命令,支持变量定义和自动变量(如$@、$^)。文章提供了GCC编译四步骤(预处理、编译、汇编、链接)和完整的Makefile示例,包含变量定义、模式规则和清理功能。此外,还展示了双向链表的基础操作代码实现,包括创建链表、插入/删除节点、查找修改等核心功能,通过doulink.h头文件和doul
2025-08-05 20:49:34
384
原创 数据结构——内存探测、网络配置以及链表操作
本文摘要包含三部分内容:1. Valgrind内存检测工具介绍,包括内存泄漏检测方法和基本使用命令;2. 虚拟机网络配置详细步骤,涵盖桥接模式设置、虚拟网络编辑器和网络服务重启;3. 链表操作算法实现,包含快慢指针查找中间节点、链表逆序、判断环形链表和约瑟夫环问题解决方案。全文提供了具体命令、代码示例和操作流程,适用于程序调试、虚拟机网络配置和数据结构实现等场景。
2025-08-04 21:18:58
257
原创 数据结构——数据结构基础
本文摘要: 数据结构与程序设计核心内容总结,重点介绍了单向链表的实现原理。主要内容包括:1)数据结构基础概念,区分逻辑结构(线性/树形/图形)和物理结构(顺序/链式/索引/散列);2)单向链表的具体实现,包含结点结构定义、链表对象创建及核心操作(插入、删除、查找、修改、销毁);3)完整C语言代码示例,展示了链表创建、头插尾插、头删尾删、遍历查找等功能的实现方法。文章通过详实的代码演示了单向链表的完整操作流程,为理解链式数据结构提供了实践参考。
2025-08-03 17:37:02
433
原创 C语言——结构体、共用体与位运算
本文系统总结了C语言中结构体、共用体、枚举、类型别名和位运算的核心特性。结构体用于封装不同数据类型,支持嵌套和内存对齐;共用体实现内存共享,节省空间;枚举定义命名常量集合;typedef简化复杂类型声明。位运算部分详细解析了与、或、异或、取反、移位等运算符的原理及应用场景,如标志位管理等。这些特性是C语言高效编程的关键,掌握它们能提升代码质量和运行效率。
2025-07-31 20:19:01
786
原创 C语言——字符串操作与函数指针
本文系统介绍了C语言字符串操作与内存管理的核心技术:1.字符串查找与统计方法,包括子串定位和重叠/非重叠计数;2.strcpy/strcat自操作时的特殊处理及优化方案;3.动态内存管理函数(malloc/calloc/realloc/free)的正确使用;4.函数指针与回调函数的应用,特别是qsort的实现机制;5.二级指针在字符串数组处理中的运用。重点强调了内存泄漏预防、野指针处理和类型安全等常见问题解决方案,为构建健壮的C程序提供技术基础。(150字)
2025-07-31 00:01:39
906
原创 C语言——指针字符串操作和数组处理以及指针函数
本文摘要:文章系统讲解了C语言指针与字符串操作的核心知识点,包括const修饰指针的用法(指向常量和指针常量)、万能指针(void*)的特性及使用限制。详细介绍了字符串操作函数(复制、拼接、比较)和内存操作函数(memcpy)的实现原理,并给出二维数组处理(求和、反转)的代码示例。同时阐述了数组指针的定义与特性,以及二维数组作为函数参数的传递方式,最后讲解了返回指针值的函数(指针函数)的定义与注意事项。文章通过大量代码示例演示了各种指针操作的实际应用。
2025-07-29 19:06:14
300
原创 C语言——空指针、排序与迭代思想
摘要:本文介绍了指针操作和常见排序算法的实现。包括空指针的使用注意事项、快速排序原理(递归分治)、数组逆序(迭代器方式)、选择排序(指针实现)、二分查找(递归实现)以及快速排序的具体实现代码。所有算法都通过指针操作数组元素,展示了指针在数组处理中的灵活运用,体现了递归与迭代的核心思想。每种算法都配有完整的C语言实现代码和测试用例。
2025-07-28 20:28:06
230
原创 C语言——预处理命令与指针
本文摘要:文章系统介绍了C语言核心概念,包括预处理命令(宏定义、文件包含、条件编译)、编译流程(预处理-编译-链接)和指针基础。重点讲解了指针的定义与使用、指针运算、指针与数组的关系,并通过实际案例演示了指针在求极值、交换变量和计算公约数/公倍数中的应用。同时指出了指针使用中的常见错误(野指针、类型匹配、越界访问)及注意事项。全文以理论结合实践的方式,帮助读者掌握C语言预处理和指针的核心技术要点。
2025-07-26 18:15:40
221
原创 C语言——函数基础与函数传参
文章摘要:本文介绍了C语言中二维数组作为函数参数的传递方式,强调必须指定列数。详细解析了标识符的作用域(局部/全局)和可见性规则,以及变量的生存期(静态/动态)。重点说明了static、extern等关键字的作用,并提供了Vim操作和编译指令示例。最后指出头文件应仅包含声明,区分了内部与外部函数。这些概念对理解C语言程序结构至关重要。
2025-07-25 19:51:16
358
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅