Cortex-M7 内存映射模型

1 前言 

       如图1所示, Cortex-M7最大支持4GB的内存寻址,并对内存映射(memory map)做了初步的规定,将整个内存空间划分为了多个内存区域(region)。每个内存区域有着既定的内存类型(memory type)和内存属性(memory attribute),这两者决定了访存的具体行为。

5f823dbef2de4b51a725596dfb554d34.png

图1  Cortex-M7 memory map 

2 内存区域的类型和属性

        Memory ordering(内存排序) 描述了CPU访问内存的前后顺序,既可以指编译器编译时生成的内存访问序列,也可以指在运行时(runtime)由CPU生成的内存访问序列。CPU 并不是完全按照我们写的程序的逻辑顺序来访问内存的,在保证原始语义的情况下,编译器会对代码指令进行重新排序, CPU也会对指令进行重新排序、延缓执行、各种缓存等等,即通过乱序执行(out-of-order execution)来提升程序执行效率。

        所以,内存排序描述了CPU在内存顺序重排方面的能力,这也直接决定了CPU是否支持乱序执行。乱序执行使得CPU可以在最大程度上利用各类型的内存的总线带宽(bus-bradwidth)以提高程序运行效率。例如,cache比普通的memory banks的访问带宽要大很多。在单线程模式下,编译器和CPU偷偷地做了优化,乱序执行的细节无须由应用层代码操心,彷佛程序确实在严格按照代码的逻辑顺序执行;但在多线程模式下,或者通过内存总线和其他硬件进行数据交互时,乱序执行很容易出问题,这时候就需要内存屏障(memory barriers)指令出场了。     

2.1  内存类型memory types

         Cortex-M7的内存区域的类型主要有以下几种:

        ① 正常(Normal)

        Cortex-M7采用了流水线机制,通过执行前预取指令和分支预测来优化程序执行效率。对于normal类型内存区域,CPU可以重新排序处理(指令)以提高效率,或者可以做一些乐观的猜测性读操作(ldr);

       设备内存和强排序内存区域Device and Strongly-Ordered)

        对于设备内存(device memory)或强排序内存区域(Strongly-ordered memory)来说,CPU会老老实实的严格按照程序定义的顺序进行指令执行。

        此外,设备内存强排序内存区域也有所不同,外部内存系统(external memory system)可以用带缓冲地写设备内存(device memory)进行写操作,但不可带缓冲地写强排序内存区域。

2.2 内存属性memory attributes

         内存属性主要包括以下两种:

        ① 可共享(Shareable)

        对于可共享内存区域,如果系统中存在多个总线master(bus master,例如CPU配有DMA控制器),内存系统需要在总线master之间提供数据同步机制。所以,可共享即意味着拿来即可用,其内存区域内的数据由内存系统来保证同步性。

        此外,强排序内存区域总是可共享的,强排序的目的其实是为了防范语义风险;如果多个总线master可以访问一个不可共享的内存区域,则必须由软件来保证个总线master之间的数据一致性(data coherency)。

        ② 不可执行(Execute Never,XN)

        意为不可执行,即不可从该内存区域取值。谁胆敢从XN内存区域进行取值操作,立马错误异常(fault exception)伺候。

3 内存系统的内存访问顺序

        Memory system ordering of memory accesses,描述了内存系统对于内存访问顺序相关的规范。

        在不影响指令序列的行为的前提下,对于由显式内存访问指令引起的内存访问,内存系统不保证访问的实际顺序与指令的程序级顺序完全相同,即支持乱序执行。如果程序的正确执行依赖于两个内存访问指令的执行顺序,则软件必须在这两条指令之间加入内存屏障指令来保证其时序。

        但是,对于设备内存(device memory)或强排序内存区域(Strongly-ordered memory)来说,内存系统确实在一定程度上保证了访存的时序。例如,假设有由同一主接口(master interface)发起的A1和A2两条访存指令,如果A1在程序中执行的顺序在A2之前,则这两条访存指令的最终内存访问顺序如表1所示:

表1 内存访问顺序示例

e10ef25a63284292bf781176c6c24781.png

        从中可见,若两者都为可共享的设备内存或强排序内存,亦或者两者都为不可共享的设备内存,则内存访问都是严格序列化的。

4 各内存区域的访存行为(Behavior of memory accesses)

        Cortex-M7对于不同内存区域的访存行为具有不同的规范。其中,Code,SRAM和 external RAM区域可用于加载程序代码,具体如表2所示。

表2 各内存区域的内存访问行为明细

