Link here

Loading Your Program Into Memory

How to use flash-backed RAM, write protect your memory, and autostart your program.

This chapter describes:

  • How to use the flash-backed shadowed RAM memory;
  • How to write protect RAM so that it cannot be corrupted; and,
  • How to configure your program to autostart so that it runs each time the board turns on.

Understanding these issues will enable you to write fast, responsive programs to control your instrument using the PDQ Single Board Computer (SBC).

 

The default memory map uses flash-backed (shadowed) RAM

The default starting location for both C and Forth program code is the beginning of page 0 of shadowed RAM, starting at address 0x8000 on page 0. The C compiler locates the top level main program at this starting address, then compiles other application code on the remainder of page 0 and on subsequent pages of flash-shadowed RAM. For Forth programmers, the recommended DEFAULT.MAP function invoked at the start of the Forth source code sets up a similar memory map as the source code is compiled by the QED-Forth interpreter/compiler.

The Mosaic IDE Plus™ (Integrated Development Environment) does most of the work for you in configuring your C-language application program to load properly under the QED-Forth operating system. The Mosaic IDE Plus generates a .dlf download file that contains a RECEIVE.HEX command followed by an “S-record” image of the compiled program to the PDQ Board, followed by some additional operating system function calls that manage the “shadow” feature of the flash-backed RAM. The S-record encodes program data and target address and page information, plus checksums to facilitate error checking. The RECEIVE.HEX command accepts the S-record and locates its data at the specified xaddresses in the PDQ Board’s memory space. RECEIVE.HEX is smart enough to deduce the type of target memory based on the specified memory pages, and performs the storage accordingly. If the target is in shadowed RAM, the data is stored in RAM (but note that it is not saved to the backup shadow Flash chip by RECEIVE.HEX). If the target is in the Freescale 9S12 (HCS12) microcontroller's onchip Flash, it is stored there via transparent calls to the Kernel’s ToFlash() function. The download file contains commands that back up the received code to the shadow flash, and provide for it to be restored to RAM on subsequent restarts.

As detailed below, you can optionally write protect the RAM that contains the compiled code for enhanced reliability, and you can set an autostart vector that causes the top level program to run every time the PDQ Board resets. You can accomplish these feats by typing commands to the PDQ Board from the terminal, or by clicking Project →  Project compiler options, and to specifying the features you want in the "Embedded Settings" tab.

Let’s trace the activities stimulated by compiling a C program using the Mosaic IDE Plus; we’ll assume that the code is targeted to the default location in shadowed RAM on the PDQ Board. The Make process generates a .dlf download file, and we invoke the Terminal (via Tools →  Mosaic Terminal) to send the file to the PDQ Board. After the RECEIVE.HEX command in the .dlf file stores the image as specified in the S-record in paged RAM, the following command in the .dlf file is executed:

SAVE.ALL

which is equivalent to:

0 0x18 STORE.PAGES
0 0x18 1 LOAD.PAGES.AT.STARTUP
SAVE

This STORE.PAGES command (which is invoked by SAVE.ALL) tells the operating system to start at page 0 and store twenty four RAM pages (that is, pages 0x00 through 0x17) to shadow Flash. This command invokes the lower level operating system function called TO.XFLASH (called ToXFlash() in C) which performs the write from RAM into the shadow external Flash chip.

The LOAD.PAGES.AT.STARTUP command (which is also invoked by SAVE.ALL) tells the operating system to restore the RAM contents of pages 0 through 0x17 (using area identifier 1) from shadow Flash upon each reset or restart. To undo the effect of a LOAD.PAGES.AT.STARTUP command, simply execute UNSAVE.ALL. Alternatively, call the LOAD.PAGES.AT.STARTUP function with a valid starting page, setting the specified number of pages equal to zero, and passing in the area ID that you want to undo.

The SAVE command (which is also invoked by SAVE.ALL) saves the current memory map parameters in EEPROM; a corresponding RESTORE or RESTORE.ALL command will restore the machine to the saved state. Executing RESTORE reverts to the SAVEd memory map pointers, while executing RESTORE.ALL immediately reads the saved shadow Flash contents into RAM, and also restores the memory map pointers. The RESTORE.ALL command is equivalent to:

0 0x18 LOAD.PAGES
RESTORE

