December 7, 2008
Memory Management Overview
The information in this document was accumulated from:
Rabbit® 4000 Microprocessor User’s Manual 019–0152 • 070720–H
Rabbit 4000® Microprocessor Designer’s Handbook 019-0156 • 070920-D
RabbitCore RCM4200 User’s Manual 019–0159 • 070928–C
Most, if not all, of the details can be found in the Rabbit 4000 User's
The Rabbit 4000 has a total of 24 physical address lines:
- dedicated lines A0-A19
- configurable lines PE0-PE3 which can function as A20-A23
The 4000 has either 8 or 16 data lines:
- dedicated lines D0-D7
- PD0-PD7 function as D8-D15 when 16 bit mode is enabled
The 4000 has
- three chip select pins: /CS0, /CS1, and /CS2
- two read strobes: /OE0 and /OE1
- two write strobes: /WE0 and /WE1
The memory is divided into four banks of equal size from
128KB up to 4MB. The bank size is set by telling the 4000 which two address
lines should be used to control the bank switching. For example, if
the 4000 is configured to use A17 and A18 for bank switching, then A0-16
will access 2^17 bytes (128KB) in each bank. The address lines above the pair used for bank
selection are not used.
Figure 5-1. Mapping Rabbit 4000 Physical Memory Space
Each bank can be configured to use a specific chip select
pin and a specific Read/Write enable pair. This allows each bank to be
read from a different device. The three chip selects in conjunction
with the two enable pairs allow the use of 6 different devices. For
example /CS0 and /OE0:/WE0 might access chip one while /CS1 and /OE0:/WE0
access chip two. Since both the chip select line and the enables are
required to access a chip, the two chips are controlled independently. The
same is true in the opposite fashion; two chips might have the same select
line but different enable pairs.
In figure 5-1, banks one and two use the same select and
enable lines so they both read from the same device. This brings up a
very important point:
Note 1: The bank selection pair of address lines
still drive external pins and are used as address bits.
This is important when two adjacent banks are setup to access
a single chip. The bank selection pair of address lines are fed to the
chip, even as they also perform bank selection duties. In the example
above, the bank select pair would be A18:A19, with A0:A17 (2^18 = 256 KB)
addressing within the bank.
When accessing memory below 256KB in this case, A18:A19 would both be zero
so bank 0 would be selected as they are also the bank selection pair.
When the second 256KB data range is accessed, A18:A19 would be 0:1 as
required to create an address in this range. The A18:A19 pair are fed
to the data chip so that it returns data from the proper address. As
the pair also serves to select the bank, they now switch to bank 1.
Since bank 1 is set up in this case to also access the same chip as bank 0,
the data from the first and second 256KB block can be read seamlessly from this single
The bank size is setup using the MECR register by specifying the pair of
address lines to use for bank switching. The timing, select line, and enable lines are setup using
MB0CR, MB1CR, MB2CR, and MB3CR.
The MBxCR registers also allow the bank select pair to be inverted.
This trick allows even more memory to be accessed. For the example
above without inversion, A18:A19 set to 0:0 would access bank 0 and the
output pins would access the lowest 256KB block. If the register is
now changed to invert A19 going out to the pin, the A18:A19 pair is still
0:0 and selecting bank 0 while the A19 pin is now a 1, which would load data
from the third 256KB segment in the chip. This allows bank 0 to access
pages at higher addresses and thus creates a paged memory system.
The Samples\MEMORY_USAGE.C program provided with the Dynamic C
installation can be used to learn how the memory is configured on a
particular Rabbit board. Running this program for the RCM4200 with
"Project Options/Compiler/Store Program in = RAM" selected shows:
MB0CR=c6=11000110: 0/1 Read/Write wait states, /CS2, /OE1 & /WE1
MB1CR=c6=11000110: 0/1 Read/Write wait states, /CS2, /OE1 & /WE1
MB2CR=45=01000101: 2/3 Read/Write wait states, /CS1, /OE1 & /WE1
MB3CR=00=00000000: 4/5 Read/Write wait states, /CS0, /OE0 & /WE0
The schematic for the RCM 4200 shows the /CS2, /OE1, and /WE1 are
connected to the 512K FSRAM, so banks 0 and 1 access this chip.
By modifying the original MEMORY_USAGE.C program to display the MECR
register using the MECRShadow value, the following is discovered:
This value is obviously wrong as it violates some restrictions on the
MECR register as explained in the Rabbit 4000 User Manual. Looking at
StdBios.c, it seems obvious that the shadow register is not always properly
updated when a value is stuffed to the MECR register. Using the method
used in StdBios.c for reading the value of MECR:
MECR=20=00100000=Bank select address is A[20:19]=512KB
Since the bank size is 512KB and the FSRAM is 512KB, bank 0 and 1 both
access the full range of the chip, so either could be used. Since the
execution code and data area are normally based at location 0x00, bank 0
would be used to execute code.
Looking at the schematic, the SRAM chip uses /CS1, /OE1, and /WE1, thus
bank 2 accesses this memory. Finally, the FLASH chip uses /CS0, /OE0,
and /WE0, thus bank 3 accesses this memory.
Note2: The purpose of the "shadow" register macros is to keep a
copy of the last value written to the associated register. Some
registers are write only so the only way to know what was written to them is
to keep a copy in memory. The MECR register can be read via the
MECR_VALUE macro, so the bios' failure to keep the shadow value updated is
Bank 0 accesses 512KB of FSRAM (fast execution ram)
Bank 1 accesses 512KB of FSRAM (mimics Bank 0)
Bank 2 accesses 512KB of SRAM (battery backed up)
Bank 3 access 512KB of FLASH
The setup is exactly the same when "Project Options/Compiler/Store Program
in = FLASH" is selected. This makes sense because with this option, the code is
stored in the FLASH memory but copied to the FSRAM before being executed.
In both the RAM and FLASH options, the code is still being run in FSRAM so
the bank layout should be the same.
Code and BIOS in Flash, Run in RAM
Several of the manuals recommend running in the "Code and BIOS in Flash,
Run in RAM" mode - but this option is no longer available in the Dynamic C
IDE, at least for the RCM4200. Apparently, because this mode is the only viable option for the
higher speed RCM4200,
the compiler now defaults to this mode regardless of which of the remaining
options of RAM or FLASH is chosen.
In RAM mode, the FLASH is bypassed and the code is compiled to and run in
the FSRAM. This is used mainly for debugging to save wear on the
In FLASH mode, the code is stored to the non-volatile FLASH and then
copied to the FSRAM before execution. This is used for production as
the code will not be lost when the power to the board is cycled.
Storing Code in Serial Flash
Code can also be stored in the serial FLASH chips which provide a lot of
memory for code and data such as web pages. The only way to specify
this seems to be to define _SERIAL_BOOT_FLASH_ in the Project
Options/Defines window or in the code itself. This was discovered by
examining the code in MEMORY_USAGE.C which checks to see if this is defined
before reporting that the code is compiled to serial FLASH.
Author: Mike Schoonover
back to main