你的位置: 首页 > 通信技术 > 嵌入式系统

ARM处理器存储器及存储器映射I/O

2016-10-23 09:16:39 | 人围观 | 评论:

     ARM7TDMI处理器采用冯・诺依曼(Von Neumann)结构,指令和数据共用一条32位数据总线。只有装载、保存和交换指令可访问存储器中的数据。
      ARM7的规范仅定义了处理器核与存储系统之间的信号及时序(局部总线),而现实的芯片一般在外部总线与处理器核的局部总线之间有一个存储器管理部件将局部总线的信号和时序转换为现实的外部总线信号和时序。因此,外部总线的信号和时序与具体的芯片相关,不是ARM7的标准。具体到某个芯片的外部存储系统的设计需要参考其芯片的数据手册或使用手册等资料。
     ARM7TDMI处理器将存储器看作是一个从0开始的线性递增的字节集合:
     (1)字节0到3保存第1个存储的字
     (2)字节4到7保存第2个存储的字
     (3)字节8到11保存第3个存储的字
     (4)依此类推
     ARM7TDMI处理器可以将存储器中的字以下列格式存储(详细说明见“存储器格式”小节):
     (1)大端格式(Big-endian)
     (2)小端格式(Little-endian)
     关于“地址空间”:ARM结构使用单个平面的232个8位字节地址空间。字节地址按照无符号数排列,从0到232-1。地址空间可以看作是包含230个32位字 ,或231个16位半字。如果地址向上或向下溢出地址空间,通常会发生翻转。
     注意:如果在取指操作时地址发生溢出,只要没有执行预取的无效指令,就不会导致异常。
     跳转目标的计算方法:(当前指令的地址) + 8 + 偏移量
     下一条指令位置的计算方法:(当前指令的地址) + 4
     关于“存储器格式”:地址空间的规则:
     (1)位于地址A的字包含的字节位于地址A,A+1,A+2和A+3;
     (2)位于地址A的半字包含的字节位于地址A和A+1;
     (3)位于地址A+2的半字包含的字节位于地址A+2和A+3;
     (4)位于地址A的字包含的半字位于地址A和A+2;
     下面讲一下,存储器系统有两种映射机制:
     (1)小端存储器系统:在小端格式中,高位数字存放在高位字节中。因此存储器系统字节0连接到数据线7~0。
     (2)大端存储器系统:在大端格式中,高位数字存放在低位字节中。因此存储器系统字节0连接到数据线31~24。
     一个基于ARM内核的芯片可以只支持大端模式或小端模式,也可以两者都支持。
     在ARM指令集中不包含任何直接选择大小端的指令,但是一个同时支持大小端模式的ARM芯片可以通过硬件配置(一般使用芯片的引脚来配置)来匹配存储器系统所使用的规则。
     注意:如果实际的存储器格式与芯片的存储器格式不符时,只有以字为单位的数据存取才正确,否则将出现不可预期的结果。
     关于“未对齐的存储器访问”:ARM结构通常希望所有的存储器访问都合理的对齐。具体来说就是字访问的地址通常是字对齐的,而半字访问使用的地址是半字对齐的。不按这种方式对齐的存储器访问称为非对齐的存储器访问。
     (1)将一个非字(半字)对齐的地址写入ARM(Thumb)状态的R15寄存器,将引起非对齐的指令取指。
     (2)在一个非字(半字)对齐的地址读写一个字(半字),将引起非对齐的数据访问:
     指令的预取和自修改代码
     许多ARM实现在前一条指令的执行尚未完成时将指令从存储器中取出。这个动作称为指令的预取。指令的预取并不是实际执行指令。芯片的生产厂商可以自由选择预取指令的数目。被预取的指令可能得不到运行,可能的原因是:(1)发生异常;(2)发生跳转;
     当读取PC时,得到的指令地址比正在执行指令的地址落后两条指令:
     (1)对于ARM指令,得到的地址是它自身地址+8;
     (2)对于Thumb指令,得到的地址是它自身地址+4;
     虽然生产厂商可以选择预取指令的数目,但是仍然可以保证读取PC所得到地址比它自身地址落后两条指令。
     在预取之前要进行转移预测,例如在执行一条分支指令,此时要判断是预取分支指令之后的指令还是转移目标地址的指令。
     关于“预取可能存在的问题”:在存储器中的指令可能在它被预取之后,被执行之前发生改变。如果发生这种情况,对存储器中的指令进行修改一般不能阻止已取指的指令的执行。
     如果在“SUB”指令预取之后,执行之前,发生中断 ,那么该指令将被丢弃,而不会执行。
     如果ARM处理器或存储器系统允许保持预取指令的备份并使用这些备份而不是重新预取,那么以后执行这段代码,仍将执行“SUB”指令。
     关于“指令存储器屏障(IMB)”:在许多系统中,几乎不可能完全避免自修改代码的使用。例如,任何一个允许将程序装入存储器然后执行的系统都使用自修改代码。
     因此每个ARM芯片都定义了一系列的操作,使自修改代码序列可以可靠地执行。这一串代码称为指令存储器屏障(IMB),它通常同时取决于具体的ARM芯片的和具体存储器芯片。
     关于“存储器映射的I/O”:基于ARM内核的芯片具有许多的外设,这些外设访问的标准方法是使用存储器映射的I/O,为外设的每个寄存器都分配一个地址。通常,从这些地址装载数据用于读入,向这些地址保存数据用于输出。有些地址的装载和保存用于外设的控制功能,而不是输入或输出功能。
     注意:存储器映射的I/O位置的操作不同于正常的存储器位置的操作。通常,存储器映射的I/O位置没有高速缓存和无缓冲区。




标签: