ARM中的ROM和RAM

ARM中的ROM和RAM,arm,Arm,我在一个ARM处理器上工作,我想知道使用的ROM和RAM是否与我假设的完全不同。例如,对于具有以下内存表的程序: Program Size: Code=1264 RO-data=16 RW-data=0 ZI-data=1384 这在ROM和RAM中是如何分布的?你说“不同于我们所想的”,好像每个人都以同样的方式思考:) 我猜你来自低端微控制器,它们通常有单独的程序和数据地址空间。在ARM上,情况有所不同:程序代码、数据和外围寄存器都位于相同的平面32位内存空间中。据说它们使用了一种所

我在一个ARM处理器上工作,我想知道使用的ROM和RAM是否与我假设的完全不同。例如,对于具有以下内存表的程序:

Program Size: 
Code=1264 
RO-data=16 
RW-data=0 
ZI-data=1384
这在ROM和RAM中是如何分布的?

你说“不同于我们所想的”,好像每个人都以同样的方式思考:)

我猜你来自低端微控制器,它们通常有单独的程序和数据地址空间。在ARM上,情况有所不同:程序代码、数据和外围寄存器都位于相同的平面32位内存空间中。据说它们使用了一种所谓的“改进的哈佛”体系结构:数据总线和指令总线是分开的*(哈佛),但它们使用单一的内存空间(冯·诺依曼)。因此,您可以从ROM读取数据并从RAM执行程序,而无需任何特殊设置

例如,这里是LPC1768的内存映射,它是NXP的一个通用Cortex-M3微控制器

请注意,在较大的臂上,映射可能要复杂得多,例如,通常有几个用于外部闪存/SRAM/SDRAM或其他外围设备的CS(芯片选择)区域,这些区域可能使用处理器连接每个特定设备,也可能不连接。但是,它们仍然可以通过相同的32位平面内存空间访问

现在谈谈你引用的那句话。据猜测,它是由Keil或ARM RVCT编译器生成的。缩写的意思如下:RO=只读,RW=读写,ZI=零初始化

当你为一个微控制器编译一个独立的固件时(与在操作系统中运行的用户模式程序相反),最终你通常会得到一个单一的单片映像,该映像将被闪存到闪存ROM中并就地执行。这对于通常不被修改的代码或只读(const)数据很好,但对于可写数据则不太好。这就是RW和ZI区域的作用。编译器插入一个小的引导代码,该代码从ROM映像中获取具有初始化数据初始值的块,并将其复制到RAM中(这是RW区域)。然后将剩余的已用RAM归零(ZI区域)。然后,控制权被转移到程序员编写的实际代码中

在这里,我试图说明上述LPC1768的典型程序的外观:

+-----------+ 0x1000 8000 \
|  Unused   |             |
+-----------+             |
|  ZI data  | <--(clear)  | RAM
+-----------+             |
|  RW data  | <--(copy)---|---+
+-----------+ 0x1000 0000 /   |
                              |
                              |
+-----------+ 0x0008 0000 \   |
|  Unused   |             |   |
+-----------+             |   |
|  RW init  |-------------|---+
+-----------+             |
|  RO data  |             | ROM (Flash)
+-----------+             |
| User code |             |
+-----------+             |
| Boot code |             |
+-----------+             |
|  Vectors  |             |
+-----------+ 0x0000 0000 /
+------------+0x1000 8000\
|未使用的|
+-----------+             |

|ZI data |如何在ROM和RAM之间分配取决于您,您需要告诉链接器将东西放在哪里。理想情况下,您希望只读代码位于rom中,而不必为此烧掉ram。同样,只读数据可以进入rom。读写和零初始化需要进入ram

您使用的是什么工具链(基于gcc、IAR、Keil、ARM等)

理想情况下,您希望只读的代码位于rom中


另外,您希望代码存储是非易失性的

伊戈尔·斯科金斯基(在我心目中)给了你一个很好的解释。我将根据KEIL针对LPC23xx的构建工具所能找到的信息,向您介绍

如果您可以在编译后生成映射文件(在keil IDE中,这是构建设置中的一个简单复选框选项),请打开该文件,最后您将看到以下几行:

Total RO Size (Code+Ro data)                36732 (35.87kB)
Total RW Size (RW Data + ZI Data)           27348 (26.71kB
Total ROM Size (Code + RO Data + RW Data)   36812 (35.95kB

我认为这是不言自明的,RO数据驻留在ROM中,RW驻留在RAM中。

因此,有人认为
bss
不够神秘,决定将同一事物命名为
ZI
?我想说ZI远没有bss神秘:)它可能是“插入一个小引导代码”的链接器,“不是编译器。”Igor Skochinsky:我们不需要考虑RAM计算中的调用堆栈大小和堆大小吗?实际上,在RAM中存储部分代码可能有一些好处,前提是它在运行之前从ROM复制。在许多芯片上,存储在RAM中的代码可能比存储在ROM中的代码运行得快得多(高达两倍)。通常不值得将整个应用程序复制到RAM中,但在RAM中加入一些小的例程可能是一个重大的胜利。RAM中必须包含的另一种代码类型是闪烁例程:当你需要更新固件时,你必须先擦除当前代码,如果你不小心的话,你最终会阻塞设备。