Link here

4: Additional Information for Advanced users

Paged memory, common memory, and GCC's view of memory

The Freescale 9S12 (HCS12) processors used on the PDQ line of Mosaic controllers use a paged memory architecture. Memory at physical addresses 0x8000 through 0xBFFF is accessed in conjunction with a page that can range from 0x00 through 0x3F, for a total of 1 megabyte of paged memory. The remaining memory at 0x0000 through 0x7FFF, and 0xC000 through 0xFFFF, is "common memory" that is accessible regardless of the current page. Thus, to fully specify a location in the processor’s paged memory space, a 24-bit (or equivalently, a 32-bit) extended address ("xaddress") must be specified.

The version of the GNU C compiler (GCC) used with the HCS12 processor has a significant limitation in how it deals with memory: all pointers in this GCC C environment are 16 bits. This means that an assignment statement or string reference that is on a given page cannot directly reference data that is on another page. The Mosaic IDE Plus includes features that enable access to all memory locations from within the C environment. Understanding how 16-bit and 32-bit pointers are handled in the IDE Plus will clarify the code design strategies that deliver optimal performance.


Managing memory in C

Memory management is one of the more challenging aspects of embedded design, but the default templates provided with the Codeblocks-based IDE (integrated development environment) simplify the task. The Mosaic IDE Plus template for each product provides a versatile working default memory map so you don’t have to worry about the details. As we release new products, we will provide Mosaic IDE Plus project templates for them.

This document does not provide a memory map as it may vary among products. For a full explanation of the memory map and the types of memory available on each hardware platform, see Using Paged Memory.

As described in the prior section, memory is either paged or common. All code is located in paged memory, typically implemented as RAM that is backed up by non-volatile flash memory. Every time the board powers up, the code stored in the flash memory is copied to the fast paged RAM where it is available for execution. This mimics the way the executable code stored on your PC’s hard drive is copied to system RAM for execution. Additional dedicated fast paged flash memory is present in the processor chip itself; this memory holds the operating system kernel as well as pre-compiled device drivers, graphics, and other resources.

Variables are typically located in common RAM. Paged RAM is also available to hold buffers and a heap. Some non-volatile EEPROM (Electrically Eraseable Programmable Read Only Memory) memory is also available, providing a convenient place to store calibration constants and other values that rarely change.

The GCC tools treat different parts of a C program as being in various sections. Although there are many sections used for debugging and internal linking, there are three primary sections: .data, .rodata, and .text. The .data section is where regular global variables are stored in common RAM. The .rodata section is also located in common RAM, but contains read-only data including const strings; these are automatically initialized each time the program restarts. The .text section contains the executable machine code instructions of the program. Projects larger than 1 page have their .text sections from all input objects spread into the many available pages, and these subsections are given names such as .text.bank1, .text.bank2, etc., where each bank corresponds to a page.

When initialized variables are created, the linking process makes a copy of them in the program ROM space that is re-imaged onto the RAM at startup to perform the required runtime initialization. Sometimes though, it is desirable to have the initialized data objects be placed directly in ROM with your code to conserve common RAM. See 3: Coding Your Application for more information about choosing where objects go in memory.


Function call details

Functions that are located on different pages can call one another; this is fully supported in the HCS12 hardware and assembly code. GCC is aware of this and will compile the proper inter-page assembly code call. When a function is invoked from code that is on a different page, the compiler generates a full 24 bit paged address call instruction rather than the 16 bit jsr (jump to subroutine) instruction. This is also called a far call.

Taking a pointer to a function works properly even though pointers in GCC are 16 bits and functions are stored in paged memory. GCC automatically creates a trampoline function in common memory for every function to which a pointer is taken. The pointer returned is actually that of the trampoline function, which is a little function in common RAM that calls the real function in paged memory. Since the trampolines are in common RAM, code on any page can safely use the 16 bit pointer to them. At program startup, the RAM is automatically initialized with an image of all initialized variables and auto-generated trampolines. Thus standard C syntax can be used to invoke functions via a function pointer. This is described in the Coding Your Application Chapter.


Variable details

Variables are allocated in the linker section called .data, which is placed into common RAM on the controller. Because of this, pointers can freely be used with variables in the usual way. It is possible to store variables in paged memory using directives described in the following section. In such cases, special rules apply to pointers.


Variables in paged memory

Storing variables in Paged RAM is accomplished by the functions StoreInt and FetchInt. Please open the "Paged Ram Demo" from the Mosaic IDE Plus so that you can follow along:

Open a new "Paged Ram Demo" project for a downloadable version of this code.

Look for this icon under Project→ New Project:
Gui Development Example
Paged Ram Demo