Complete definitions of these functions can be found in the "Interactive Debugger Glossary" section of the PDQ C Glossary document. Definitions and function prototypes of the corresponding C-callable functions can be found in the main section of the PDQ C Glossary. C-callable versions of many of the shadow Flash management functions are also available if you want to invoke them from within your C program. The function prototypes are documented in the C:\MosaicPlus\c\libraries\include\mosaic directory in the MEMORY.h and OPSYSTEM.h files:

extern int   StorePages          (int basePage, int numPages);
extern void  LoadPagesAtStartup  (int start_page, int num_pages, int area_id);
 

Write protecting the paged RAM

Keeping your compiled application code in Flash-shadowed paged RAM ensures that the contents are not lost when power is removed, but we also want the code to be safe from “errant writes” that can occur when a program crashes or invokes buggy routines. This is accomplished by “write protecting” the RAM so that it cannot be modified after it is loaded. “Write enabling” simply means undoing the protection so that the RAM can be written to. You can use the dialog box found in Build →  Global compiler options to specify write protection of the downloaded code in the PDQ Board. This section describes the operating system functions that write protect and write enable the paged RAM.

There are two write protection “regions”. Region 1 comprises the sixteen pages from 0x00 through 0x0F, and region 2 comprises the eight pages from 0x10 through 0x13. Each region can be independently write protected or write enabled. The write protection functions are typically typed interactively at the terminal, although C-callable versions are available if you want to invoke them from your program. As usual for Forth commands, the input parameter is typed before the function name, and spaces separate all the entries on the command line. To write protect pages 0x00 through 0x13, you could type at the terminal prompt:

1 WRITE.PROTECT
2 WRITE.PROTECT

or, equivalently, you could execute the single short-hand Forth command:

WP.ALL

which write protects pages 0x00 through 0x13, inclusive.

Now, even if you try to overwrite the contents of pages 0x00-0x0F (region 1) or 0x10-0x13 (region 2), the original contents will remain until the write protection is removed. The LOAD.PAGES and LOAD.PAGES.AT.STARTUP functions mentioned in the prior section are smart enough to note the write protection status, write enable the RAM before restoring the RAM contents from shadow Flash, and restore the write protection status of the RAM when the processor is powered up or restarted.

To undo the write protection, simply execute the commands

1 WRITE.ENABLE
2 WRITE.ENABLE

or, equivalently, you could execute the single short-hand command:

WE.ALL

which write enables pages 0x00 through 0x13, inclusive.

C-callable versions of the two fundamental write protection configuration commands are also declared in the C:\MosaicPlus\c\libraries\include\mosaic directory in the OPSYSTEM.h files, with function prototypes:

extern void  __attribute__((far)) WriteProtect        (int ram_region_id);
extern void  __attribute__((far)) WriteEnable         (int ram_region_id);

The relevant functions are documented in the PDQ C Function Glossary (A-H) in the main glossary section and in the interactive debugger glossary section.

 

Autostarting your application

You can configure QED-Forth to automatically execute a specified application program after every reset, restart, and error-induced ABORT. This makes it easy to design a production instrument based on the PDQ Board; the instrument will automatically perform its required function when it is turned on or reset. The "Embedded Settings" tab, found under Build →  Global compiler options, lets you specify the setting of the autostart vector, or you can follow the instructions in this section to accomplish the same thing.

QED-Forth provides two functions named AUTOSTART: and PRIORITY.AUTOSTART: that allow you to specify a startup routine. Both write a pattern in memory that instructs QED-Forth to execute a user-specified program. AUTOSTART: stores the pattern at the top of page 0x37 in onchip Flash inside the HCS12 processor chip, and PRIORITY.AUTOSTART: stores the pattern near the top of page 0x0F in both RAM and the shadow Flash memory. The choice of which version to use depends upon where you are locating your program code. The recommended area for compiled code is on pages 0x00-0x0F in write-protectable shadowed RAM; use of the PRIORITY.AUTOSTART: routine locates the autostart information in this same memory region. If you prefer to instruct the compiler to load code into onchip Flash, then the AUTOSTART: routine makes sense, as it locates the vector in onchip Flash.

Be sure to include the Autostart vector in your download image
To go into production, make sure that the locations containing the startup vector (the top 6 bytes of page 0x0F for PRIORITY.AUTOSTART: or the top 6 bytes of page 0x37 for AUTOSTART:) are included in the image that is loaded into production boards. The convenient utility function DUMP.AUTOSTARTS can help you to accomplish this; see its entry in the Interactive Debugger Glossary.

