Dunfield Development Services Inc.
APPLICATION NOTE
Home
Products
Ordering & Status
Free Download Files
Links
Notices
Contact Us

 

Dunfield Development Services Inc.
Customer Support -- Application Note #0013

MICRO-C
Accessing "volatile" locations and devices

Applies to: [Micro-C Compiler ]
Last updated: Sunday May 04, 2003 .
Application Note Index

Back ] Next ]

PROCEDURE

The Micro-C optimizer performs an optimization called "Redundant Load Suppression" which may cause the compiler to incorrectly access memory locations which are considered "volitile".

The term "volitile" is used to refer to locations which may not read the same value as was last written there. An example of this would be an I/O port, where some of the bits are used for OUTPUT, and some bits are used for INPUT. When reading the port, the input bits will always reflect the physical state of the corresponding digital input lines, and NOT the value last written to those bits by the processor.

Micro-C's "Redundant Load Suppression" optimization is intended to reduce unnecessary code produced when a variable is re-used immediately after it is written. Examples are:

b = a;
c = b;

In this case, the compiler generates code which looks like:

LOAD a
STORE b
LOAD b
STORE c

The optimizer recognizes that the 'LOAD b' immediately following the 'STORE b' is unnecessary, and removes it, leaving a sequence which looks like:

LOAD a
STORE b
STORE c

Another perhaps more common example, in which similar code would be generated is:

a = function();
if(a & 0x10) { ... }

In this case, the compiler generates code which looks like:

CALL function
STORE a
LOAD a
AND 0x10
JUMP_IF_ZERO ...

Again, the optimizer recognizes that the 'LOAD a' immediately following the 'STORE a' is unnecessary, and removes it.

For most cases involving RAM, or I/O ports which are output only, this would be correct, however if A is a port used for output AND input, the intent of the programmer might be to write the output bits with the return value from 'function()', and then immediately test the 0x10 input bit. In this case, the optimized code would fail, as it will test the 0x10 bit in the return value from 'function()', NOT the value read from the input port!

Some compilers use a "volatile" keyword to identify locations which should not be write/read optimized however Micro-C does not have this capability. it is however quite easy to achieve the same functionality.

The cases where the Micro-C optimizer will perform Redundant Load Suppression are very specific, in particular, the location must be written, and then IMMEDIATELY read. If any other operation occurs in between the write and the read, the optimization will not occur.

You can also take advantage of the fact that the optimizer considers a blank line or comment to be equivalent to "any other operation", and therefore will not perform the optimization if a blank line or comment separates the write from the read. You will find that this optimization does not get performed when the -C option is used to insert the C source code as comments. This is because the comments inserted by the compiler between the write and the read prevent the optimizer from recognizing the sequence.

You can defeat specific Redundant Load Suppression optimizations by adding a asm""; directive to your code in order to force a blank line between the write and the read operation:

a = function();
asm ""; /* Defeat RLS to insure volitile location re-read after store */
if(a & 0x10) { ... }

This inserts a blank line in the output code between the write to 'a', and the read from it, defeating the optimization.

You should keep this in mind and insert the asm""; whenever you are writing to an IO port and them immediately reading from it, and expecting to read the actual hardware value. If you like, you can hide this in a #define:

#define VOLITILE asm""

a = function();
VOLITILE; /* Insure volitile location re-read after store */
if(a & 0x10) { ... }

Note that this "Redundant Load Suppression" problem occurs only on I/O locations which are mapped as memory devices, and read/written in two consecutive C statements as simple variables. This problem will NOT occur on I/O devices which are accessed by peek/poke/in/out functions.

 

 

Back ] Next ]

© 2008 Dunfield Development Services Inc.     View our Privacy Statement
Refunds given at the discretion of management.
 Last Updated:  Tuesday, March 18, 2008