Link here

Using Paged Memory
The GNU C compiler, RTOS, and your C language programs easily address the
HCS12/9S12 MCU's RAM and Flash memory pages

The memory map of the PDQ Board is described here, including;

  • the types of available memory (Flash, RAM, and EEPROM),
  • how different regions of memory are devoted to different uses,
  • where the GNU C compiler allocates memory,
  • how paged memory works, and,
  • how to access paged memory from C language programs.

Understanding these issues will help you to write highly effective programs within the PDQ Board's RTOS for your instrument control and automation applications.


The PDQ Board’s memory map

The Freescale 9S12 (HCS12) microcontroller has a native address space of 64 Kbytes, but it can address up to 1 megabyte of memory implemented as 64 pages of 16 Kbyte each. The PDQ Single Board Computer (SBC) includes a variety of convenient memory types, including:

  • sector-programmable Flash on the processor chip (onchip Flash),
  • byte-programmable nonvolatile EEPROM,
  • paged RAM backed up by an onboard Flash chip (shadowed RAM), and
  • common RAM that is available regardless of the current page for variable storage, buffers and stacks.

Part of the common RAM is on the processor chip (onchip RAM), and the rest is implemented by an external RAM chip on the board. The memory and memory-mapped hardware on the PDQ Board fills the processor’s 1 Mbyte memory space, so there is no external memory bus brought out. However, if you need more memory you can simply plug in a Compact Flash Wildcard module to add 512 Mbytes or more of removable mass memory.

Flash memory is nonvolatile, so it retains its contents even when power is removed. Simple write-cycles do not modify the Flash memory contents, so program code stored in Flash is safe even if the processor gets lost and overwrites memory. Flash memory is also re-programmable, and the Flash programming functions are present in the PDQ Board’s onboard software library. Flash is ideal for storing compiled program code.

Code can also be compiled into paged RAM and saved to a shadow Flash device. Much as your desktop PC loads pre-compiled code from the hard drive into RAM each time you turn it on, you can configure the PDQ Board to load specified pages from the shadow Flash into paged RAM upon each power-up, reset or restart. The RAM has fast access time and can support full speed program execution, while the slower external shadow Flash provides nonvolatile storage of the contents when power is removed. Designated page regions (pages 0x00-0F and/or pages 0x10-13) of this shadowed RAM can be automatically write protected after the contents are loaded from the shadow Flash, so that an unexpected processor crash can not corrupt the RAM contents. Like Flash, write-protected shadowed RAM is an ideal place to store a compiled application program. Regions of shadowed RAM that are not needed for code storage can be dedicated to the storage of arrays of volatile data.

The PDQ Board includes 512K onchip Flash memory, 14K onchip RAM, 1K onchip EEPROM (384 bytes usable by application), and 496K off-chip RAM with Flash backup. Code can be located in the write-protectable Flash-backed RAM or the onchip Flash. Some memory is reserved for use by the Kernel (operating system), and the remaining memory is available for use by your application program.

The paged memory address space of the 9S12 HCS12 development board showing its partitioning among RAM Flash and EEPROM.
Fig. 1  The paged memory space of the PDQ Board showing its 1MB paged memory and 48KB common memory. Memory areas allocated to your application code are highlighted in green, those reserved to the kernel (RTOS) are shown in red. Pages 00-1D of RAM are transparently backed up by "shadow" Flash.

The above figure illustrates the memory map. The processor’s native address space is only 64K, so a paging architecture is used to expand the addressable memory to 1 Mbyte. “Common memory” is accessible from any page, and “paged memory” comprises sixty four 16K pages located at addresses 0x8000 to 0xBFFF on pages 0x00 through 0x3F. The current page is specified by the contents of the processor’s PPAGE register, also called the PAGE_LATCH. As shown in the figure, the top 16K of the memory space is reserved for the common Kernel Flash and used for the RTOS. The bottom 32K of the memory space is common memory that is accessible regardless of the page, and comprises the 1K processor registers, 1K of common EEPROM (384 bytes usable by application), 14K of internal (onchip) common RAM, and 16K of external common RAM. The application program can use 10K of common onchip RAM at 0x0800-0x0FFF and 0x2000-0x3FFF, plus the 16K of common RAM at 0x4000-0x7FFF.

The HCS12 processor chip contains 4 Kbytes of EEPROM at 0x0000-0x0FFF, but fully 3 Kbytes are hidden by higher priority onchip resources (1K of registers at 0x0000-0x3FF and 2K of onchip RAM at 0x0800-0x0FFF). The kernel and RTOS reserves decimal 640 bytes of EEPROM at 0x0400-0x067F. Your application program can store calibration constants and other nonvolatile data in the remaining 384 bytes of available common EEPROM at addresses 0x680 to 0x7FF. EEPROM can be written one to four bytes at a time using Kernel drivers declared in the memory.h file, and the memory EEPROM contents are retained even when power is removed.

