Reentrant/Non-reentrant Functions
|
|
Products 8051 Starter Kit In-Circuit Debugger Development Suite ColdFire 68XXX Z80/HD64180 8085 6801/6301 6809 68HC11 Embedded Development Studio (IDE) Show all productsSales Price list Shopping Basket Distributors Request information15 day Evaluation 8051 Development Suite ColdFire Development Suite 680X0 C Compiler & 68000 Simulator4kb 12 Month Demos ColdFire Development Suite 680X0 C Compiler & 68000 SimulatorSupport Register Get updated
|
The compiler will produce both reentrant and
non-reentrant functions. Reentrant functions are fully
compatible with ANSI C and allow recursive calls within
and between functions. Also a reentrant function can be
called during an interrupt even if it is being invoked
during the non-interrupt part of the process or by
another lower priority interrupt. Space for parameters
and local variables is allocated dynamically on a stack
located in either internal indirectly addressable data
memory or external data memory depending on the memory
model. Since this stack space is released as soon as the
function exits, reentrant code is data memory efficient.
However, the 8051 instruction set is not particularly
well suited to conventional stack operations (it has no
indexed addressing modes for accessing data memory) and a
dramatic improvement in program size and speed can be
achieved by implementing a statically allocated stack
system. With this approach, each function has it's own
fixed data memory for storage of its parameters and local
variables. Because this memory is in a fixed location, if
the function is called again while it is already running,
the parameters and local variables of the second call
will overwrite those of the first call. The function
cannot be reentered and it is therefore a non-reentrant
function. Although a statically allocated stack system is not as data memory efficient as a dynamic, reentrant stack, the amount of statically allocated stack is not the sum total of the stack space required by each function present in the program. It can be considerably less. This is because the linker carries out an analysis of the complete program and constructs a function call tree. It uses this call tree to determine which functions can safely share stack space. The stack space for functions that cannot possibly invoke each other are then overlaid. The linker is also able to exactly determine the total stack space required by functions that have a variable number of arguments (such as printf() and scanf()) and so no space is wasted allowing for additional arguments that are never present. Another advantage of non-reentrant functions is that it is possible to support true _bit types as parameters and local variables. If you use a _bit type as a parameter or local variable in a reentrant function, it will be quietly converted to unsigned char. However, with a non-reentrant function it will remain as a _bit type located in bit addressable data memory. The compiler can be set using a command-line option (or dialogue box option in the Embedded Development Studio) to default to either reentrant or non-reentrant code. This will determine whether the reentrant or non-reentrant libraries are included and all functions will be compiled as the selected default type unless they are specifically designated as either reentrant or non- reentrant. The _reentrant and _nonreentrant keywords can be placed to the left of the function name to force it to be one type or the other regardless of the default type selected. These keywords should also be used with function prototypes to ensure the function is called correctly from other modules. Nevertheless, the linker will check function calls against function type across the complete program and warn of a reentrant/non-reentrant mismatch. (Note that the compiler does not need to use function name colouring to perform this type checking. No additional characters are appended to function names other than the normal underscore.) The linker will also warn if a non-reentrant function is potentially recursive so that you can take steps to declare this particular function as reentrant. This warning does not mean that the function is bound to be recursive, only that the linker has found the function itself on its own call tree. Whether or not it is actually recursive depends upon the execution path of the program. Even though the linker can warn you if a function is potentially recursive, it cannot warn you if a function is potentially reentrant due to an interrupt event. Consequently, care should be taken when including calls to non-reentrant functions (including library functions) from within an interrupt function. If you want a particular library function to be reentrant (so that you can use it for instance in both an interrupt function and your normal code without fear of conflict) and the default type is non- reentrant then you will need to take special steps to integrate this reentrant library function into your code. Let's say you want to use the reentrant version of strcpy() in an otherwise non- reentrant program. You need to do the following:
char * strcpy (char * string1, const char * string2); to: char * _reentrant strcpy (char * string1, const char * string2); Extract the reentrant version of strcpy() from the appropriate memory model. The non-reentrant libraries have an 'n' as the last character and so the small memory model non-reentrant library is slib51n.lib and the small memory model reentrant library is slib51.lib. To extract strcpy() from slib.51.lib use the command line, lib *strcpy slib51.lib; (slib51.lib must be in the current directory and PATH must point to lib.exe) This will create object file strcpy.obj leaving the original library unchanged. Now you can either include this extracted object file in your build, replace the version in the non-reentrant library with this reentrant version, or build a new library with this object file, in it and include this new library in your build. |Home|Request information|How to order|
Copyright © 2000-2004 Crossware
Products. All rights reserved. CROSSWARE and the Crossware logo are trademarks of Crossware Products. |