Let’s assume that you want to want to run the top level main routine every time you turn on, reset, or restart the PDQ Board. The following command:

AUTOSTART: main↓

writes a pattern into onchip Flash at addresses 0xBFFA-BFFF on page 0x37 comprising a 16-bit flag (equal to 0x1357) followed by the 32-bit extended code field address (xcfa) of the specified startup program. All subsequent resets and restarts will call the specified application program after QED-Forth initializes the system.

To specify the startup vector so that it can eventually reside in write-protectable shadowed RAM, we would execute a different command:

PRIORITY.AUTOSTART: main↓

which writes a pattern starting at 0xBFFA on page 0x0F comprising a 16-bit flag (equal to 0x1357) followed by the 32-bit xcfa of the specified startup program. All subsequent resets and restarts will call the specified application program after QED-Forth initializes the system.

The priority autostart and autostart locations are checked each time QED-Forth executes ABORT, which is called after every reset, COLD or WARM restart, or error. ABORT first checks the priority autostart location at 0xBFFA\37, and if 0x1357 is stored there it executes the program whose xcfa is stored in the next four bytes. If the priority autostart pattern is not present, or if the specified priority startup program finishes executing and “returns”, ABORT then checks the autostart pattern at 0xBFFA\0F. If 0x1357 is stored there it executes the program whose 32-bit xcfa is stored in the next four bytes starting at 0xBFFC\0F.

To remove the autostart pattern or patterns, execute:

NO.AUTOSTART↓

This command clears all of the startup patterns in onchip flash, RAM and shadow flash.

 

Program loading and memory configuration summary

It is easy to invoke functions that automatically restore your program from shadow flash into the paged RAM at startup, to write protect your code so it can’t be corrupted by a processor crash, and to configure the PDQ Board to automatically run your top level program each time the controller is powered up or restarted. The following functions are callable from Forth (either interactively from the terminal or from a compiled Forth program), and most are callable from your compiled C program:

Interactive (Forth) Functions C Functions
STORE.PAGES StorePages()
LOAD.PAGES LoadPages()
LOAD.PAGES.AT.STARTUP LoadPagesAtStartup()
SAVE
SAVE.ALL
RESTORE
RESTORE.ALL
WRITE.PROTECT
WP.ALL
WriteProtect()
WRITE.ENABLE
WE.ALL
WriteEnable()
PRIORITY.AUTOSTART:
AUTOSTART:
IS.AUTOSTART IsAutostart()
IS.PRIORITY.AUTOSTART IsPriorityAutostart()
NO.AUTOSTART NoAutostart()

The following table presents a brief summary of these functions and their uses, including including examples of C syntax and Forth syntax and comments. Don’t forget to type spaces between the parameters and before and after function names when typing Forth commands. Consult the C Glossary for detailed descriptions of the functions. The Forth function descriptions can be found in the Interactive Debugger section of the C Glossary, and the C function descriptions are located in the main section of the C Glossary.

For a complete listing of operating system configuration commands, browse through the entire Interactive Debugger Glossary, or equivalently, see the functions listed in the Operating System category of the Forth Glossary.

Shadow Flash, Write Protection, and Autostarting Configuration Functions
Forth Function Name
C Function Name
Example of use and comments
Store from RAM to Shadow Flash now:
STORE.PAGES
StorePages()
Interactive Forth: 0 0x18 STORE.PAGES
Compiled C: StorePages( 0, 0x18);

Moves the contents of 0x18 pages starting at page 0 from RAM to shadow flash. Returns –1 flag if successful. ee also SAVE.ALL
Load from RAM to shadow Flash now:
LOAD.PAGES
LoadPages()
Interactive Forth: 0 0x18 LOAD.PAGES
Compiled C: LoadPages( 0, 0x18);

Moves the contents of 0x18 pages starting at page 0 from shadow flash to RAM. Works even if the RAM is write-protected. See also RESTORE.ALL
Load from RAM to shadow Flash at each power up or restart:
LOAD.PAGES.AT.STARTUP
LoadPagesAtStartup()
Interactive Forth: 0 0x18 1 LOAD.PAGES.AT.STARTUP
Compiled C: LoadPagesAtStartup( 0, 0x18, 1);