The paged memory is located in the 16 Kbyte region at addresses 0x8000-0xBFFF. Pages 0x00 through 0x1D (decimal page 29) are implemented as fast RAM shadowed by Flash. Of these pages, pages 0x00 through 0x13 can be optionally write-protected in two regions: pages 0x00-0F (region 1), and pages 0x10-13 (region 2), so they are ideal for code and non-volatile data. If these pages are not needed for program code, they can be left as write-enabled RAM and used for volatile data storage. Pages 0x14 through 0x1D cannot be write-protected, so they are best used for volatile data storage. The kernel reserves page 0x1D: the top portion from 0x9C00 to 0xBFFF holds system arrays and buffers, and the bottom portion from 0x8000 to 0x9BFF is allocated for code and names definitions that can be used for interactive debugging after a COLD restart. The real time operating system (RTOS) implements a heap memory manager and FORTH_ARRAY operators at pages 0x18–0x1C that make it easy to take advantage of this 80K of contiguous RAM for volatile data storage.

After a COLD restart, the operating system sets DP to 0x8000 and NP to 0x9000 on page 0x1D so that short interactive debugging routines can be compiled in this out of the way location. The COLD restart also initializes an 80K heap to fill pages 0x18 to 0x1C; this heap is useable by either Forth or C.

Forth programmers using the recommended DEFAULT.MAP will compile code (pointed to by dictionary pointer DP) starting at page 0x00, and names (pointed to by names pointer NP) starting at page 0x10. The Forth DEFAULT.MAP function initializes the variable pointer VP to 0x2000, and leaves the heap occupying pages 0x18-1C.

Pages 0x20 through 0x37 provide 384K of onchip Flash inside the HCS12 processor chip that is available for application code and pre-compiled libraries. It is typically used for pre-compiled device driver libraries, graphics images, and other non-volatile data objects, but it can also be used for compiled C application code. Pages 0x38 through 0x3F hold the QED-Forth real-time operating system in write-protected onchip Flash.

To recap, the PDQ Board uses a paged memory system to expand the processor’s native 64 Kbyte address space to 1 Megabyte of addressable memory. The top 16 Kbytes at addresses 0xC000-0xFFFF access the common kernel, and the bottom 32 Kbytes at addresses 0x0000-0x7FFF access the common registers, EEPROM, and common RAM. These common memory areas always visible (i.e., accessible using standard 16-bit addresses) to any code running, no matter where it resides in the memory space. The remaining 16 Kbytes of the address space at addresses 0x8000 to 0xBFFF is duplicated 64 times and addressed through the processor’s 16-bit address bus augmented by a 6-bit page address. Together the address and a padded-out version of the page are held in a 32-bit data type, an xaddress, which is described in more detail in Using Paged Memory below.


Memory allocation

The Mosaic IDE Plus intelligently allocates memory. C source code is compiled into paged memory, and allowed to span across many pages. The PPAGE register is seamlessly managed in the background so that you don't need to worry about it. The only limit is that the code compiled from any one C file cannot be larger than one 16K page. Variables are treated differently, and need to be addressed in common (unpaged) memory. The default memory map is very generous, giving ample space for variables and code.


Kernel versus application memory space

Table 5-1 details the partitioning of the onboard memory between the operating system (the Kernel) and your application functions. Of the 1 MB+ of memory on the PDQ Board, the RTOS/kernel reserves 128K of onchip flash, 4K of common RAM, 8K of paged RAM, and 640 bytes of EEPROM. The remaining memory is available for the application program and its data.

