> > By the way. What does reentrancy mean? as in: (Global
> > variables require
> > less code to access at the expense of data memory and reentrancy.)
A quick explanation of how this might be implemented on an 18C chip.
A global variable is simple a memory location, allocated by the
compiler/linker, used to hold the value. The value is always in the same
location. If the variable is allocated to access RAM it can always be
accessed in a single cycle like this:
movf global_var,w,a
addwf global_var,f,a
etc.
Very efficient.
If the variable is not in access RAM you can still get at it with a two
cycle/two word instruction:
movff global_var,someplace
movff someplace,global_var
Local variables get a little more complicated on a PIC. In the traditional
implementation, the compiler/linker figure out what functions call what
functions and they allocate variables to memory locations in such a way that
a location is never reused for another purpose while its function is active.
This is good (because access to the variable is as efficient as accessing a
global), but it doesn't allow the functions to be called recursively or
reentrantly (e.g. from an interrupt handler and main-line code at the same
time).
On the 18C you can create a real 'stack' of variables. Now a function that
needs local variables can keep them on the stack, probably pointed to by an
FSR. The 18C has a neat 'indexed with offset' access mode that can be
efficient to read them. Given that FSR2 points to the 'stack frame', and
that the desired value is at offset 'my_var' relative to FSR2, the following
will access the local variable:
movlw my_var ; offset of variable
movf PLUSW2,W,A ; get the variable at [FSR2+W]
You do have to deal with the overhead of managing FSR2 of course.
Note that in "C" you can have a variable that is local to a function, yet is
allocated like a global. This is done with the static keyword:
void foo()
{
unsigned char bar; // dynamically (stack) allocated
static unsigned char baz; // statically allocated
}
'bar' will have an indeterminate value on each entry to foo(), 'baz' will
retain its value from one call to the next.
Real 'C' would allow foo() to be recursive and reentrant, each
recursive/reentrant call would create a new 'bar' but use the same 'baz'.
PIC compilers have traditionally generally not supported recursive/reentrant
code, but the 18C does a pretty good job of it. I do not know if MPLAB-C18
uses a stack for local's, but I would guess that they do.
Bob Ammerman
RAm Systems
(contract development of high performance, high function, low-level
software)
> Re-entrant
>
> <programming> Used to describe code which can have multiple simultaneous,
> interleaved, or nested invocations which will not interfere with each
other.
> This is important for parallel processing, recursive functions or
> subroutines, and interrupt handling.
>
> It is usually easy to arrange for multiple invocations (e.g. calls to a
> subroutine) to share one copy of the code and any read-only data but, for
> the code to be re-entrant, each invocation must use its own copy of any
> modifiable data (or synchronised access to shared data). This is most
often
> achieved using a stack and allocating local variables in a new stack frame
> for each invocation. Alternatively, the caller may pass in a pointer to a
> block of memory which that invocation can use (usually for outputting the
> result) or the code may allocate some memory on a heap, especially if the
> data must survive after the routine returns.
>
> Re-entrant code is often found in system software, such as operating
systems
> and teleprocessing monitors. It is also a crucial component of
multithreaded
> programs where the term "thread-safe" is often used instead of
"re-entrant".
{Quote hidden}
--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email .....listservKILLspam
.....mitvma.mit.edu with SET PICList DIGEST in the body