042a6d938e7d43c99e9d7fe045461d82.png

        以上只是默认的内存访问行为,如果使能MPU,则可以对其进行重新定义。

        当系统拥有cache和可共享内存(shared memory)时,某些内存区域的约束有所增加,某些内存区域被划分成更小颗粒度的区域,具体如表3所示:

 表3 各内存区域的共享性和cache策略

3cbedb156b3e4d59b3bf67c4a8e33f7f.png

        其中,WT表示的是write through,no allocate;WBWA表示write back,write allocate,具体含义如图2所示。        

64576ccc94f04b9db9cd885832a727f6.jpeg

图2 Cache读写策略示意图

5 软件程序定义的内存访问顺序

        软件程序直观地定义了一个程序执行流(program flow),其规则时基于一定的逻辑顺序。而当软件程序经编译器翻译成可执行的机器码并在CPU上执行时,内存系统通常不会严格按照软件程序定义的时序来进行内存访问,这也就是前文描述的乱序执行。

        CPU采用乱序执行的原因主要有以下几点:

        ① 在不改变软件程序定义的指令序列的预期行为的前提下,CPU可能会对一些访存操作重新排序;

        ② CPU拥有多个总线接口(bus interface);

        ③ 不同的内存区域或设备具有不同的等待状态;

        ④ 一些内存访问是带缓冲的,或者是带分支预测的;        

        举例来说,如果可以在运行时更改存储器的映射关系或者内存保护区的设置, (通过写MPU 的寄存器),就必须在更改之后立即补上一条 DSB 指令(数据同步指令)。因为对 MPU 的写操作很可能会被放到一个写缓冲中。

        写缓冲是为了提高存储器的总体访问效率而设的,但它也有副作用,其中之一,就是会导致写内存的指令被延迟几个周期执行,因此对存储器的设置不能即刻生效,这会导致紧临着的下一条指令仍然使用旧的存储器设置——但程序员的本意显然是使用新的存储器设置。这种紊乱危象是后患无穷的,常会破坏未知地址的数据,有时也会产生非法地址访问 fault。

       章节3中描述的一些由内存系统保驾护航的,严格按程序定义的顺序来访问内存的情况。除此之外,需要软件程序通过内存屏障指令(memory barrier instructions)来强制保证CPU的内存访问顺序,即严格按照软件程序定义的指令序列执行。

        这些相关的内存屏障指令指令有如下几种:

        ① DMB(Data Memory Barrier)             

        DMB指令可以保证其身前的内存指令全部处理完成后,其身后的指令才可以开始处理;DMB对于非访存指令的执行顺序没有影响;

        ② DSB(Data Synchronization Barrier)

       DSB架起了一道屏障,保证其身前所有的内存指令都执行完毕后,才会打开屏障,使得其身后的内存指令得以开始执行。在屏障打开之前,后续的所有内存指令都只能乖乖等待。此外,DSB指令不会更新xPSR的标志位。

        ③ ISB(Instruction Synchronization Barrier)

        ISB指令是指令级别的同步指令,在其身前的内存指令全部处理完毕后,对于其后的已预取指令通通抛掉,直接清洗流水线,重新从cache或内存中取指。这也就,处理结果对于后续的指令来说,ISB之前的所有指令都已执行完毕,且结果也已经落到实处;

        DMB 在双口 RAM 以及多核架构的操作中很有用。如果 RAM 的访问是带缓冲的,并且写完之后马上读,就必须让它“喘口气” ——用 DMB 指令来隔离,以保证缓冲中的数据已经落实到 RAM 中。
        DSB 比 DMB 更保险(当然也是有执行代价的),它是宁可错杀也不漏网——清空了写缓冲,使得任何它后面的指令,不管要不要使用先前的存储器访问结果,通通等待访问完成。
        同 DMB/DSB 相比, ISB 指令看起来似乎最强悍,对于高级底层技巧:“自我更新” (self-mofifying)代码,非常有用。举例来说,如果某个程序从下一条要执行的指令处更新了自己,但是先前的旧指令已经被预取到流水线中去了,此时就必须清洗流水线,把旧版本的指令洗出去,再预取新版本的指令。因此,必须在被更新代码段的前面使用 ISB,以保证旧的代码从流水线中被清洗出去,不再有机会执行。