Partition of Flash and RAM among Kernel (RTOS) and Application Functions
Function Size Memory Page Memory Address Physical Location
Kernel RAM (12K)
Kernel stacks, buffers, task area 4K common 1000 – 1FFF HCS12 Processor Chip
Kernel hash array, buffers 8K 1D A000 – BFFF PDQ Board RAM
Kernel EEPROM (640 bytes)
Kernel vectors and structures 640 b common 0400 – 067F HCS12 Processor Chip
Processor Registers (1K)
Kernel/HCS12 Hardware Registers 1K common 0000 – 03FF HCS12 Processor Chip
Kernel Flash (128K)
Common Kernel Code 16K common C000 – FFFF HCS12 Processor Chip
Kernel Code 112K 38 – 3E 8000 – BFFF HCS12 Processor Chip
Application RAM (26K)
Application data and task areas8 2K common 0800 – 0FFF HCS12 Processor Chip
Application data and task areas 8K common 2000 – 3FFF HCS12 Processor Chip
Application data 16K common 4000 – 7FFF PDQ Board RAM
Application Non-Write-Protectable Shadowed RAM (144K)
Driver library RAM9 and/or
Heap area for FORTH_ARRAYs
144K 14 – 1C 8000 – BFFF PDQ Board RAM backed by PDQ Board Flash
Application paged RAM or Default
Forth DP & NP after COLD restart
8K 1D 8000 – 9FFF PDQ Board RAM
Application Write-Protectable Shadowed RAM (320K)
Application code and data       
(Write protect region 1 = pages 00–0F)
(Write protect region 2 = pages 10–13)
320K 00 – 13 8000 – BFFF PDQ Board RAM backed by PDQ Board Flash
Application EEPROM (384 bytes)
EEPROM Variables 384 b common 0680 – 07FF HCS12 Processor Chip
Application Flash (384K)
Application code, device drivers 384K 20 – 37 8000 – BFFF HCS12 Processor Chip
Shadow Flash (480K)
Transparently backs-up RAM 480K 00 – 1D 8000 – BFFF 512K onboard Flash chip
  1. All pages and addresses are hexadecimal numbers; all numbers in the size column are decimal. 1K=1024 bytes.
  2. The unused page 0x1E is unpopulated and not uniquely decoded; application programs must not write to it.
  3. Page 0x1F is reserved for address-mapped logic including Wildcard I/O. Application programs should not directly access it; rather, the built-in device drivers in the kernel access on-board address-mapped hardware.
  4. The top 8K on page 0x1D is reserved for kernel use. C programs may use the bottom 8K on page 1D at addresses 0x8000-9FFF if there is no need to access the QED-Forth interactive debugging functions located there.
  5. Application programs may reside in Write-protectable Flash-shadowed RAM at pages 0x00-0F and 0x10-13, corresponding to write protect regions 1 and 2 respectively. Non-write-protected shadowed RAM may be used for paged storage of data by C or Forth programs. To use the “write protect” feature, see the glossary entries for WRITE.PROTECT, WRITE.ENABLE, WP.ALL, and WE.ALL in the Interactive Debugging section of the Glossary.
  6. To use the “shadow” feature, see the glossary entries for STORE.PAGES, LOAD.PAGES.AT.STARTUP, SAVE.ALL and RESTORE.ALL in the Interactive Debugging section of the C Glossary.
  7. Task areas should be preferentially located in onchip RAM; the C compiler performs this allocation automatically in Mosaic IDE Plus revisions 1500+.
  8. Starting with Mosaic IDE Plus revision 1525, the common RAM region at 0x800-0xFFF is used for the EXTRA_TASK macro, and is used internally by the Ether/Wifi Wildcard driver in Ether_C_Task_Setup() and WIFI_C_TASK_SETUP().
  9. Some driver software libraries for external hardware use specific RAM pages as buffer space.
    The Compact Flash Wildcard and USB-Drive Wildcard use page 0x17. The Ether/WiFi Wildcards use the bottom half of page 0x16. INIT_DEFAULT_HEAP() places the Forth heap (for Forth arrays) in pages 0x18–0x1C. The _flashconfig nonvolatile storage region for the SAVE_…_ARRAY() macros is located on page 0x14.

Common memory

The common memory which is accessible regardless of the page is also partitioned between the operating system and application program. The following table presents a summary of the common memory addresses used by the operating system, and in bold type those addresses available to the application program.

Partition of the Common Memory
Address Size (bytes) Type Function
C000 – FFFF16K Onchip Flash Common Kernel – code
4000 – 7FFF 16K Board RAMApplication – Variables*
2000 – 3FFF8K Onchip RAMApplication – Variables, buffers, task areas
1000 – 1FFF 4KOnchip RAM Kernel – Variables, buffers, Forth task area, stacks
0800 – 0FFF2K OnchipRAMApplication – one task area declared with EXTRA_TASK
0680 – 07FF384 bytesEEPROMApplication – Nonvolatile data storage
0400 – 067F640 bytesEEPROMKernel – Interrupt vectors, save/restore values, segment management
0000 – 03FF1KRegisters Kernel – Processor control registers
* Highlighted entries indicate memory available for application programs.

Referring to Table 5-2, there are four unencumbered common memory areas totaling 26 Kbytes of RAM and 384 bytes of EEPROM that your application can use. The C compiler automatically allocates TASK areas, buffers, C arrays and variables in the 24K of common RAM above 0x2000, and you can designate one task as EXTRA_TASK (instead of TASK) in Mosaic IDE Plus revisions greater than 1500 to place it in the 2K of common RAM starting at 0x800. You may also define EEPROM variables that are allocated to the user-available EEPROM area as explained later in this Chapter.

Forth programmers typically start their program with the DEFAULT.MAP declaration that initializes the VP (variable pointer) at 0x2000 to take advantage of the common RAM, and the EEP (EEPROM pointer) at 0x0680 to take advantage of available EEPROM.


