1 / 51

嵌入式系统与结构 第六课 嵌入式系统的接口

嵌入式系统与结构 第六课 嵌入式系统的接口. 主要内容. 通信基础 微处理器接口 仲裁 多级总线结构 通信协议. 1. 通信基础. 嵌入式系统的功能涵盖 处理功能 利用处理器实现 存储功能 用 Memory 实现 通信 处理器和存储器之间的数据传递 用总线来实现 称为 接口技术 interfacing. rd'/wr. Processor. Memory. enable. port. addr[0-11]. data[0-7]. bus. bus structure. 2. 通信基础: 一个简单的总线. 线 ( Wires ) :

sydnee
Download Presentation

嵌入式系统与结构 第六课 嵌入式系统的接口

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 嵌入式系统与结构 第六课 嵌入式系统的接口

  2. 主要内容 • 通信基础 • 微处理器接口 • 仲裁 • 多级总线结构 • 通信协议

  3. 1.通信基础 • 嵌入式系统的功能涵盖 • 处理功能 • 利用处理器实现 • 存储功能 • 用Memory实现 • 通信 • 处理器和存储器之间的数据传递 • 用总线来实现 • 称为接口技术interfacing

  4. rd'/wr Processor Memory enable port addr[0-11] data[0-7] bus bus structure 2.通信基础:一个简单的总线 • 线 (Wires): • 单项或双向的,可以代表多条Wires • 总线 (Bus); • 单一功能的一组线 • 地址总线, 数据总线 • 也可指用于通信的所有线集合 • 地址,数据和控制 • 相关协议: 是指一组通信规则 • 端口 (Ports) • 可以是引脚,也可是芯片内部连接

  5. rd'/wr enable addr data tsetup tread read protocol rd'/wr enable addr data tsetup twrite write protocol 2.通信基础---总线时序图 • 最常用的描述通信协议的方法 • 控制信号:高或低 • 数据信号: 有效或无效 • 协议可以有子协议 • 称为总线周期, 如读周期和写周期 • 每个总线周期由多个时钟周期组成 • 读操作举例

  6. Time-multiplexed data transfer Master Servant Master Servant req req 7:0 15:8 data(15:0) data(15:0) addr data addr data mux demux mux demux data(8) addr/data req req data addr/data 数据串行 地址/数据多工 addr data 3.接口---基本协议概念 (1) • 执行设备: 主设备启动数据传输, 从设备响应启动 • 数据方向: 发送者, 接收者 • 地址: 一种特殊的数据类型 • 指定一个内存、外设或外设内寄存器的位置 • 时分复用 • 多个数据部分共享一条总线 • 节省了线但耗费了时间

  7. 3. 基本协议概念:控制方法(2) Master Servant Master req Servant req ack data data req 1 3 req 1 3 ack 2 4 data 2 4 data taccess 1. 主设备将req设置,以接收数据 1.主设备将req设置,以接收数据 2. 从设备在时间内taccess将数据输出 2. 从设备将数据挂上并发送ack 3. 主设备接收数据,取消req 3.主设备接收数据,取消req 4. 从设备准备下一次请求 4.从设备准备下一次请求 使能协议 握手协议

  8. 3. 使能与握手折衷 (3) Master Servant req wait data req 1 3 req 1 4 wait wait 2 3 data 2 4 data 5 taccess taccess 1. 主设备将req设置,以接收数据 1.主设备将req设置,以接收数据 2. 从设备在时间内taccess将数据输出 2. 从设备不能在时间内taccess将数据输出,则将wait线置为有效 3. 主设备接收数据,取消req 4. 从设备准备下一次请求 3. 从设备将数据输出,则将wait线置为无效 4.主设备接收数据,取消req 5.从设备准备下一次请求 快响应方式 慢响应方式

  9. Microprocessor Memory I/O Device ISA bus C1 C2 WAIT C3 C4 CYCLE CLOCK D[7-0] A[19-0] ALE /MEMW CHRDY DATA ADDRESS C1 C2 WAIT C3 C4 CYCLE CLOCK D[7-0] A[19-0] ALE /MEMR CHRDY DATA ADDRESS 4.ISA 总线协议 –存储器访问 • ISA: 工业标准结构 • 用于 80x86’s • 特点 • 20-bit 地址 • 使能/握手折衷控制 • 4 总线周期 • CHRDY信号有效会导致 额外等待周期 (达到6) memory-read bus cycle memory-write bus cycle

  10. 主要内容 • 1. 接口基础 • 2.微处理器接口 • 2.1 I/O 寻址 • 2.2 中断 • 2.3 直接内存访问(DMA) • 3. 仲裁 • 4. 多级总线结构 • 5. 通信协议

  11. 1.微处理器接口:I/O寻址 • 处理器的很多引脚用于数据的I/O • 基于端口的(并行 I/O) • 处理器有一个或多个N-bit 端口 • 软件以读写寄存器的方式读写端口 • E.g., P0 = 0xFF; v = P1.2; -- P0 和 P1 是 8-bit 端口 • 基于总线的I/O • 处理器有一组地址、数据和控制端口对应与总线信号线; • 处理器将总线协议建在其硬件内 • 一条指令执行总线上的读写协议

  12. Processor Memory Processor Port 0 Port 1 Port 2 System bus Port 3 Parallel I/O peripheral Parallel I/O peripheral Port A Port B Port C Port A Port B Port C Adding parallel I/O to a bus-based I/O processor Extended parallel I/O 并行端口的扩展 • 并行 I/O 外设 • 处理器仅支持基于总线的I/O,但是又需要并行I/O 时 • 并行I/O外设连接到外设内部的寄存器,由处理器设置该寄存器对端口进行操作 • 扩展并行 I/O • 处理器支持基于端口的I/O,但是不够使用 • e.g., 扩展4端口到6端口

  13. 基于总线类型I/O : 内存映射 I/O 和标准 I/O • 处理器用相同总线与存储器和外设进行通信,与外设之间采用两种方式: • 内存映射 I/O • 外设寄存器占用内存地址空间的地址 • e.g., 总线有 16-bit地址 • 低32K 地址可能对应到内存 • 高32k 地址可以对应到外设 • 标准I/O (I/O映射 I/O) • 用总线上的额外引脚 (M/IO) 来指示 是访问一个内存还是外设 • e.g.,总线有 16-bit地址 • 全部 64K 对应到存储器(当 M/IO 设置成0) • 全64K对应到外设(当 M/IO 设置成1)

  14. ISA I/O bus read protocol C1 C2 WAIT C3 C4 CYCLE CLOCK D[7-0] A[15-0] ALE /IOR CHRDY DATA ADDRESS ISA bus的标准I/O 实例 • ISA 支持标准 I/O • 用/IOR 而不是/MEMR 来对外设读 • /IOW 用于外设写 • 16-bit I/O地址空间 vs. 20-bit 内存地址空间 • 其它与内存控制协议相同 • 折衷的使能/握手控制协议

  15. 8051 74373 HM6264 D<0...7> P0 Q D A<0...15> /CS /OE ALE G /WE CS2 /CS1 8 P2 /WR 27C256 /CS /RD D<0...7> /PSEN A<0...14> /OE Adr. 7..0 P0 P2 Q ALE /RD Data Adr. 15…8 Adr. 7…0 实例:8051基本内存协议 • 8051接口到外部存储器 • 端口 P0和P2支持 基于端口的 I/O • 当使用外部存储器时,这些端口用于数据/地址总线 • 16-bit 地址和8-bit数据被时分复用; 必须在ALE 信号的帮助下锁存地址低8位信号

  16. FSM description GO=0 GO=1 ADSP=1, ADSC=1 ADV=1, OE=1, Addr = ‘Z’ ADSP=0, ADSC=0 ADV=0, OE=1, Addr = Addr0 S0 S1 Specification for a single read operation GO=0 Data is ready here! CLK /ADSP /ADSC /ADV addr <15…0> /WE /OE /CS1 and /CS2 CS3 data<31…0> GO=0 GO=1 ADSP=1, ADSC=0 ADV=1, OE=1, Addr = ‘Z’ ADSP=1, ADSC=1 ADV=0, OE=0, Addr = ‘Z’ S2 S3 GO=1 GO=1 GO=0 实例:更复杂的存储器协议 • 产生控制信号来驱动流水线读取模式的TC55V2325FF存储器芯片 • Addr0是起始地址 • GO是使能输入

  17. 主要内容 • 1.接口基础 • 2.微处理器接口 • 2.1 I/O 寻址 • 2.2 中断 • 2.3 直接内存访问(DMA) • 3. 仲裁 • 4. 多级总线结构 • 5. 通信协议

  18. 1. 微处理器接口: 中断 • 当外设间歇的接收数据,必须由处理器进行处理 • 处理器可以周期的轮询外设检查数据是否到达–很浪费! • 外设能够在数据到达时中断处理器 • 需要额外的一个管脚:Int引脚 • 若Int为1, 处理器停止当前程序,跳到中断服务子程序( ISR) • 中断驱动的I/O • 本质上对中断引脚的轮询功能内嵌在硬件中,不需要额外周期。

  19. 1.微处理器接口:中断 (1) • 中断地址向量 • 固定中断 • 中断地址内嵌于处理器中,不会发生改变 • 可以将ISR保存在这个地址,若字节空间不够也可以将跳转地址指令存放在中断地址中。 • 向量中断 • 外设必须提供地址 • 处理器的系统总线上连接了多个外设 • 折中: 中断地址向量表

  20. 2. 使用固定ISR 位置的中断驱动 I/O 1(a):微处理器执行一个主程序 1(b): P1 接收数据到 0x8000. 的寄存器 Time 2: P1 将Int设置为有效,请求处理器服务 3:完成 100的指令, 微处理器检查出Int有效,则保存PC的当前值100,并将PC值设为ISR的固定地址16 4(a): The ISR 从 0x8000读取数据并修改将结果写回 0x8001. 4(b):读取数据后, P1 取消Int信号. 5: ISR返回,恢复 PC为 100+1=101微处理器继续执行

  21. μP 数据存储器 程序存储器 ISR 16: MOV R0, 0x8000 系统总线 17: # modifies R0 18: MOV 0x8001, R0 19: RETI # ISR return ... P1 P2 Int 主程序 ... PC 0x8000 0x8001 100: instruction 101: instruction 2.固定ISR位置的中断驱动I/O (2) 1(a): 微处理器执行主程序 1(b): P1 用地址为0x8000的寄存器接收数据.

  22. μP 数据存储器 程序存储器 ISR 16: MOV R0, 0x8000 系统总线 17: # modifies R0 18: MOV 0x8001, R0 19: RETI # ISR return ... P1 P2 Int 主程序 1 ... PC 0x8000 0x8001 100: instruction 101: instruction 2.固定ISR位置的中断驱动I/O (3) 2: P1置 Int引脚向微处理器请求服务 Int

  23. μP 数据存储器 程序存储器 ISR 16: MOV R0, 0x8000 系统总线 17: # modifies R0 18: MOV 0x8001, R0 19: RETI # ISR return ... P1 P2 Int 主存储器 ... PC 0x8000 0x8001 100: instruction 100 100 101: instruction 2.固定ISR位置的中断驱动I/O (4) 3: 完成指令100后,微处理器检查到Int引脚被置位于是保存PC值100,将PC设置成ISR的固定位置16 。

  24. μP 数据存储器 程序存储器 ISR 16: MOV R0, 0x8000 System bus System bus 17: # modifies R0 18: MOV 0x8001, R0 19: RETI # ISR return ... P1 P1 P1 P2 P2 Int Int 主程序 0 ... PC 0x8000 0x8001 0x8001 100: instruction 101: instruction 0x8000 2.固定ISR位置的中断驱动I/O (4) 4(a): The ISR 从0x8000读数据并修改然后写回到0x8001. 4(b): 读完后, P1 释放 Int引脚. 100

  25. μP 数据存储器 程序存储器 ISR ISR 16: MOV R0, 0x8000 系统总线 16: MOV R0, 0x8000 17: # modifies R0 17: # modifies R0 18: MOV 0x8001, R0 18: MOV 0x8001, R0 19: RETI # ISR return ... 19: RETI # ISR return P1 P2 Int ... ... 主程序 PC 0x8000 0x8001 ... 100: instruction +1 100: instruction 100 100 100 101: instruction 101: instruction 2.固定ISR位置的中断驱动I/O (5) 5: ISR返回, 然后被保存的 PC 100+1=101, 微处理器回到101处开始执行。.

  26. 1(a):微处理器执行一个主程序. 1(b):P1 接收数据到 0x8000的寄存器. Time 2: P1 将Int设置为有效,请求处理器服务 3:完成 100的指令, 微处理器检查出Int有效,则保存PC的当前值100,并将Inta设置有效。. 4: P1 探测到Inta并且将中断地址向量16放在数据总线上。 5(a):微处理器跳到总线上的地址16,ISR从地址为 0x8000的寄存器中读出数据,修改,然后回写到寄存器0x8001中。 5(b):读取数据后, P1 取消Int信号 6: ISR 返回,然后回复PC 到100+1=101,微处理器开始执行。 3.矢量中断驱动I/O

  27. μP 数据存储器 程序存储器 ISR 16: MOV R0, 0x8000 系统总线 17: # modifies R0 18: MOV 0x8001, R0 19: RETI # ISR return ... P1 P2 Inta 主程序 Int 16 ... PC 100: instruction 0x8000 0x8001 100 101: instruction 3.矢量中断驱动I/O 1(a):微处理器执行一个主程序 1(b):P1 接收数据到 0x8000. 的寄存器. .

  28. μP 数据存储器 程序存储器 ISR 16: MOV R0, 0x8000 系统总线 17: # modifies R0 18: MOV 0x8001, R0 19: RETI # ISR return ... Inta P1 P2 Int 主程序 16 ... 1 PC 100: instruction 0x8000 0x8001 100 101: instruction 3.矢量中断驱动I/O 2:P1 将Int设置为有效,请求处理器服务 Int

  29. μP 数据存储器 程序存储器 ISR 16: MOV R0, 0x8000 系统总线 17: # modifies R0 18: MOV 0x8001, R0 19: RETI # ISR return 1 ... Inta Inta P1 P2 Int 主程序 16 ... PC 100: instruction 0x8000 0x8001 100 100 101: instruction 3.矢量中断驱动I/O 3:完成 100的指令, 微处理器检查出Int有效,则保存PC的当前值100,并将 Inta设置有效。

  30. μP 数据存储器 程序存储器 ISR 16: MOV R0, 0x8000 系统总线 17: # modifies R0 16 18: MOV 0x8001, R0 19: RETI # ISR return ... Inta P1 P2 Int 主程序 16 16 ... PC 100: instruction 0x8000 0x8001 101: instruction 3.矢量中断驱动I/O 4: P1 探测到Inta并且将中断地址向量16放在数据总线上。 100

  31. μP 数据存储器 程序存储器 ISR ISR 16: MOV R0, 0x8000 系统总线 系统总线 16: MOV R0, 0x8000 17: # modifies R0 17: # modifies R0 18: MOV 0x8001, R0 18: MOV 0x8001, R0 19: RETI # ISR return ... 19: Inta RETI # ISR return P1 P1 P2 P2 ... Int Int Main program 16 ... 主程序 0 PC ... 100: instruction 0x8000 0x8000 0x8001 0x8001 100: instruction 100 101: instruction 101: instruction 3.矢量中断驱动I/O 5(a):微处理器跳到总线上的地址16,ISR从地址为 0x8000的寄存器中读出数据,修改,然后回写到寄存器0x8001中。 5(b):读取数据后, P1 取消Int信号

  32. μP 数据存储器 程序存储器 ISR ISR 16: MOV R0, 0x8000 系统总线 16: MOV R0, 0x8000 17: # modifies R0 17: # modifies R0 18: MOV 0x8001, R0 18: MOV 0x8001, R0 19: RETI # ISR return ... 19: RETI # ISR return P1 P2 Int ... 主程序 ... 主程序 PC 0x8000 0x8001 ... 100: instruction +1 100: instruction 100 100 100 101: instruction 101: instruction 3.矢量中断驱动I/O 6: ISR 返回,然后回复PC 到100+1=101,微处理器开始执行。

  33. 4. 中断向量表 • 在固定和向量中断进行折衷 • 一个中断引脚 • 内存中的表来保存ISR地址 (可以有256 个字) • 外设不提供ISR地址,而只提供表内索引 • 外设发送更少的位 • 不改变外设就能移动ISR位置

  34. 5. 屏蔽和非屏蔽中断 • 可屏蔽中断: • 通过设置屏蔽位使处理器忽略外设产生的中断。 • 在执行实时任务时很重要 • 非屏蔽中断 • 一个独立的中断,不能被屏蔽 • 在一些突发状态使用,如断电情况下,要通知处理器在电源消失之前跳转到子程序来备份关键数据到非易失性存储器中。

  35. 主要内容 • 1.接口基础 • 2.微处理器接口 • 2.1 I/O 寻址 • 2.2 中断 • 2.3 直接内存访问(DMA) • 3. 仲裁 • 4. 多级总线结构 • 5. 通信协议

  36. 1. 直接内存访问 (DMA) • 缓冲 • 在处理之前在存储器中临时保存数据 • 在外设内积累的数据通常会被缓冲 • 微处理器通过ISR处理这些数据 • 保存与恢复微处理器状态造成低效率 • 正常的程序必须等待 • DMA控制器具有更高的效率 • 独立的单用途处理器-DMA控制器 • 微处理器将系统总线控制权交给DMA控制器 • 微处理器能继续执行它的正常程序 • 不会由于ISR调用造成低效率的存储和恢复状态 • 正常程序只有在需要系统总线时才会停下 • 哈佛结构 –处理器能够取回并执行指令,只要它们不访问数据- 如果访问数据,就要暂停。

  37. μP Data memory Program memory 0x0000 0x0001 ISR 16: MOV R0, 0x8000 17: # modifies R0 System bus 18: MOV 0x0001, R0 19: RETI # ISR return ... Inta Main program P1 ... Int 16 100: instruction PC 101: instruction 0x8000 2.外设到存储器传输(采用向量中断) 1(a):微处理器执行一个主程序. 1(b):P1 接收数据到 0x8000的寄存器.

  38. μP Data memory Program memory 0x0000 0x0001 ISR 16: MOV R0, 0x8000 17: # modifies R0 System bus 18: MOV 0x0001, R0 19: RETI # ISR return ... Inta Main program P1 ... Int Int 16 100: instruction 1 PC 101: instruction 0x8000 100 2.外设到存储器传输(采用向量中断) 2: P1 将Int设置为有效,请求处理器服务

  39. μP Data memory Program memory 0x0000 0x0001 ISR 16: MOV R0, 0x8000 17: # modifies R0 System bus 18: MOV 0x0001, R0 19: RETI # ISR return ... Inta Main program P1 ... Int 16 100: instruction PC 101: instruction 0x8000 100 100 1 Inta 2.外设到存储器传输(采用向量中断) 3:完成 100的指令, 微处理器检查出Int有效,则保存PC的当前值100,并将 Inta设置有效。

  40. μP Data memory Program memory 0x0000 0x0001 ISR 16: MOV R0, 0x8000 17: # modifies R0 System bus System bus 18: MOV 0x0001, R0 16 19: RETI # ISR return ... Inta Main program P1 ... Int 16 16 100: instruction PC 101: instruction 0x8000 2.外设到存储器传输(采用向量中断) 4: P1 探测到Inta并且将中断地址向量16放在数据总线上。. 100

  41. ISR 16: MOV R0, 0x8000 17: # modifies R0 System bus 18: MOV 0x0001, R0 RETI # ISR return 19: ... Main program ... 100: instruction 101: instruction Int 0 2.外设到存储器传输(采用向量中断) μP 5(a):微处理器跳到总线上的地址16,ISR从地址为 0x8000的寄存器中读出数据,修改,然后回写到寄存器0x0001中。. 5(b):读取数据后, P1 取消Int信号。 Data memory Data memory Program memory 0x0000 0x0001 0x0001 ISR 16: MOV R0, 0x8000 17: # modifies R0 System bus 18: MOV 0x0001, R0 19: RETI # ISR return ... Inta Main program P1 P1 ... Int 16 100: instruction PC 101: instruction 0x8000 0x8000 100

  42. μP Data memory Program memory 0x0000 0x0001 ISR 16: MOV R0, 0x8000 17: # modifies R0 System bus 18: MOV 0x0001, R0 19: RETI # ISR return ... Inta Main program P1 ... Int 16 100: instruction PC 101: instruction 0x8000 +1 100 2.外设到存储器传输(采用向量中断) 6: ISR 返回,然后回复PC 到100+1=101,微处理器开始执行 100

  43. 3.外设到存储器传输(采用DMA) 1(a): μP 正执行主程序,已配置了DMA的控制寄存器 1(b): P1 收到输入数据放在寄存器0x8000.中 Time 3: DMA 控制器将Dreq引脚设置为有效,请求系统总线控制权 4:执行网指令100后,微处理器检查到Dreq信号有效,交出系统总线,将Dack 引脚有效,继续执行,只有在需要系统总线时才暂停 2: P1 设置req引脚有效,请求DMA控制器的服务 5: (a) DMA 控制器将ack引脚设置为有效, (b) 从地址0x8000读数据 (c) 将数据写入存储器地址 0x0001中。 6:. DMA 将 Dreq和 ack 无效,结束与P1的握手。 7(a):微处理器将 Dack无效,重新获得系统总线控制权。 7(b): P1 将req无效.

  44. μP Data memory Program memory 0x0000 0x0001 No ISR needed! System bus ... Dack DMA ctrl P1 Main program Dreq ... ack 0x0001 100: instruction PC req 0x8000 0x8000 101: instruction 100 3.外设到存储器传输(采用DMA) 1(a): μP 正执行主程序,已配置了DMA的控制寄存器 1(b): P1 收到输入数据放在寄存器0x8000中

  45. μP Data memory Program memory 0x0000 0x0001 No ISR needed! System bus ... Dack DMA ctrl DMA ctrl P1 P1 P1 Main program Dreq ... ack 0x0001 100: instruction PC req 0x8000 0x8000 101: instruction 100 Dreq req 1 1 3.外设到存储器传输(采用DMA) 2: P1 设置req引脚有效,请求DMA控制器的服务 . 3: DMA 控制器将Dreq引脚设置为有效,请求系统总线控制权

  46. μP Data memory Program memory 0x0000 0x0001 No ISR needed! System bus 1 ... Dack Dack DMA ctrl P1 Main program Dreq ... ack 0x0001 100: instruction PC req 0x8000 0x8000 101: instruction 100 3.外设到存储器传输(采用DMA) 4:执行网指令100后,微处理器检查到Dreq信号有效,交出系统总线,将Dack 引脚有效,继续执行,只有在需要系统总线时才暂停

  47. μP Data memory Program memory 0x0000 0x0001 No ISR needed! System bus ... Data memory Dack DMA ctrl P1 0x0000 0x0001 Main program Dreq ... ack 0x0001 100: instruction PC req 0x8000 0x8000 System bus 101: instruction 100 DMA ctrl P1 ack 0x0001 1 req 0x8000 ack 0x8000 3.外设到存储器传输(采用DMA) 5: (a) DMA 控制器将ack引脚设置为有效, (b) 从地址0x8000读数据 (c) 将数据写入存储器地址 0x0001中。 (处理器仍然执行无需暂停)

  48. μP Data memory Program memory 0x0000 0x0001 No ISR needed! System bus ... Dack DMA ctrl P1 Main program Dreq ... ack 0x0001 100: instruction PC req 0x8000 0x8000 101: instruction 100 0 ack Dreq 0 3.外设到存储器传输(采用DMA) 6: DMA 将 Dreq和 ack 无效,结束与P1的握手.

  49. C1 C2 C3 C4 C5 C6 C7 CYCLE CLOCK D[7-0] A[19-0] ALE /IOR /MEMW CHRDY DATA DMA Memory-Write Bus Cycle DMA Memory-Read Bus Cycle ADDRESS C1 C2 C3 C4 C5 C6 C7 CYCLE CLOCK D[7-0] A[19-0] ALE /MEMR /IOW CHRDY Processor Memory DATA ISA-Bus A R ADDRESS R I/O Device DMA A 4. ISA 总线的DMA 周期

  50. 小结 接口技术 (1) • 总线与端口的区别 • 总线接口的基本控制方法 • 总线时序图 • 基于端口I/O寻址与基于总线I/O寻址 • 基于中断向量表的总断响应过程 • 在DMA控制器控制下的外设与存储器的数据传输

More Related