5 总结        

        以上讨论的都是Cortex-M7默认的内存框架和内存访问行为,在功能安全的加注下,MPU的地位愈发重要,很多内容都还要和MPU结合起来一起考虑。不过,这都是后话了。

  • 56
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Cortex-M7编程手册是指针对ARM公司推出的Cortex-M7内核的编程指南。Cortex-M7是一种高性能、高效能的嵌入式处理器,被广泛应用于物联网、汽车、工业控制以及消费电子等领域。 Cortex-M7编程手册的目的是向开发人员提供有关如何优化使用Cortex-M7的信息和指导。该手册详细介绍了Cortex-M7内核的功能、寄存器和指令集,帮助开发人员了解处理器的架构和工作原理。 手册首先介绍了Cortex-M7的特性和优势,例如高性能时钟系统、深度流水线、硬件分析和调试等。然后,手册介绍了处理器的主要寄存器,包括通用寄存器、特殊寄存器和控制寄存器等,开发人员可以了解如何使用这些寄存器来配置和控制处理器的运行。 手册还详细介绍了Cortex-M7的指令集和编程模型。通过学习指令集和指令的编码方式,开发人员可以编写高效的程序来充分发挥处理器的性能。此外,手册还提供了一些面向特定应用场景的编程示例,帮助开发人员理解如何在实际应用中使用Cortex-M7。 最后,手册还介绍了一些优化技巧和调试方法,帮助开发人员进一步提升程序的性能和可靠性。通过深入理解Cortex-M7的内部结构和工作原理,开发人员可以通过合理的软件设计和编程方法来优化程序的执行效率。 总之,Cortex-M7编程手册是一本对于想要了解和开发基于Cortex-M7的嵌入式系统的开发人员来说非常有价值的参考书。它提供了全面的指导和信息,帮助开发人员充分发挥Cortex-M7处理器的性能。 ### 回答2: Cortex-M7编程手册是一本关于ARM Cortex-M7处理器编程的指南手册。它提供了关于这款处理器的详细技术资料和编程指令,以帮助工程师更好地理解和利用Cortex-M7处理器的性能和功能。手册的内容主要包括以下几个方面。 首先,手册介绍了Cortex-M7处理器的架构和特点。它详细解释了处理器的组成部分,包括核心、寄存器、存储器系统和外设。通过了解这些组成部分的工作原理,开发者可以更好地理解Cortex-M7处理器的内部结构和运行机制。 然后,手册介绍了Cortex-M7处理器的编程模型和指令集。编程模型是指处理器的寄存器和内存布局,以及程序执行的规则。指令集包括处理器支持的各种操作和功能的指令。手册会详细介绍常见的指令,如数据传输指令、算术运算指令、逻辑运算指令等。通过学习这些指令,开发者可以编写高效和功能强大的Cortex-M7程序。 此外,手册还介绍了Cortex-M7处理器的中断和异常处理机制。中断是指处理器在执行程序时遇到的事件,如外部设备的输入信号或定时器的触发。异常是指程序运行时发生的错误或异常情况。手册会详细介绍中断和异常的处理流程,以及如何编写中断服务程序和异常处理程序。 最后,手册提供了一些示例代码和开发工具的介绍,以帮助开发者更好地使用Cortex-M7处理器。这些示例代码可以作为学习和参考的资源,开发工具则可以提供更方便的开发环境和调试功能。 总之,Cortex-M7编程手册是一本帮助开发者理解和使用Cortex-M7处理器的重要参考资料。通过学习和掌握手册中的内容,开发者可以编写出高效、功能强大的Cortex-M7程序,实现各种应用需求。 ### 回答3: Cortex-M7编程手册是一本专门针对Cortex-M7处理器的编程指南,旨在帮助开发者更好地理解和使用Cortex-M7处理器。 该手册首先介绍了Cortex-M7处理器的架构和核心特性。Cortex-M7是一款高性能而低功耗的微控制器处理器,采用了ARMv7-M架构,并支持Thumb-2指令集。手册详细说明了Cortex-M7处理器的指令集,包括地址模式、数据处理指令、逻辑指令、分支指令等,开发者可以根据手册中的信息来编写针对Cortex-M7处理器的汇编程序。 此外,手册还介绍了Cortex-M7处理器的内存管理单元(MMU)和保护单元(MPU),并详细说明了如何配置和使用它们。MMU和MPU可以有效地保护系统的安全性和稳定性,开发者可以根据手册中的指导来配置和优化内存管理和保护机制。 此外,手册还介绍了如何在Cortex-M7处理器上进行外设编程,包括串口、SPI、I2C等常见外设的编程方法。手册还涵盖了中断处理、系统调试和性能优化等方面的内容,开发者可以根据手册中的指导来实现高效的系统设计和调试。 总之,Cortex-M7编程手册是一本涵盖了Cortex-M7处理器架构、指令集和各种编程技术的全面指南。通过学习和应用该手册,开发者可以更好地理解和使用Cortex-M7处理器,从而开发出更高效、稳定的嵌入式系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值