ROM and RAM in ARM
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?
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.
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?
Ideally you would want the code, which is read-only to be in rom
Also, you want your code storage to be non-volatile!
精彩评论