The first step to storing variables in RAM is selecting a good address. Start by looking at the table in Making Effective Use of Memory chapter of the PDQ Board Users Guide. From this table we can see that pages 14 - 1C are marked as "Application paged RAM and/or Heap area for FORTH_ARRAYs". This demo saves variables on page 14 using the following declaration:

// Paged RAM memory at:   page 14, address 8000
#define PAGED_RAM_XADDR 0x148000

Now that we have chosen an appropriate address, we need to save some values. The following line runs 10 times inside a loop where i is the iterator:

      // store to the start address, plus the offset
      store_at_address = PAGED_RAM_XADDR + i*sizeof(int);

      // store to a paged ram address
      StoreInt( value, store_at_address );

Fetching memory is as simple as executing the following line:

tmp = FetchInt(  PAGED_RAM_XADDR + i*sizeof(int) );

And that's all it takes to save variables to paged RAM!


The directory tree

The Mosaic IDE Plus is an amalgam of several open source projects plus additional glue scripts and utilities written by Mosaic Industries. The IDE directory structure, described below, is rooted by default at C:\MosaicPlus. Here’s a high level view of each directory present in C:\MosaicPlus.



This is the default directory in which new projects are created. By default a new subdirectory is created for each project.



This top level directory holds all files related to C development.



This top level directory holds all files related to forth development. The directory structure is a mirror of the C folder for simplicity.



For Mosaic IDE Plus revisions later than 1300 that were installed from CD, this folder contains PDF documentation for offline viewing (if the installer was downloaded from the web, PDF documentation will not be installed). For earlier Mosaic IDE Plus revisions, this folder holds an offline copy of this wiki which can be used to view all the documentation of the PDQ Board Users Guide and Mosaic IDE Plus through a web server started on your computer for the purpose.



Contains *.A library files which GCC links against for Wildcard drivers and other libraries. Whenever you #include a library’s header file, instructions within the header file automatically cause the inclusion of the appropriate driver’s object(s) from the driver library and the firmware install files from the firmware directory.



Contains *.H files which may be included for using Wildcards or other libraries.



Contains *.H Mosaic header files which allow access to all kernel functions. These files provide the exact C syntax for each function, and can be viewed to refresh your memory. To gain access to all functions declared in .H files in this folder, ensure all source code files contain #include <mosaic\allqed.h>.



Most subdirectories under this folder contain a *.s file for the relevant library, containing assembly code wrappers for each firmware library routune. Some subdirectories contain .c files with C source code implementing library routines.



Holds *.CIN and *.QCIN files which contain precompiled firmware in S19 format for most libraries. A .CIN file is inserted into the .DLF file for each precompiled library you are using.



All C demos are stored here, and are accessible via the Project→ New Project menu. Each demo has files of these types: .C and .TEMPLATE. A demo may also have a .PNG icon file in addition, or other resource files (see the websocket-basic-io folder for an example.)



Contains the GCC 68hc12 compiler and related files. Note the config subdirectory which holds the PDQ Board memory map and Makefiles, and the m6811-elf subdirectory which holds C Standard Library header and library files.



Contains *.FIN and *.QFIN files which contain a S19 record for each precompiled library. Each Forth demo which requires a library loads a .FIN file from this directory via the demo_loader.4TH file.



Each sub folder contains a Forth demo program. Note that all the _loader.4th files are very similar. You should copy the format of this loader file if you are making your own Forth project.



This directory is where the executable of the image converter utility is stored. The image converter can be launched from Start→ Programs→ Mosaic Plus→ Mosaic Image Converter or from Tools→ Mosaic Image Converter from inside the Mosaic IDE Plus. See the Help→ Help menu from inside the Image Converter for more information.



The Mosaic Terminal program executable is stored in this directory. It can be launched using the Start→ Programs→ Mosaic Plus→ Mosaic Terminal shortcut or from Tools→ Mosaic Terminal from inside the Mosaic IDE Plus. The Mosaic Terminal allows you to interact with and download code to the Mosaic controller.



This directory is where the MSYS environment files are stored. MSYS provides an emulated UNIX environment to manage the C application build process.


Intermediate files produced during a build

Many files are produced when an application is built. For a description of these files, see c-language-file-naming-conventions.


Further reading

This page is about: Paged Memory, Common Memory, GCC Handling of Memory, C Function Calls, Locating Variables in Paged Memory, Intermediate Files Created during Build Process, Compiling Programs to Run on 9S12 (HCS12) Microcontroller – Describes paged memory, common memory, GCC handling of memory, function calls, locating variables in paged memory, and intermediate files created during the build process when compiling programs to run on the 9S12 (HCS12) microcontroller.