我正在研究ARM处理器,我想知道使用的ROM和RAM是否与我假设的完全不同。例如,对于具有以下内存表的程序:
Program Size:
Code=1264
RO-data=16
RW-data=0
ZI-data=1384
如何在ROM和RAM之间分配?
答案 0 :(得分:60)
你说“不同于我们想到的”,好像每个人都以同样的方式思考:)
我猜你是来自低端微控制器,它们通常有独立的程序和数据地址空间。在ARM上,情况有所不同:程序代码,数据和外设寄存器都位于相同的32位平坦存储空间中。他们据说使用了所谓的“改进的哈佛”架构:数据和指令总线是独立的*(哈佛),但它们使用单个存储空间(Von Neumann)。因此,您可以从ROM读取数据并从RAM执行程序而无需任何特殊设置。
例如,这是LPC1768的存储器映射,LPC1768是恩智浦常见的Cortex-M3微控制器。
请注意,在较大的ARM上,地图可能会复杂得多,例如外部闪存/ 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 /
因此,要计算使用过的ROM(闪存)空间,需要添加代码,RO数据和RW数据。使用的RAM将是RW数据和ZI数据的总和。因此,对于您的情况,它是1264 + 16 + 0 = 1280字节的闪存和0 + 1384 = 1384字节的RAM。
*:并非总是如此:我认为 Cortex-M0芯片只有一条数据/指令总线。
答案 1 :(得分:3)
如果你有可能在编译后生成地图文件(在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数据驻留在RAM中的ROM和RW中。
答案 2 :(得分:2)
如何在ROM和RAM之间进行分配取决于您,您需要告诉链接器放置内容的位置。理想情况下,你会希望代码是只读的,不需要使用刻录ram。同样,只读数据可以用于rom。读写和零初始化需要进入ram。
您使用的是什么工具链(基于gcc,IAR,Keil,ARM等)?
答案 3 :(得分:1)
理想情况下,您希望代码(只读)位于ROM中
此外,您希望代码存储非易失性!