 |
Making Kernel-Based Programs |
To produce a kernel-based program, i.e. a program which will need PreOS,
DoorsOS, UniversalOS, TeOS, etc. for executing, simply define the global
preprocessor symbol USE_KERNEL
at the begining of your program,
before including any other header files from the library. Alternatively, the
old method (including the doors.h header file
before including any other header files from the library) still works. In
fact, if USE_KERNEL
is defined, including any header file from
the library will include doors.h
automatically (if it is not
included explicitely before). So, explicitely including doors.h
is really necessary only if your program does not include any other header
file from the library (which is extremely unlikely).
Here is a Kernighan & Ritchie "Hello world" example (kernel version, called "Hello World 4"),
which works exactly like the example given in the previous section
(Making Kernel-Less Programs):
#define USE_KERNEL // include kernel support
#define USE_TI89 // produce all types of files
#define USE_TI92PLUS
#define USE_V200
#include <stdio.h> // standard ANSI C input/output support
#include <kbd.h> // keyboard handling support, needed for ngetchx
void _main(void) // main entry point is function _main
{
clrscr (); // clear the screen and reset print position
printf ("Hello world!"); // do you know what this is?
ngetchx (); // wait for a keypress
}
Note that the directive SAVE_SCREEN
is not included like in the NoStub version.
DoorsOS saves and restores the screen content by default, so no extra intervention
is necessary.
Of course, it is better again to use TIOS specific functions than ANSI C console
functions, so an extended "Hello world" TI-specific example (kernel-based
version), which does the same as in the NoStub case, follows (called "Hello World 5"):
#define USE_KERNEL
#define USE_TI89
#define USE_TI92PLUS
#define USE_V200
#include <graph.h>
#include <kbd.h>
void _main(void)
{
static WIN_RECT rect = {0, 0, 100, 14};
ClrScr ();
FontSetSys (F_8x10);
DrawStr (3, 3, "Hello world!", A_NORMAL);
DrawClipRect (&rect, ScrRect, A_NORMAL);
ngetchx ();
}
See graph.h and kbd.h for
detailed descriptions of the used functions and data types. Be aware of the slight difference between
ClrScr defined in graph.h and
clrscr defined in stdio.h.
To compile this program, you can use the
TIGCC Integrated Environment, or you can type from the command line
(if the file is named "hello.c"):
tigcc -O2 hello.c
Always include the '-O2' or '-Os' switch: it will turn on optimization
(click here to see much more about compiler command line options).
See also the notes given with the example in the previous section.
If you make programs spread in more than one file, you must define
USE_KERNEL
(or include doors.h) in each file!
The advantage of kernel-based programs lies in the fact that they are
often (but not always) shorter than NoStub programs if the
program contains a lot of ROM calls. Kernel-based programs can also call
routines from external files (often called "libraries") without special
library support inside the program. Any other features supported
with this library of header files work in both kernel and
NoStub mode, so if the difference in the program size is not
too large, and if no external libraries are needed, NoStub mode
is recommended. Note that routines defined in these header files
contain most of the routines which are seen in various external
libraries, sometimes maybe with different name and syntax.
Additionally, if you want to make your program even smaller but only want to support
new versions of the PreOS kernel, you can define USE_PREOS_COMPRESSED_TABLES
.
This will create compressed versions of the relocation tables, which are not
available in older kernels. If you try to run the program with an old kernel
installed, you will get an error message.
If you make a kernel-based program, knowing the following facts may be useful:
-
You can produce an external library file by defining the global symbol
_library
, i.e. by putting int _library
in your program. If the name of your library is for example MyLib,
all symbols with names like MyLib__nnnn will be exported as public. To make
life easier, use the #define
directive. For example, if you
want to export function named MyFunc, you can, for example, put the directive
#define MyFunc MyLib__0005
at the beginning of
your library. The same directive must be included in the program which wants
to use the function MyFunc from the library MyLib. Also, the prototype
of the imported function also needs to be defined.
-
Kernel-based programs may have an exit point. The function with name
_exit
will be executed if and only if the program is terminated
in an abnormal way, for example if there was an error, or if the user pressed
STO+ON.
See also: doors.h