I am working on an ARM processor, I wondered if the ROM and RAM used are quite different than what I assume. For an example, for a program having the following memory table:
Program Size: Code=1264 RO-data=16 RW-data=0 ZI-data=1384
How is this distributed among ROM and RAM?
In general, processor instructions are placed in a segment you will call "code memory". This may actually reside in RAM and not in Flash or ROM. For example, on a PC, your code could be loaded from the hard drive into RAM and executed in RAM.
All addresses in a system that are not marked as faulting are assigned a memory type. The memory type is a high-level description of how the processor should interact with the address region. There are two memory types in Armv8-A: Normal memory and Device memory.
As with all prior ARM processors, the ARMv8 architecture is a Load/Store architecture. This means that no data processing instruction operates directly on data in memory. The data must first be loaded into registers, modified, and then stored to memory.
The abbreviations mean the following: RO=read-only, RW=read-write, ZI=zero-initialized. When you compile a standalone firmware for a microcontroller (as opposed to a user-mode program to be run in an OS), in the end you usually get a single monolithic image that will be flashed into the flash ROM and executed in-place.
The following table differentiates ROM and RAM: RAM is a volatile memory which could store the data as long as the power is supplied. ROM is a non-volatile memory which could retain the data even when power is turned off. Data stored in RAM can be retrieved and altered.
The ARM architecture is a von Neumann architecture, not a Harvard architecture. That means it uses a unified address space for both instructions and data. Whether any particular address contains RAM or ROM is up to the system designer. Instructions can be fetched from either. Show activity on this post.
ROM stands for non-volatile memory in computers., which means the information is permanently stored on the chip. The memory does not depend on an electric current to save data, instead, data is written to individual cells using binary code.
How it is distributed between ROM and RAM is up to you, you need to tell the linker where to put things. Ideally you would want the code, which is read-only to be in rom, no use burning ram for that. Likewise read only data can go in rom. read write and zero init need to go in ram. What toolchain (gcc based, IAR, Keil, ARM, etc) are you using?
You say "different than what we think of", as if everyone thinks in the same way :)
I would guess that you are coming from low-end microcontrollers which often have separate program and data address spaces. On ARM the situation is different: program code, data and peripheral registers all reside in the same flat 32-bit memory space. They are said to use a so-called "modified Harvard" architecture: the data and instruction buses are separate* (Harvard), but they use a single memory space (Von Neumann). Thus, you can read data from ROM and execute programs from RAM without any special set up.
For example, here's the memory map of LPC1768, a common Cortex-M3 microcontroller from NXP.
Note that on bigger ARMs the map can be much more complex, e.g. there are usually several CS (chip select) regions for external flash/SRAM/SDRAM or other peripherals, which might or might not be connected for each specific device using the processor. However, they all are still accessible via the same 32-bit flat memory space.
Now about the line you quote. At a guess, it was produced by Keil or ARM RVCT compiler. The abbreviations mean the following: RO=read-only, RW=read-write, ZI=zero-initialized.
When you compile a standalone firmware for a microcontroller (as opposed to a user-mode program to be run in an OS), in the end you usually get a single monolithic image that will be flashed into the flash ROM and executed in-place. This is fine for code which usually is not modified, or read-only (const) data, but not so great for writable data. That's where RW and ZI regions come in. The compiler inserts a small bootstrap code which takes a chunk with initial values of initialized data from the ROM image and copies it into RAM (this is the RW region). It then zeroes out the rest of the used RAM (ZI region). Then the control is transferred to the actual code written by the programmer.
Here I tried to illustrate how a typical program looks like for the above-mentioned 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 /
Thus, to calculate the used ROM (flash) space, you need to add up code, RO-data and RW-data. Used RAM will be the sum of RW-data and ZI-data. So, for your case, it's 1264+16+0=1280 bytes of flash and 0+1384=1384 bytes of RAM.
*: not always true: I think Cortex-M0 chips have a single data/instruction bus.
Igor Skochinsky gave you a good explanation (in my mind). I'll give you based on what I could find out with the KEIL build tools for a LPC23xx.
If you have the possibility to generate the map file after compilation (in keil IDE this is a simple checkbox option in the build setup) open the file and at the end you'll see the following lines :
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
I think that is self-explanatory, the RO data resides in ROM and RW in RAM.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With