<< Previous | Index | Next >>

17. Hints and Tips

This chapter offers hints on how to speed up an application and how to store persistent data at run time.

17.1 Efficiency

There are a number of methods that can be used to reduce the size of a program, or to increase its speed. Let's look at the events that occur when a program enters a function.

The last two consume significant execution time and are eliminated when stack checking is disabled or if the debug mode is off.

17.1.1 Nodebug Keyword

When the PC is connected to a target controller with Dynamic C running, the normal code and debugging features are enabled. Dynamic C places an RST 28H instruction at the beginning of each C statement to provide locations for breakpoints. This allows the programmer to single step through the program or to set breakpoints. (It is possible to single step through assembly code at any time.) During debugging there is additional overhead for entry and exit bookkeeping, and for checking array bounds, stack corruption, and pointer stores. These "jumps" to the debugger consume one byte of code space and also require execution time for each statement.

At some point, the Dynamic C program will be debugged and can run on the target controller without the Dynamic C debugger. This saves on overhead when the program is executing. The nodebug keyword is used in the function declaration to remove the extra debugging instructions and checks.


nodebug int myfunc( int x, int z ){
...
}

If programs are executing on the target controller with the debugging instructions present, but without Dynamic C attached, the function that handles RST 28H instructions will be replaced by a simple ret instruction. The target controller will work, but its performance will not be as good as when the nodebug keyword is used.

If the nodebug option is used for the main function, the program will begin to execute as soon as it finishes compiling (as long as the program is not compiling to a file).

Use the directive #nodebug anywhere within the program to enable nodebug for all statements following the directive. The #debug directive has the opposite effect.

Assembly code blocks are nodebug by default, even when they occur inside C functions that are marked debug, therefore using the nodebug keyword with the #asm directive is usually unnecessary.

17.1.2 Static Variables

Using static variables with nodebug functions will greatly increase the program speed. Stack checking is disabled by default.

When there are more than 128 bytes of auto variables declared in a function, the first 128 bytes are more easily accessed than later declarations because of the limited 8-bit range of IX and SP register addressing. This makes performance slower for bytes above 128.

The shared and the protected keywords in data declarations cause slower fetches and stores, except for one-byte items and some two-byte items.

17.2 Run-time Storage of Data

Data that will never change in a program can be put in flash by initializing it in the declarations. The compiler will put this data in flash. See the description of the const, xdata, and xstring keywords for more information.

If data must be stored at run-time and persist between power cycles, there are several ways to do this using Dynamic C functions:

17.2.1 User Block

The User block is an area near the top of flash reserved for run-time storage of persistent data and calibration constants. The size of the User block can be read in the global structure member SysIDBlock.userBlockSize. The functions readUserBlock() and writeUserBlock() are used to access the User block. These function take an offset into the block as a parameter. The highest offset available to the user in the User block will be


SysIDBlock.userBlockSize-1 

if there are no calibration constants, or


DAC_CALIB_ADDR-1 

if there are.

See the Rabbit 3000 Designer's Handbook or the Rabbit 2000 Designer's Handbook for more details about the User block.

17.2.2 Flash File System

For a complete discussion of the file system, please see The Flash File System.

17.2.3 WriteFlash2

See the Dynamic C Function Reference Manual for a complete description.

NOTE There is a WriteFlash() function available for writing to the first flash, but its use is highly discouraged for reasons of forward source and binary compatibility should flash sector configuration change drastically in a product. See Technical Notes 216 and 217 for more information on flash compatibility issues.

17.2.4 Battery Backed RAM

Static variables and global variables will always be located at the same addresses between power cycles and can only change locations via recompilation. The file system can be configured to use RAM also. While there may applications where storing persistent in RAM is acceptable, for example a data logger where the data gets retrieved and the battery checked periodically, keep in mind that a programming error such as an uninitialized pointer could cause RAM data to be corrupted.

xalloc() will allocate blocks of RAM in extended memory. It will allocate the blocks consistently from the same physical address if done at the beginning of the program and the program is not recompiled.

17.3 Root Memory Reduction Tips

Customers with programs that are near the limits of root code and/or root data space usage will be interested in these tips for saving root space. The usage of root code and data by the BIOS in Dynamic C 7.20 increased from previous versions. A follow-on release will reduce BIOS root space usage, but probably not to the level of usage in previous versions.

17.3.1 Increasing Root Code Space

Increasing the available amount of root code space may be done in the following ways:

17.3.2 Increasing Root Data Space

Increasing the available amount of root data space may be done in the following ways:


<< Previous | Index | Next >>
Z-World, Inc.
www.zworld.com
Phone: 1.530.757.3737
Fax: 1.530.757.3792
Rabbit Semiconductor
www.rabbitsemiconductor.com
Phone: 1.530.757.8400
Fax: 1.530.757.8402