700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 【嵌入式开发】LED 驱动 ( LED发光二极管原理 | 底板原理图分析 | 核心板原理

【嵌入式开发】LED 驱动 ( LED发光二极管原理 | 底板原理图分析 | 核心板原理

时间:2024-06-27 04:12:49

相关推荐

【嵌入式开发】LED 驱动 ( LED发光二极管原理 | 底板原理图分析 | 核心板原理

文章目录

开发板 的 LED 灯 作用 :嵌入式软件的开发初期, 如 开发 BootLoader 代码 或者 Kernel 内核代码 过程中, 有效的调试方法有限, 此时通常使用 开发板上的 LED 灯 作为程序调试的手段; 另外除 LED 灯 之外 并不是没有调试手段, JLink 调试器可以进行本阶段的调试 ;

之后的博客中开始接触 外围 硬件的操作,外围硬件包括 串口, Flash, SD卡, 网卡等; LED 是最简单的一种 外围硬件;

外围硬件驱动程序设计流程 :① 分析原理图 ② 阅读分析 芯片手册, ③ 驱动设计, ④ 代码编写 ;

本博客的参考文章及相关资料下载 :

1.本博客代码及参考手册下载 :/download/han120/10573310

#一. LED 简介

##1. LED 原理图

###(1) LED 底板 原理图

LED 底板原理图分析 :

1.LED 发光原理 :LED 是发光二极管, 二极管两端的电压差到达一个阈值, 就会处于导通状态, 此时就是发光状态;2.OK6410 LED 底板图分析 :以 第一个 LED1 为例, 右侧时高电平, 左侧是低电平, 当电压差到达一定程度 LED 就会处于导通状态, 低电平端引脚是 NLED1 ;

###(2) LED 核心板 原理图

LED 核心板原理图 :

1.OK6410 核心板原理图分析 :下图是 核心板 原理图的部分截图, 可以看到NLED1接在 CPU GPIO 的GPM0引脚上, 因此可以通过操作 GPIO 的 GPM0 引脚 来进行设置 NLED1 引脚的低电平操作;

##2. GPIO

###( 1 ) GPIO 简介

GPIO 简介 :英文全称General-Purpose Input / Output Ports, 中文翻译为 : 通用输入输出端口;

1.GPIO 作用 :很多结构简单的外部设备 或者 电路 只要求两种状态 : 开 或 关, GPIO 端口 只用于传输 开关 信号, CPU 通过 GPIO 端口来操作这些简单的设备;2.串口 和 USB 作用 :用于传输复杂数据, 因此简单的 开关 使用 GPIO 比较 合适;3.LED 灯场景 :此处通过操作 GPIO 的 GPM0 引脚, 来给 LED 灯一段加低电平, 只需要 加 或者 不加 两种操作;4.GPIO 使用 :每个 GPIO 端口都至少需要两个寄存器来使用,① 控制寄存器选择端口的 输入/输出 操作,② 数据寄存器用于存放数据;

###( 2 ) GPIO 文档

参考手册 :ARM芯片 手册 S3C6410X.pdf ( 基于 6410 开发板 ARM 11 )

1.手册对应章节 :10 章节 10-GPIO;2.S3C6410X.pdf手册下载地址 :/download/han120/10573310

GPIO 文档 :

1.GPIO 引脚说明 :S3C6410 有 187 个输入输出引脚, 分属于 17 个端口; 其中的 LED1 就是属于 GPM0;2.GPM 控制寄存器 :GPM 控制寄存器分为 4 位, 其中 LED1 连接的引脚为 GPM0,GPM0 引脚 对应的控制寄存器的 [3 : 0] 位, 设置 0b0000 即 设置为输入数据, 设置 0b0001 即设置为输出数据;

3.GPM 数据寄存器 :GPM 数据寄存器 有 6 位 [5 : 0], 设置 第 0 位 数据, 当端口被设置为 输入/输出 功能, 其设置的 0 或 1 数据就是引脚的状态 ;

###( 3 ) 点亮 LED 灯

点亮 LED 灯 :

1.地板原理图分析 :四个 LED 灯的低电平, 分别由 NLED1, NLED2, NLED3, NLED4 四个引脚控制;

2.核心板原理图 :NLED1, NLED2, NLED3, NLED4 四个引脚分别接在了 GPIO 端口的 GPM0, GPM1, GPM2, GPM3 四个引脚上;

3.设置 GPIO 控制寄存器 :设置 GPM0, GPM1, GPM2, GPM3 对应的 控制寄存器 ;

4.设置 GPIO 数据寄存器 :设置 GPM0, GPM1, GPM2, GPM3 对应的 数据寄存器 ; 其中设置 0 为 低电平, 设置 1 为 高电平, 使 LED 灯亮起来, 该引脚需要设置 低电平 达到 发光二极管的电压差阈值, LED 才能亮起来;

##3. 外设基地址初始化

###( 1 ) C15 寄存器 简介

C15 寄存器 :英文全称Peripheral Port Memory Remap Register,外设端口内存映射寄存器;

1.外设端口内存映射寄存器 作用 :为 非共享 的设备 重新进行内存映射, 覆盖页表中的内存映射关系, 可以通过一个地址强制访问外设端口;2.无使用前提 :不管 MMU 是否启用, 都不影响 外设端口地址内存 的重新映射;3.权限说明 :外设端口内存映射寄存器 拥有最高级别的权限, 高于 Primery 和 Normal 级别的内存映射寄存器;

###( 2 )外设端口内存映射寄存器 属性

外设端口内存映射寄存器 属性 :

1.寄存器编号 :该寄存器是 CP15 协处理器中的 C15 寄存器;2.寄存器属性 :该寄存器是一个 32 位 的可读写寄存器;3.访问权限 :只有在特权模式下才可以访问 ;

#二. LED 控制代码编写

##1. 汇编代码编写

###(1) 控制 LED 开关

LED 控制 汇编代码编写 :基于 OK6410 开发板; 1 ~ 3 步骤为 数据准备, 4 ~ 6 步骤为 设置 GPIO 的 GPM 控制寄存器值, 将引脚设置为输出功能, 7 ~ 9 步骤 为 设置 GPIO 的 GPM 数据寄存器值 ;

1.定义 GPM 控制寄存器地址常量 :GPM 控制寄存器的地址是 0x7F008820,#define GPBCON 0x7F008820, 下图是S3C6410X.pdf 文档中 10-GPIO Page 338介绍;

2.定义 GPM 数据寄存器地址常量 :GPM 控制寄存器的地址是 0x7F008824,#define GPBDAT 0x7F008824, 上图是S3C6410X.pdf 文档中 10-GPIO Page 338介绍;3.定义 LED 操作标号 :light_led :, 可以在其它位置通过 跳转到 该标号处执行 LED 灯打开的操作;4.装载控制寄存器地址 :首先将 GPM 控制寄存器地址装载到 r0 中, 以方便之后访问这个地址,ldr r0, =GPBCON, 其中 将 0x7F008820 地址装载到了 r0 寄存器中,GPBCON是之前定义的 GPM 控制器地址 的常量 ;5.计算 GPM 控制寄存器值 :下图是 GPM 控制寄存器的值, 4个 LED 灯分别由 GPM0, GPM1, GPM2, GPM3 控制, 因此需要**将 GPM0, GPM1, GPM2, GPM3 对应的控制器设置成输出模式**, 每一位设置占 4 位, 即设置成 0x1 即可, 前 0 ~ 15 位 设置成 0x1111, GPM4 和 GPM5 的内容不需要, 因此设置成0 即可, 最后该寄存器的值设置成 0x1111 即可; 代码为ldr r1, =0x1111;

6.将 值 正式存储到 GPM 控制寄存器中 :使用 str 指令, 将 r1 中的值 存储到 GPM 控制寄存器中, 代码为str r1, [r0], 解读 : 将 r1 中的值 存储到 r0 指向的地址的内存中 ;

此时还未完成, 如果烧写该程序, 会出现无法点亮 LED 灯的情况, OK6410 开发板还需要进行外设基地址初始化步骤;

###(2) 外设端口基地址初始化

参考手册 :ARM核 手册 Arm1176jzfs.pdf ( 基于 OK6410 开发板 ARM 11 )

1.手册对应章节 :***3 章节 ***;2.S3C6410X.pdf手册下载地址 :

外设端口基地址初始化 步骤 :

1.C15 寄存器 ( 外设端口内存映射寄存器 ) 简介 :控制外设基地址的寄存器的是 C15 寄存器;

2.设置汇编模块标号 :设置一个标号, 方便汇编语句跳转, 代码set_serial_port :;3.将基地址装载到 r0 寄存器中 :查找 OK6410 开发板的 外设基地址, 在S3C6410X.pdf文档中查询到, 基地址值为0x70000000; 使用ldr r0, =0x70000000语句将基地址值 0x70000000 立即数值 装载到 r0 寄存器中;① 语法解析 :区分ldr r0, =0x70000000ldr r0, 0x70000000语句, 前者是将 立即数 0x7000000 装载到 r0 寄存器中, 后者是将 数字 0x70000000 的地址 装载到 r0 寄存器中;

4.设置外设端口内存映射寄存器 值 :下图的表就是该寄存器设置位说明, 我们要初始化 256M 内存, [4:0] 位 设置成 0b10011, 即 0x13, 整个寄存器的值应该是 0x70000000 与 0x13 进行与操作, 代码为orr r0, r0, #0x13;

5.将 r0 寄存器中的值传递给 C15 协处理器 :根据下图 c15 协处理器 的 CRn Op1 CRm Op2 , 使用 mcr 指令, 将 r0 值 传给 c15 寄存器; 语句为mcr p15, 0, r0, c15, c2, 4;① 语法说明 :MCR p,o,Rd,CRN,CRM,q将 rd 寄存器值 传递给 CRN 协处理器,6.跳转回原来的位置 :mov pc, lr, 该标号处代码执行完毕, 跳转回调用处继续执行下面的内容;7.整体代码 :

set_serial_port : ldr r0, =0x70000000@ 将基地址装载到 r0 寄存器中, 该基地址 在 arm 核 手册中定义orr r0, r0, #0x13@ 设置初始化基地址的范围, 将 r0 中的值 与 0x13 立即数 进行或操作, 将结果存放到 r0 中mcr p15, 0, r0, c15, c2, 4@ 将 r0 中的值设置给 c15 协处理器 mov pc, lr

###(3) 完整汇编代码

完整汇编代码 :详细注释版本 ;

@**************************** @File:start.S @ @BootLoader 初始化代码 @**************************** .text@ 宏 指明代码段 .global _start@ 伪指令声明全局开始符号 _start: @ 程序入口标志 b reset @ reset 复位异常 ldr pc, _undefined_instruction @ 未定义异常, 将 _undefined_instruction 值装载到 pc 指针中 ldr pc, _software_interrupt@ 软中断异常 ldr pc, _prefetch_abort @ 预取指令异常 ldr pc, _data_abort @ 数据读取异常 ldr pc, _not_used@ 占用 0x00000014 地址 ldr pc, _irq@ 普通中断异常 ldr pc, _fiq@ 软中断异常 _undefined_instruction: .word undefined_instruction @ _undefined_instruction 标号存放了一个值, 该值是 32 位地址 undefined_instruction, undefined_instruction 是一个地址 _software_interrupt: .word software_interrupt @ 软中断异常 _prefetch_abort: .word prefetch_abort @ 预取指令异常 处理 _data_abort: .word data_abort@ 数据读取异常 _not_used:.word not_used @ 空位处理 _irq: .word irq @ 普通中断处理 _fiq: .word fiq @ 快速中断处理 undefined_instruction:@ undefined_instruction 地址存放要执行的内容 nop software_interrupt: @ software_interrupt 地址存放要执行的内容 nop prefetch_abort: @ prefetch_abort 地址存放要执行的内容 nop data_abort: @ data_abort 地址存放要执行的内容 nop not_used: @ not_used 地址存放要执行的内容 nop irq: @ irq 地址存放要执行的内容 nop fiq: @ fiq 地址存放要执行的内容 nop reset:@ reset 地址存放要执行的内容 bl set_svc @ 跳转到 set_svc 标号处执行bl set_serial_port@ 设置外设基地址端口初始化bl disable_watchdog@ 跳转到 disable_watchdog 标号执行, 关闭看门狗bl disable_interrupt@ 跳转到 disable_interrupt 标号执行, 关闭中断bl disable_mmu@ 跳转到 disable_mmu 标号执行, 关闭 MMU bl light_led@ 打开开发板上的 LED 发光二极管set_svc:mrs r0, cpsr @ 将 CPSR 寄存器中的值 导出到 R0 寄存器中bic r0, r0, #0x1f @ 将 R0 寄存器中的值 与 #0x1f 立即数 进行与操作, 并将结果保存到 R0 寄存器中, 实际是将寄存器的 0 ~ 4 位 置 0orr r0, r0, #0xd3 @ 将 R0 寄存器中的值 与 #0xd3 立即数 进行或操作, 并将结果保存到 R0 寄存器中, 实际是设置 0 ~ 4 位 寄存器值 的处理器工作模式代码msr cpsr, r0 @ 将 R0 寄存器中的值 保存到 CPSR 寄存器中mov pc, lr@ 返回到 返回点处 继续执行后面的代码#define pWTCON 0x7e004000 @ 定义看门狗控制寄存器 地址 ( 6410开发板 )disable_watchdog: ldr r0, =pWTCON @ 先将控制寄存器地址保存到通用寄存器中mov r1, #0x0 @ 准备一个 0 值, 看门狗控制寄存器都设置为0 , 即看门狗也关闭了str r1, [r0] @ 将 0 值 设置到 看门狗控制寄存器中 mov pc, lr@ 返回到 返回点处 继续执行后面的代码disable_interrupt:mvn r1,#0x0@ 将 0x0 按位取反, 获取 全 1 的数据, 设置到 R1 寄存器中ldr r0,=0x71200014@ 设置第一个中断屏蔽寄存器, 先将 寄存器 地址装载到 通用寄存器 R0 中 str r1,[r0]@ 再将 全 1 的值设置到 寄存器中, 该寄存器的内存地址已经装载到了 R0 通用寄存器中ldr r0,=0x71300014@ 设置第二个中断屏蔽寄存器, 先将 寄存器 地址装载到 通用寄存器 R0 中 str r1,[r0]@ 再将 全 1 的值设置到 寄存器中, 该寄存器的内存地址已经装载到了 R0 通用寄存器中mov pc, lr@ 返回到 返回点处 继续执行后面的代码disable_mmu : mcr p15,0,r0,c7,c7,0@ 设置 I-Cache 和 D-Cache 失效mrc p15,0,r0,c1,c0,0@ 将 c1 寄存器中的值 读取到 R0 通用寄存器中bic r0, r0, #0x00000007@ 使用 bic 位清除指令, 将 R0 寄存器中的 第 0, 1, 2 三位 设置成0, 代表 关闭 MMU 和 D-Cachemcr p15,0,r0,c1,c0,0@ 将 R0 寄存器中的值写回到 C1 寄存器中mov pc, lr@ 返回到 返回点处 继续执行后面的代码set_serial_port : ldr r0, =0x70000000@ 将基地址装载到 r0 寄存器中, 该基地址 在 arm 核 手册中定义orr r0, r0, #0x13@ 设置初始化基地址的范围, 将 r0 中的值 与 0x13 立即数 进行或操作, 将结果存放到 r0 中mcr p15, 0, r0, c15, c2, 4@ 将 r0 中的值设置给 c15 协处理器 mov pc, lr#define GPBCON 0x7F008820#define GPBDAT 0x7F008824light_led : ldr r0, =GPBCON @ 将 0x7F008820 GPM 控制寄存器的地址 0x7F008820 装载到 r0 寄存器中ldr r1, =0x1111 @ 设置 GPM 控制寄存器的行为 为 Output 输出, 即每个对应引脚的设置为 0b0001 值str r1, [r0]@ 将 r1 中的值 存储到 r0 指向的 GPBCON 0x7F008820 地址的内存中ldr r0, =GPBDAT@ 将 GPBDAT 0x7F008824 地址值 装载到 r0 寄存器中ldr r1, =0b110000@ 计算 GPM 数据寄存器中的值, 设置 0 为 低电平, 设置 1 为高电平, 这里设置 0 ~ 3 位为低电平, 其它为高电平str r1, [r0]@ 将 r1 中的值 存储到 r0 指向的 GPBDAT 0x7F008824 地址的内存中mov pc, lr

##2. 链接器脚本

gboot.lds 链接器脚本 代码解析 :

1.指明输出格式 ( 处理器架构 ) :使用OUTPUT_ARCH(架构名称)指明***输出格式, 即处理器的架构***, 这里是 arm 架构的,OUTPUT_ARCH(arm);2.指明输出程序的入口 :设置编译输出的程序入口位置, 语法为ENTRY(入口位置), 在上面的 Start.S 中设置的程序入口是_start, 代码为ENTRY(_start);3.设置代码段 :使用.text :设置代码段;4.设置数据段 :使用.data :设置数据段;5.设置 BSS 段 :使用.bss :设置 BSS 段;( 1 ) 记录 BSS 段的起始地址 :bss_start = .;;( 2 ) 记录 BSS 段的结束地址 :bss_end = .;;6.对齐 :每个段都需要设置内存的对齐格式, 使用. = ALIGN(4);设置四字节对齐即可;7.代码示例 :

OUTPUT_ARCH(arm) /*指明处理器结构*/ ENTRY(_start) /*指明程序入口 在 _start 标号处*/ SECTIONS {. = 0x50008000;/*整个程序链接的起始位置, 根据开发板确定, 不同开发板地址不一致*/ . = ALIGN(4); /*对齐处理, 每段开始之前进行 4 字节对齐*/ .text : /*代码段*/ { start.o (.text)/*start.S 转化来的代码段*/ *(.text) /*其它代码段*/ } . = ALIGN(4); /*对齐处理, 每段开始之前进行 4 字节对齐*/ .data : /*数据段*/ { *(.data) } . = ALIGN(4); /*对齐处理, 每段开始之前进行 4 字节对齐*/ bss_start = .;/*记录 bss 段起始位置*/ .bss : /*bss 段*/ { *(.bss) } bss_end = .; /*记录 bss 段结束位置*/ }

##3. Makefile 编译脚本

makefile 文件编写 :

1.通用规则 ( 汇编文件编译规则 ) :汇编文件 编译 成同名的 .o 文件, 文件名称相同, 后缀不同,%.o : %.S, 产生过程是arm-linux-gcc -g -c $^, 其中^标识是所有的依赖文件, 在该规则下 start.S 会被变异成 start.o ;2.通用规则 ( C 文件编译规则 ) :C 代码编译成同名的 .o 文件,%.o : %.c, 产生过程是arm-linux-gcc -g -c $^;3.设置最终目标 :使用all:设置最终编译目标;( 1 ) 依赖文件 :产生最终目标需要依赖 start.o 文件, 使用all: start.o表示最终目标需要依赖该文件;( 2 ) 链接过程 :arm-linux-ld -Tgboot.lds -o gboot.elf $^, 需要使用链接器脚本进行连接,①链接工具是 arm-linux-ld 工具,②使用-Tgboot.lds设置链接器脚本 是刚写的 gboot.lds 链接器脚本,③输出文件是 gboot.elf 这是个中间文件,④ 依赖文件是$^代表所有的依赖;( 3 ) 转换成可执行二进制文件 :arm-linux-objcopy -O binary gboot.elf gboot.bin, 使用-O binary设置输出二进制文件, 依赖文件是gboot.elf, 输出的可执行二进制文件 即 结果是gboot.bin;4.makefile 文件内容 :

all: start.o #依赖于 start.o arm-linux-ld -Tgboot.lds -o gboot.elf $^ #使用链接器脚本, 将 start.o 转为 gboot.elf arm-linux-objcopy -O binary gboot.elf gboot.bin #将 gboot.elf 转化为可以直接在板子上执行的 gboot.bin 文件 %.o : %.S #通用规则, 如 start.o 是由 start.S 编译来的, -c 是只编译不链接 arm-linux-gcc -g -c $^ %.o : %.c #通用规则, 如 start.o 是由 start.c 编译来的, -c 是只编译不链接 arm-linux-gcc -g -c $^ .PHONY: cleanclean: #清除编译信息 rm *.o *.elf *.bin

##4. 编译输出可执行文件

编译过程 :

1.文件准备 : 将 汇编代码 ( start.S ) 链接器脚本 ( gboot.lds ) makefile 文件 拷贝到编译目录;2.执行编译命令 :make;3.编译结果 :可以看到 生成了 编译目标文件 start.o, 链接文件 gboot.elf, 可执行的二进制文件 gboot.bin ;

##5. 烧写代码到开发板并执行

###( 1 ) OK6410 开发板启动切换方式

OK6410 开发板启动切换方式 :通过控制 开发板右侧的 8个开关来设置启动来源;

1.sd 卡启动 :(1~8) 位置 : 0, 0, 0, 1, 1, 1, 1, 1;2.nand flash 启动 :(1~8) 位置 : x, x, x, 1, 1, 0, 0, 1;3.nor flash 启动 :(1~8) 位置 : x, x, x, 1, 0, 1, 0, x;

###( 2 ) 制作 SD 卡启盘 并 准备程序

制作 SD 卡启动盘 :

1.找到开发板的烧写工具 :OK6410-A 开发板的烧写工具 在开发光盘 A 的OK6410-A-1G用户光盘(A)-0812\Linux-3.0.1\Linux烧写工具目录下, 开发板光盘资料下载地址 ;

2.设置 SD_Writer.exe 属性 ( win10系统需要进行的设置 ) :右键点击属性, 在兼容性一栏, 设置 以 Windows 7 兼容模式运行, 并设置 以管理员身份运行此程序 ;

3.先格式化 SD 卡 :注意这里要使用 SD_Writer 中的 format 功能进行格式化 , 按照下面的步骤, 一步一步点击确定执行 ;

4.选择要烧写的文件 :这里选择OK6410-A-1G用户光盘(A)-0812\Linux-3.0.1\Linux烧写工具\mmc_ram256.bin文件;5.烧写文件到 SD 卡中 :直接点击 Program 按钮, 就将启动程序烧写到了 SD 卡中;

6.准备 LED 灯程序 :将编译出的 gboot.bin 文件名修改成 u-boot.bin, 必须修改成该文件名, 否则无法烧写上去;7.将程序拷贝到 SD 卡中 :将程序直接拷贝到 SD 卡中即可;

参考资料 :OK6410烧写裸板程序方法

这是之前写过的博客, 仅作为参考;

###( 3 ) SecureCRT 连接开发板并烧写程序

SecureCRT 连接开发板并烧写程序 步骤 :

1.硬件连接操作 :使用 USB 转 串口工具 将电脑 与 开发板链接, USB 插在电脑端, 串口端插在 开发板上, 插上电源适配器, 但是不要打开电源开关;2.开发板设置 :将开发板右侧的开关设置成 SD 卡启动, 即 (1~8) 位置 : 0, 0, 0, 1, 1, 1, 1, 1; 该步骤很重要;2.查询串口端口号 :在设备管理器中查看串口端口号, 这里可以看到是 COM9;

3.SecureCRT 连接串口 :打开 SecureCRT 软件, 点击快速连接, 然后在弹出的对话框中按照下面进行配置, ① 首先要选择 Serial 协议, ② 然后选择端口, 这个端口从设备管理器中查看, ③ 波特率选择 115200, ④ 取消 RTS/CTS 选项;

4.打开开发板 ( 很重要 ) :选中 SecureCRT 软件, 然后按住空格键不放, 这个操作很重要, 打开开发板开关,① 先按住空格键, ②再打开开关;

5.首先格式化 Nand Flash :选择 [1] 选项, 格式化 Nand Flash;

6.选择从 SD 卡中烧写 :选择 [2] Burn image from SD card 选项, 从 SD 卡中向开发板烧写程序;

7.选择烧写 u-boot :选择 [2] Flash u-boot, 烧写 u-boot, 会从 SD 卡中查找 u-boot.bin 文件, 然后烧写到 nand flash 中, 如果 SD 卡中 没有 u-boot.bin 会报错;

8.设置从 Nand Flash 启动 :设置开发板上的启动开关, (1~8) 位置 : x, x, x, 1, 1, 0, 0, 1; 此时 四个 LED 全亮;9.效果展示 :设置的 GPBDAT 寄存器值为 0b110000, 四个 LED 灯都亮起来;

10.修改 LED 灯显示参数后显示结果 :设置 GPBDAT 寄存器中值为 0b110101 是 第一个 和 第三个 LED 亮起来;

本博客的参考文章及相关资料下载 :

1.本博客代码及参考手册下载 :/download/han120/10573310

【嵌入式开发】LED 驱动 ( LED发光二极管原理 | 底板原理图分析 | 核心板原理图分析 | GPIO | 裸板程序烧写流程 )

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。