Available common memory areas

0x0680 – 0x07FF: The processor’s available on-chip EEPROM (Electrically Erasable Programmable Read Only Memory) is located at 0x04000x07FF. Locations 0x04000x067F are reserved by the operating system for use by the interrupt vectors, SAVE and RESTORE utilities, and for segment management data structures. EEPROM at 0x06800x07FF is available to your programs. The pre-coded Kernel functions StoreEEChar, StoreEEInt, StoreEELong, StoreEEFloat, and ToEEPROM declared in the memory.h header file can store data into the EEPROM. Fetching data from EEPROM uses standard read cycles and does not require the use of special functions.

0x0800 – 0x0FFF and 0x2000 – 0x3FFF: The processor’s 14K of onchip RAM extends from 0x0800 to 0x3FFF, and the kernel reserves a 4K block at 0x1000. The remaining 10K of onchip RAM available for the application program comprises the 2K block at 0x0800-0FFF and the 8K block at 0x2000-0x3FFF. This onchip RAM is ideal for task areas, program-implemented stacks, buffers, arrays, and variables. Task areas as declared by the TASK typedef (see the USER.h file for its definition) are preferentially allocated by the C compiler in onchip RAM to optimize the timing of stack operations.

Note that the 8K block of onchip RAM at 0x2000-0x3FFF is contiguous with the following 16K block of off-chip common RAM, resulting in a 24K block of contiguous common RAM available for your application program.

0x4000 – 0x7FFF: These 16K bytes of common RAM are also available for run-time variables, buffers and arrays. They are useable but not ideal (because of slight timing differences in HCS12 stack push/pull instructions) for implementing TASK areas and stacks.

The remainder of the common memory area is used by either the processor or the kernel/RTOS. The processor’s 1K register block is located at 0x00000x03FF, the kernel reserves EEPROM at 0x400-0x067F, and the operating system reserves common RAM at 0x1000-1FFF for user areas, buffers, and stacks.


Paged memory overview

The PDQ Board uses a paged memory system to expand the processor’s native 64 Kbyte address space to 1 Megabyte of addressable memory. The 16 Kbyte page window at addresses 0x8000 to 0xBFFF is duplicated 64 times and addressed through the processor’s 16-bit address bus augmented by a 6-bit page address. Although 6 bits are sufficient to address the 64 possible pages in the HCS12 architecture, the page is padded out to a more standard 16-bit date type so that the full address, lower 16 bits plus 16-bit page, occupies 32 bits. We’ll refer to this full address as an xaddress (32-bit extended addresses).

Implementation details
The page (padded out to 16 bits) occupies the most significant cell of the xaddress, and the native 16-bit address occupies the least significant cell of the xaddress. When an xaddress is stored in memory, the 16-bit padded out page is stored in the two numerically lower memory locations, followed by the 16-bit native address in the next two memory locations. This is because Motorola processors use the big endian data storage paradigm, meaning that the most significant data is stored in low memory. When an xaddress is placed on a stack which grows downward in memory (i.e., grows toward numerically lower addresses), the page (most significant data in the xaddress) is the first accessible cell on the stack, and the native address is the next accessible stack cell in higher memory.

A subroutine on any page can fetch or store to any address on the same page or in the common memory, or transfer control to another routine in common memory. A routine in paged memory “sees” a 64K address space comprising its own page window at addresses 0x8000 to 0xBFFF, with the common memory filling the rest of the address space. To access data stored on another page, special memory access routines located in the common Kernel Flash are used to change the page, fetch or store the data, restore the page, and return. These routines are declared in the memory.h header file, and include functions such as FetchChar, FetchInt, FetchLong, FetchFloat, StoreChar, StoreInt, StoreLong, and StoreFloat. To move blocks of data from one location to another in paged or common RAM, use the CMoveMany, CmoveManyCheck, or ToMemory routines. To store large amounts of data in paged RAM, use FORTH_ARRAYs declared in the array.h header file as described in Storing and Accessing Data in Paged RAM and Flash.

The operating system automatically handles function calls and returns among the pages in both the C and Forth languages. There is very little speed penalty associated with changing pages. The C compiler is configured to use the HCS12’s page-aware CALL and RTC assembly instructions for function invocation, so that functions can be called from anywhere in the paged or common memory space. For its part, the QED-Forth compiler is inherently page aware and compiles page-smart function calls wherever they are required.

See also →

This page is about: Using 9S12 HCS12 Memory Map, Using FLASH RAM & EEPROM Memory with RTOS – The available memory (Flash, RAM, and EEPROM) of the 9S12 HCS12 MCU is partitioned into common and paged addresses for access by a GNU C compiler and C language programs. address space, volatile memory, nonvolatile memory, paged memory, onchip memory, shadow flash, pre-compiled device driver libraries, graphics images, heap