Defines restoration behavior at each subsequent reset or COLD restart for area ID 1: Moves the contents of 0x18 pages starting at page 0 from shadow flash to RAM. Works even if the RAM is write-protected. See also SAVE.ALL
Save and restore a set of memory map pointers:
SAVE Interactive Forth: SAVE

Saves the operating system memory pointers in reserved eeprom. See also SAVE.ALL
RESTORE Interactive Forth: RESTORE

Restores the memory pointers to values they had when SAVE was executed. See also RESTORE.ALL
Store from RAM to shadow Flash now, load from RAM to shadow Flash at each power up or restart, and save the memory map pointers:
SAVE.ALL Interactive Forth: SAVE.ALL

Invokes STORE.PAGES, LOAD.PAGES.AT.STARTUP, and SAVE to back up pages 0x00 through 0x17 inclusive to the shadow Flash, and automatically causes the RAM contents and memory map to be restored upon each power-up or COLD restart. Returns flag =-1 if successful.
Restore from shadow Flash to RAM now, and restore to the memory map pointers:
RESTORE.ALL Interactive Forth: RESTORE.ALL

Invokes LOAD.PAGES to restore RAM pages 0x00 - 0x17 from shadow Flash, and calls RESTORE to revert to the memory map that existed when SAVE or SAVE.ALL was called.
Write protect or write enable paged RAM:
WRITE.PROTECT
WriteProtect()
Interactive Forth: 1 WRITE.PROTET
Compiled C: WriteProtect(1);

Disallows writes to RAM pages 0x00-0x0F (WP region 1). Passing a 2 disallows writes to pages 0x10-13 (region 2).
WP.ALL Interactive Forth: WP.ALL

Disallows writes to RAM pages 0x00-0x13 (WP regions 1 and 2).
WRITE.ENABLE
WriteEnable()
Interactive Forth: 1 WRITE.ENABLE
Compiled C: WriteEnable( 1);

Allows writes to RAM pages 0x00-0x0F (WP region 1). Ppassing a 2 allows writes to pages 0x10-13 (region 2).
WE.ALL Interactive Forth: WE.ALL

Allows writes to RAM pages 0x00-0x13 (WP regions 1 and 2).
Automatically run a specified program at each power up or restart:
PRIORITY.AUTOSTART: Interactive Forth: PRIORITY.AUTOSTART: main

Automatically runs main (execution address 0x8000 on page 0) on each subsequent power up, restart, or abort. The autostart vector is stored at 7FFA-7FFF on page 0x0F.
IS.PRIORITY.AUTOSTART
IsPriorityAutostart()
Interactive Forth: CFA.FOR main IS.PRIORITY.AUTOSTART
Compiled C: IsPriorityAutostart( main );

Automatically runs main (execution address 0x8000 on page 0) on each subsequent power up, restart, or abort. The autostart vector is stored at 7FFA-7FFF on page 0x0F.
AUTOSTART: Interactive Forth: AUTOSTART: main

Automatically runs main (execution address 0x8000 on page 0) on each subsequent power up, restart, or abort. The autostart vector is stored at 7FFA-7FFF on page 0x37.
IS.AUTOSTART
IsAutostart()
Interactive Forth: CFA.FOR main IS.AUTOSTART
Compiled C: IsAutostart( main );

Automatically runs main (execution address 0x8000 on page 0) on each subsequent power up, restart, or abort. The autostart vector is stored at 7FFA-7FFF on page 0x37.
NO.AUTOSTART
NoAutostart()
Interactive Forth: NO.AUTOSTART
Compiled C: NoAutostart( );

Erases the priority autostart vectors at 7FFA-7FFF on page 0x0F RAM and shadow flash and erases the autostart vector at 7FFA-7FFF on page 0x37.



See also → Storing and Accessing Data in Paged RAM and Flash

 
 
 
Navigation
 
Registration on or use of this site constitutes acceptance of our User Agreement and Privacy Policy. Purchase of Mosaic's products constitutes acceptance of the End User License Agreement, Sales Terms and Conditions, and Life Support policy. Mosaic’s products are not authorized for use as components in life support or medical devices. The material on this site may not be reproduced, distributed, transmitted, cached or otherwise used, except with the prior written permission of Mosaic Industries, Inc. Mosaic and other product names are trademarked and should be capitalized when reproduced. You are encouraged to link to pages of this site.

© Mosaic Industries, Inc. All rights reserved.