目录
[1.1 关于内存系统](#1.1 关于内存系统)
[1.2 系统级问题](#1.2 系统级问题)
[1.2.1 内存系统、写缓冲区和缓存](#1.2.1 内存系统、写缓冲区和缓存)
[1.2.2 中断](#1.2.2 中断)
[1.2.3 Semaphores 信号量](#1.2.3 Semaphores 信号量)
1.1 关于内存系统
ARM处理器广泛应用于各种嵌入式系统和其他应用中。这些应用的内存系统需求差异很大,从具有平面地址映射的简单内存块,到使用以下任意或所有技术来优化内存资源使用的系统:
- 多种类型的内存
- 缓存
- 写缓冲区
- 虚拟内存和其他内存重映射技术
可用的内存映射I/O设备的范围进一步增加了基于ARM处理器的系统的多样性。
大多数系统需要以各种方式初始化和控制其内存系统设施,例如:
- 启用缓存,以确保实现其性能优势。
- 设置虚拟到物理地址的映射,以支持虚拟内存系统。
- 限制对内存区域的访问。
- 确保对内存映射I/O设备的正确访问,并且在正确的时间发生。(在最简单的内存系统中,这通常是自动发生的,但在更复杂的系统中,缓存和其他设施可能会干扰这一过程。)
注意: 由于基于ARM处理器的系统种类繁多,Part B中描述的所有功能可能不适用于任何特定系统。此外,一些ARM处理器以与此处描述的不同方式实现了功能。因此,特定ARM处理器的数据手册或技术参考手册是其内存和系统控制设施的权威来源。
因此,Part B不试图规定系统控制协处理器或其他内存系统组件功能的绝对要求。相反,它包含了一系列指南,如果遵循这些指南:
- 意味着系统更有可能与现有和未来的ARM软件兼容。
- 可能使不兼容的软件更容易移植到该系统。
1.2 系统级问题
本节列出了系统设计人员在使用ARM处理器时需要解决的许多一般和操作系统问题。
1.2.1 内存系统、写缓冲区和缓存
ARM处理器和软件被设计为连接到字节寻址的内存。对内存的字和半字访问忽略地址的对齐,并访问自然对齐的值(因此,内存访问忽略了字访问的地址位0和1,半字访问忽略了位0)。ARM处理器的字节序通常应与内存系统匹配,或者在发生任何非字访问之前配置为匹配(当字节序可配置且实现了CP15时,CP15寄存器1的位[7]控制字节序)。
用于存储程序和数据的内存应该被标记如下:
- 主内存(RAM)通常被设置为可缓存和可缓冲。
- 只读存储器(ROM)内存通常被设置为可缓存,并应该被标记为只读,因此不使用可缓冲属性,并且应该为1。
写缓冲区
一些ARM实现包含了一个合并写缓冲区,它将对同一位置的多次写操作合并为一次写入主内存。此外,一些写缓冲区会重新排序写操作,以便写操作以与处理器发出的顺序不同的顺序发布到内存。因此,I/O位置通常不应被标记为可缓冲,以确保所有写操作都以正确的顺序发布到I/O设备。
对于写入可缓冲内存区域的写操作,内存中止只能在数据放入写缓冲区时可检测到的条件作为结果向处理器发出。只能在数据后来写入主内存时才能检测到的条件(例如,来自主内存的奇偶校验错误)必须通过其他方法处理(通常通过引发中断)。
缓存
帧缓冲区可以是可缓存的,但在写回缓存实现上的帧缓冲区在更新后必须回写到内存。帧缓冲区可以是可缓冲的,但同样,在帧缓冲区更新后,写缓冲区必须写回内存。
ARM处理器通常不支持ARM和其他系统总线主控之间的缓存一致性。不支持总线监听。如果内存数据要在多个总线主控之间共享,而不采取特殊的软件措施确保一致性,那么数据必须被映射为:
- 不可缓存,以确保所有读取都访问主内存
- 不可缓冲,以确保所有写入都访问主内存
或者,您可以使用软件来管理由另一个总线主控器读取或写入的数据缓冲区的一致性,方法是:
- 在处理器写入数据缓冲区并在其他总线主控器读取缓冲区之前,从写回缓存和写缓冲区清理数据到内存。
- 在其他总线主控器写入缓冲区后,当缓冲区正在被读取时,从缓存中清除相关数据。
您可以使用未缓存的、未缓冲的信号量来维护多个总线主控器之间的同步(见B1-6页上的"信号量")。
对于具有写回缓存的实现,在对MMU页表进行任何更改之前,必须将所有脏缓存数据回写到内存,以确保缓存行回写可以使用页表形成传输的正确物理地址。
您可以使用虚拟地址或物理地址来索引缓存。物理页面必须只映射到一个虚拟页面,否则结果将是不可预测的。ARM处理器通常不提供单个物理页面的多个虚拟副本之间的一致性。
一些ARM实现支持单独的指令和数据缓存。数据和指令缓存之间的一致性不一定是硬件维护的,因此如果指令流被写入,必须使指令缓存和数据缓存保持一致。这可能涉及:
- 清除数据缓存(将脏数据存储到内存)
- 排空写缓冲区(完成所有缓冲的写操作)
- 清除指令缓存。
在程序被加载(因此被视为数据)并即将执行后,会发生指令和数据内存的不一致。如果使用或生成自修改代码,也会出现这种情况。
1.2.2 中断
ARM处理器实现了快速中断(Fast Interrupt,简称FIQ)和普通中断(Normal Interrupt,简称IRQ)两个级别的中断。这两个中断都是由外部信号触发的,许多实现在引发异常之前会同步中断。
快速中断请求(FIQ):
- 通过在CPSR中设置I和F位来禁用随后的普通和快速中断。
普通中断请求(IRQ):
- 通过在CPSR中设置I位来禁用随后的普通中断。
取消中断
软件(中断处理程序)有责任确保在重新启用中断(通过清除CPSR中的I位和/或F位)之前,中断的原因被取消(不再向处理器发出信号)。可以使用任何可能进行外部数据总线访问的指令来取消中断,这意味着任何加载或存储操作、交换操作或任何协处理器指令都可以用于取消中断。
在设计中断处理程序时,需要确保:
- 快速且准确地识别和处理中断的原因。
- 在处理完中断后,正确地清除中断信号,以防止不必要的中断重新触发。
- 在重新启用中断之前,确保系统状态是稳定的,并且中断处理程序已经完成了所有必要的操作。
这通常涉及到与硬件设备交互,以清除设备上的中断标志,以及可能的软件状态更新,以反映中断处理的结果。正确管理中断是确保系统稳定性和响应性的关键部分。
1.2.3 Semaphores 信号量
Swap 和Swap Byte指令在以下两种情况下具有可预测的行为:
-
多总线主控系统:
- 在这种情况下,使用Swap指令实现信号量,以控制不同总线主控之间的交互。
- 信号量必须放置在未缓存和未缓冲的内存区域中。Swap指令会导致一个(锁定的)读写总线事务。
- 这种类型的信号量可以被外部中止。
-
单处理器上的多线程系统:
- 在这种情况下,使用Swap指令实现信号量,以控制线程之间的交互。
- 信号量可以放置在可缓存和可缓冲的内存区域中,可能会发生(锁定的)读写总线事务,也可能不会。在这种系统中,Swap和Swap Byte指令的性能通常优于多总线主控系统(如上所述)。
- 如果被外部中止,这种类型的信号量的行为是不可预测的(UNPREDICTABLE)。
注意事项
- 放置在不可缓存/可缓冲内存区域中的信号量会导致不可预测的结果。
- 放置在可缓存/不可缓冲内存区域中的信号量也会导致不可预测的结果。
在设计和实现信号量时,选择合适的内存区域和指令使用方式至关重要,以确保系统的稳定性和性能。确保信号量的正确管理可以有效地控制多线程或多总线主控环境中的资源访问和同步。