Processor instructions can specify 16-bit addresses, giving a logical address space of 64K (65,536 bytes). Dynamic C supports a physical address space of 1 MB on all Rabbit-based boards. Dynamic C 10.21 introduces support for a physical address space of 16 MB of combined code and data on Rabbit 4000 or 5000 based boards, with up to 1 MB for code. Dynamic C has been verified to work with Rabbit-based boards with 4.5 MB of memory.
An on-chip memory management unit (MMU) translates 16-bit addresses to 24-bit memory addresses for Rabbit 4000 and 5000 based boards. Four MMU registers (SEGSIZE, STACKSEG, DATASEG and XPC) divide and maintain the logical sections and map each section onto physical memory. Any memory beyond the 16-bit address capability of the processor, whether flash or RAM, is called xmem and requires memory management techniques for access.
A typical Dynamic C memory mapping of logical and physical address space is shown in the figure below. The actual layout may be different depending on the Rabbit processor used, the board type and which compilation options are selected. For example, enabling separate I&D space will affect the memory map.
Figure 10.1 Dynamic C Memory Mapping with a Rabbit 4000-Based Board
The register set provided by the Rabbit makes it easy to access the physical memory directly, bypassing the logical to physical mapping and allowing linear access of up to 16 MB. The size of the physical address space is determined by the quadrant size.
The quadrant size is determined by the MMU Expanded Code Register (MECR). This register contains the Bank Select Address setting. The Bank Select Address represents the two most significant bits of the physical address that will be used to select among the different quadrants. By defaul in Dynamic C 10.40, the MECR selects A20 and A19, thus leaving 19 bits for the address, which results in a quadrant size of 512 KB and a physical address space of 2 MB.
Figure 10.1 illustrates how the logical address space is divided and where code resides in physical memory. Both the static RAM and the flash memory are 1 MB in the diagram. Physical memory starts at address 0x000000 and flash memory is usually mapped to the same address. SRAM typically begins at address 0x100000.
If BIOS code runs from flash memory, the BIOS code starts in the root code section at address 0x000000 and fills upward. The rest of the root code will continue to fill upward immediately following the BIOS code. If the BIOS code runs from SRAM, the root code section, along with root data and stack sections, will start at address 0x100000.
The advanced user of Dynamic C can control how Dynamic C allocates and maps memory. For details on memory mapping, refer to any of the Rabbit microprocessor user’s manuals or designer’s handbooks. You can also refer to one of our technical notes: TN202, “Rabbit Memory Management in a Nutshell.” All of these documents are available at:
www.rabbitsemiconductor.com/docs/
A program can use many pages of extended memory (xmem). Under normal execution, code in xmem maps to the logical address region 0xE000 to 0xFFFF. To move blocks of data between logical memory and physical memory, you can still use the Dynamic C functions root2xmem(), xmem2root() and xmem2xmem(); however Dynamic C also has the “far” keyword, which makes use of physical addresses and thereby eliminates the need for root2xmem(), xmem2root() and xmem2xmem().
Code runs just as quickly in extended memory as it does in root memory, but calls to and returns from the functions in extended memory take a few extra machine cycles. Code placement in memory can be changed by the keywords xmem and root, depending on the type of code:
Pure Assembly Routines
Pure assembly functions may be placed in root memory or extended memory. Prior to Dynamic C version 7.10, pure assembly routines had to be in root memory.
C Functions
C functions may be placed in root memory or extended memory. Access to variables in C statements is not affected by the placement of the function. Dynamic C will automatically place C functions in extended memory as root memory fills. Short, frequently used functions may be declared with the root keyword to force Dynamic C to load them in root memory.
Inline Assembly in C Functions
Inline assembly code may be written in any C function, regardless of whether it is compiled to extended memory or root memory.
All static variables, even those local to extended memory functions, are placed in root memory. Keep this in mind if the functions have many variables or large arrays. Root memory can fill up quickly.
A Dynamic C application can allocate a pool of memory at compile time for dynamic allocation and deallocation of fixed-size blocks at run time. A pool can be located in root or extended memory. Descriptions for all API functions for dynamic memory allocation are in the Dynamic C Function Reference Manual. Or use Function Lookup from the Help menu (or Ctrl+H) to gain quick access to the function descriptions from within Dynamic C.
Read the comments at the top of \LIB\..\POOL.LIB for a description of how to use dynamic memory allocation in Dynamic C.