============================================================================ This is a textual excerp from http://www.ai.sri.com/people/erratic/icn.html ============================================================================ ICn: Native Mode C Compiler for HC11 Microcontrollers ICn is a native mode C compiler for HC11-based robotics applications. Source files for a Unix version of ICn are available as ICn unix sources. The original IC program by Randy Sargent and Anne Wright is available as freeware from IC files. For information about the SRI/RWI educational robots, which use ICn, please see the Erratic robot home page and RWI's Robot Platform home page. IC native IC (Interactive C) is a C compiler for HC11 boards originating from MIT: the Rug Warrior board (featured in the Jones and Flynn book) and the 6.270 board. It features an interactive environment in which C statements can be typed on the host computer, then downloaded and run on the HC11, returning results to the host. IC compiles C into pseudo-codes (pcodes) for a virtual machine. A pcode interpreter on the HC11 interprets pcodes. The advantages of IC are small code size and a simple multiprocess executive. However, pcode interpretation is slow, typically one to two orders of magnitude slower than equivalent hand-coded assembly routines. ICn has the following changes from IC: Option to compile individual functions to fast native code Enchanced syntax, especially for memory access Bug fixes to source code ICn will compile either to pcodes or native codes, and both can run compatibly on the 6.270 and Rug Warrior board. Native codes are significantly faster (2x-25x), but usually take more space (0.9x-2x). Use native-code functions when you want the speed, e.g., in interrupt code. Details on constraints for producing fast native code are given below. Several new syntactic features enhance the usability, efficiency, and readability of ICn. These include automatic type promotion, automatic casts in assignments, contant declarations, and pointer access to memory. Future modifications will include pointer arithmetic. *** NOTE *** YOU MUST USE THE PCODE FILE PROVIDED WITH THE DISTRIBUTION!!! ICn will not work with older versions of the pcode. The two files pcoder22.s19 (6.270 board) and pcoderwl.s19 (Rug Warrior board) are included. Please note: if you build your own .s19 files, you must use the pcode.h and pcode_in.h files provided in the ICn distribution. I have not tested the Rug Warrior code at all, not having the board, but the 6.270 code should work ok. I have successfully loaded the lib_r22 files and run them in the simulator. ICn v1.2b is now stable enough to be a beta release. Most standard IC constructs will work in pcode mode, including arrays. Almost all features will also work in native mode; see below for exceptions. I expect some bugs, especially since I run on a custom HC11F1 board. Native Mode Compiler ICn's compiler recognizes a "native" procedure declaration, e.g., int *MSLO = 0x14; int *TCNT = 0x100E; int *bb = 0x1024; native int time1(int n) { int a, b; a = *MSLO; while(--n) *bb += *TCNT; b = *MSLO; return b-a; } ICn will compile time1 not to pcodes, but to native HC11 instructions, together with initial and final code to interface to the pcode interpreter. Native procedures can be called just like pcode procedures. Native procedures can call other native or pcode procedures. Here are time and space figures for time1: Mode us/iteration bytes -------------------------------- Native 11 73 Pcode 291 64 These figures are for an HC11F1 using a 4 MHz bus (16 MHz crystal); the 6.270 and miniboard are half this speed. The compiler first converts syntactic statements into semantic expressions, performs some reductions, and then spits out either pcodes or native codes, depending on the declaration. There is little optimization; typical loops coded by ICn take about twice the time of hand-coded ones. With some additional work, optimization could reduce this difference. I don't know how ICn compares with commercial compilers. Efficient Native Code There are several constraints to keep in mind when writing native procedures. In general, using float and long types makes native code less advantageous, and also increases native code size relative to pcodes. For example, consider the following function. float fa; native int time2(int n) { int a, b; a = *MSLO; while(--n) fa = fa + (1.0*fa); b = *MSLO; return b-a; } Here are time and space figures for time2: Mode us/iteration bytes -------------------------------- Native 218 128 Pcode 469 70 Here the speedup is only a factor of two. If the difference in loop overhead time is subtracted out, the floating-point operations themselves take 206us in native mode, and 239us with pcodes. Since the HC11 is very slow on any floating-point operation, and on longword multiplication and division, these should be avoided. Use int's and char's whenever possible, e.g., try scaled arithmetic instead of floating-point. Conditionals have not yet been optimized in native mode. while loops with a countdown to zero, as in the functions above, work best. Prefix increment and decrement are faster than postfix. Use const declarations for variables whenever possible. Shift commands are not yet optimized in native code. Restrictions Arrays are only implemented in pcodes, and cannot be used in native procedures. poke, pokeword, peek, peekword, bit_set, bit_clear, and mseconds have been supplanted by newer constructs (see below). They are still available for compatibility. None of the process commands (start_process, defer, etc.) are available in native mode. Multiprocessing Native mode procedures currently hog the processor until they exit. This can be an advantage for some applications, but not others. A workaround is to use smaller native procedures, called by a pcode procedure. I plan to implement an operation that lets native procedures cede the processor at a given point. Interrupts Native mode procedures can be installed as interrupts, since they run HC11 code. I haven't implemented this feature yet; more details in a future release. Syntactic Enhancements I've been frustrated by the clunkiness of POKE/PEEK constructs, when C's dereferencing mechanism is so elegant, as well as a number of other features. Here are some modifications in ICn. Pointer assignments and dereferencing Pointers can be set to memory locations by assigning them to an integer. char, int, and long types are available for 1, 2, and 4 byte access. For example, char *ca = 0x100A; sets ca as a pointer to the byte at memory location 0x100A. ca can be used in assignments and references, e.g., *ca += 3; increments the byte at location 0x100A by 3. In IC, you would have to use the statement poke(0x100A,peek(0x100A)+3); Similarly, bit_set and bit_clear are implemented with assignment statements on memory pointers: *ca = *ca & !0x0f; instead of bitclr(0x100A,0x0f); Or more elegantly: *ca &= !0x0f; The function mseconds() has been superseded by the pointer syntax; use: const long *MS = 0x12; ... + *MS + ... Or you can access the low and high words of the system ms timer as: const int *MSLO = 0x14; const int *MSHI = 0x12; Constant Declarations Global and local variables can be declared constant. This is most useful in setting constant referred to in other parts of the program or other files, since there is no preprocessing facility. It is also a more efficient way to set up memory pointers. const int a = 34; const int *b = 0x100A; Constant declarations must have an initialization. They are treated like constant numbers in expressions, and reduced by the compiler. For example, const int a = 34; ... i = a/2; declares a a constant integer, so a/2 is reduced to the constant 17 before it is compiled into the assignment. Constants may not appear on the left-hand side of an assignment expression. Type Promotion and Automatic Casts IC does not perform type promotion, which may be a Good Thing in reminding the user when longs and floats are being produced. But it can also be a pain. In expressions, ICn does automatic type promotion according to standard rules, e.g., int/long -> long int/float -> float long/float -> float char/x -> x NOTE: there is an error in ICn's (and IC's) type promotion from ints to longs: negative ints are not sign-extended. Chars are always considered to be unsigned. In assignments, casts are also made automatically to the assigned variable type, by conversion and truncation if necessary. ICn will cast integers to pointers. Pointer Addition This is a useful feature in some applications. It is not yet implemented, but will be in a future release. Getting and Running ICn The Unix sources for ICn are direct descendents of IC version 2.860 (beta). There is a distribution file in ICn unix sources. To compile ICn, untar the distribution, then go into the libs directory and type configure to autoconfigure the libraries. You might check the original config.h file included with the distribution; this is the config file I used on a Sparc SunOs 4.1.3/4 machine. If you have any trouble, please let me know. I've successfully compiled these files on Sparc (but not Solaris 2.x and later) and SGI machines. Supposedly the sources also work for Macs and PCs, but I have no experience with them; if anyone does a successful compile, please email me the details at the address below. After configuring ICn, go into the libs directory and type make. If all goes well, do the same in the ic directory. To run ICn, you need to download the pcoder22.s19 or pcoderwl.s19 file included in the pcode directory. This file contains only a minor modification to the pcode assembler file included with the IC 2.860 beta distribution. After downloading and resetting the board, start up ICn (type ic) and you should be in business. Note that it takes a little longer to start icn, since it reads jumptable addresses from the board during initialization. Other Useful Information IC was originally written by Randy Sargent and Anne Wright for use with the miniboard and 6.270 board at MIT. There is a commercial version of IC (3.0) available from Randy Sargent Imachinations 2 Newton St. Apt. 1 Cambridge, MA 02139 (617) 547-6664 The original pcode interpreter was written by Randy Sargent, Anne Wright, and Fred Martin. I've used IC to experiment with low-level control of various home-built robotics platforms in AI courses. The latest one, Erratic, placed second in the 1994 AAAI robotics contest. A commercial version of this platform is available from Real World Interface, Inc. P.O. Box 375 Jaffrey, NH 03452 (603) 532-6900 For more information, contact konolige@ai.sri.com