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结合起来一起考虑。不过,这都是后话了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/796149.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

numpy学习笔记,不定期更新

numpy类型入门 import numpy库后,通过numpy参数操作示例 import numpy as np# 创建ndarray,通过list创建 a np.array([1, 2, 3]) print(a)[1 2 3]# 通过元组创建ndarray,并指定数据类型为float (此处是python的float类型,不是n…

从石膏像到真人:素描的进步之路

从石膏像绘画到真人绘画:素描的进步之路怎么走 从石膏像绘画到真人绘画,素描的进步之路可以通过以下几个步骤来实现: 掌握基本技能:在开始真人绘画之前,需要先掌握基本的素描技能,包括构图、明暗关系、观察…

物理层习题及其相关知识(谁看谁不迷糊呢)

1. 对于带宽为50k Hz的信道,若有4种不同的物理状态来表示数据,信噪比为20dB 。(1) 按奈奎斯特定理,信道的最大传输数据速率是多少?(2) 按香农定理,信道的最大传输数据速度…

PSI相关存档

https://anquan.baidu.com/upload/ue/file/20190814/1565763561975581.pdf 关于PSI的研究综述_psi综述-CSDN博客 https://zhuanlan.zhihu.com/p/532761749 https://zhuanlan.zhihu.com/p/407290294 隐私集合求交(Private Set Intersection)问题综述 - 知乎 (zhihu.com) Pr…

基于Springboot+Vue实现前后端分离酒店管理系统

一、🚀选题背景介绍 📚推荐理由: 近几年来,随着各行各业计算机智能化管理的转型,以及人们经济实力的提升,人们对于酒店住宿的需求不断的提升,用户的增多导致酒店管理信息的不断增多,…

ICLR 2024 | 联邦学习后门攻击的模型关键层

ChatGPT狂飙160天,世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 联邦学习使多个参与方可以在数据隐私得到保护的情况下训练机器学习模型。但是由于服务器无法…

华为分红出炉,人均超50w!

华为分红 770 亿 4 月 2 日,北京金融资产交易所官网发布了《华为投资控股有限公司关于分配股利的公告》。 公告指出:经公司内部有权机构决议,拟向股东分配股利约 770.945 亿元。 众所周知,华为并不是一家上市公司,这里…

C++从入门到精通——初步认识面向对象及类的引入

初步认识面向对象及类的引入 前言一、面向过程和面向对象初步认识C语言C 二、类的引入C的类名代表什么示例 C与C语言的struct的比较成员函数访问权限继承默认构造函数默认成员初始化结构体大小 总结 前言 面向过程注重任务的流程和控制,适合简单任务和流程固定的场…

详解Qt中的布局管理器

Qt中的布局管理是用于组织用户界面中控件(如按钮、文本框、标签等)位置和尺寸调整的一种机制。说白了就是创建了一种规则,随着窗口变化其中的控件大小位置跟着变化。Qt提供了多种布局管理器,每种都有其特定用途和特点。以下是对Qt…

使用open3d分离背景和物体点云(二)

一、代码 Python import cv2 import open3d as o3d import matplotlib.pyplot as plt import numpy as npdef thPlaneSeg(pointcloud):pcd_np = np.asarray(pointcloud.points)# 设置深度阈值 (假设Z轴是深度轴)depth_threshold = 0.196 # 1.0米# 应用深度阈值,移除远于阈值…

自定义实现shell/bash

文章目录 函数和进程之间的相似性shell打印提示符,以及获取用户输入分割用户的输入判断是否是内建命令执行相关的命令 全部代码 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站, 通俗易懂,风趣幽默&#…

vue项目打包

Vue项目打包的步骤如下: 确保环境配置正确:首先,确保你的开发环境已经安装了Node.js和npm(Node.js的包管理器)。Vue项目通常使用npm或yarn作为包管理器来安装依赖。 安装项目依赖:在项目根目录下&#xff…

Day30 线程安全之窗口售票问题(含代码)

Day30 线程安全之窗口售票问题(含代码) 一、需求: 铁道部发布了一个售票任务,要求销售1000张票,要求有3个窗口来进行销售, 请编写多线程程序来模拟这个效果( 注意:使用线程类的方式…

【Qt 学习笔记】详解Qt中的信号和槽

博客主页:Duck Bro 博客主页系列专栏:Qt 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ 详解Qt中的信号与槽 文章编号:Qt 学习笔记 / 12 文章目录…

红黑树的平衡之道:深入解析右旋操作的原理与实践

红黑树的平衡之道:深入解析右旋操作的原理与实践 一、 红黑树旋转的背景二、右旋(RIGHT-ROTATE)的原理三、右旋(RIGHT-ROTATE)的算法步骤四、右旋(RIGHT-ROTATE)的伪代码五、右旋(RI…

C语言-角谷步数

题目描述 你听说过角谷猜想吗? 任意的正整数,比如 5,我们从它开始,如下规则计算: 如果是偶数,则除以2;如果是奇数,则乘以 3 再加 1。 如此循环,最终必会得到 1&#xff…

ctf_show笔记篇(web入门---jwt)

目录 jwt简介 web345: web346: web347: web348: web349: web350: jwt简介 JSON Web Token(JWT)通常由三部分组成 Header(头部):包含了两部分信息&…

蓝桥杯备考3

P8196 [传智杯 #4 决赛] 三元组 题目描述 给定一个长度为 n 的数列 a,对于一个有序整数三元组 (i,j,k),若其满足 1≤i≤j≤k≤n 并且,则我们称这个三元组是「传智的」。 现在请你计算,有多少有序整数三元组是传智的。 输入格式…

LRU的原理与实现(java)

介绍 LRU的英文全称为Least Recently Used,即最近最少使用。它是一种内存数据淘汰算法,当添加想要添加数据而内存不足时,它会优先将最近一段时间内使用最少的数据淘汰掉,再将数据添加进来。 原理 LRU的原理在介绍中就已经基本说…

机器学习模型——逻辑回归

https://blog.csdn.net/qq_41682922/article/details/85013008 https://blog.csdn.net/guoziqing506/article/details/81328402 https://www.cnblogs.com/cymx66688/p/11363163.html 参数详解 逻辑回归的引出: 数据线性可分可以使用线性分类器,如果…