Simplified Language for Embedded Compilation
1. Introduction
In the development of embedded systems, there is a need to understand multiple CPU architectures and to be able to use dedicated development environments. This situation gives rise to concerns that long term maintenance, including maintenance of the development environment itself, could become very difficult as the environment evolves over time. In fact, such maintenance problems have already been observed. For example, finding compatible CPU’s for ten year old FA systems is very difficult. Reconstruction of the environment to generate the same object code has become almost impossible. In cross development, it is foreseen that reconstruction of older development environments will become increasingly more difficult because manufacturers continually update integrated environments and operating systems as improvements are made in them. In addressing these concerns, I have developed a technique to embed compilers into systems equipped with microprocessors. This will provide for minimum maintenance in the long term when effecting repairs or functional enhancements.
Photo 1: Example Implementation of the ForCy2. Virtualization of CPU Architectures
CPU’s implemented with intermediate code interpreters can be operated as virtual stack machines. One CPU can easily be replaced by another CPU equipped with the same interpreter. With the increased processing power of recent low-end microcontrollers, some decrease in processing efficiency may be acceptable for many applications.
Figure 1: Built-in Compiler and Virtual Stack Machine3. Embedded Language Processors
Microcomputers embedded with source programs and language processors require only text editors and a user interface in order to repair or replace code. Source code is internally encoded into intermediate code during the transfer from the host PC. Alternately, the source code can be embedded into the compiling device before compilation. The intermediate code is stored in programmable flash memory or EEPROM’s.
Abstract of the ForCy system (pdf 191KB)
4. Reducing the Overall Bulk of Compilers
The language specification has been written to reduce the code bulk of the compiler. It is reduced to be compatible with the limited amount of memory (in the range of several kilobytes) available to low-end microcomputers. In addition, the language offers low implementation cost and high scalability through modifications and simplification allowing improved program flow. ForCy is a programming language in a postfix notation similar to the C language with PostScript syntax. It generates intermediate code for virtual stack machines. This compiler can handle three data types, such as 16-bit unsigned integers, arrays and strings. Pointer operations are prohibited, and tail callings are optimized to reduce stack consumption. The main process of code generation is identification of words and assignment of byte codes in virtually one-to-one correspondence. A parser counts the length of { } blocks and generates code to be disregarded. Due to the small RAM capacity, the one-pass processing is designed to compile into self-programmable flash memory while receiving source text through a serial communications interface.
"\n\tHello, World.\n" %s // show string :hello 10 0 // repeat 10 times { hello ++ } for .. :hello_10 ;i [10]a [10]b [10]c // array 10 0 { dup =i i a i b * i =c // c[i] = a[i] * b[i]; ++ } for .. :c=ab ;x ;y // multiply table 1 =y { y 9 <= while // repeat from 1 to 9 1 =x { x 9 <= while // repeat from 1 to 9 x y * %3d // show x * y ++ =x } do . ‘\r’ %c ‘\n’ %c // CR-LF ++ =y } do . :multiply 1 > { dup -- self * } if :factorialList 1: Example of ForCy Program Code
The interpreter sequentially calls processes depending on intermediate codes to operate the data stack and the return stack. The compiler itself is also encoded into intermediate codes and operates on the interpreter. The entire language processors including compilers and interpreters can be implemented in 4 to 6 kilobytes of code.
Figure 2: Memory usage of PIC16F885. Implementation
This simplified language was implemented using a Microchip PIC16F88 (4K word ROM and 368 byte RAM). It sequentially compiles program text transmitted through a RS-232C interface. It then writes the results into a flash memory area and interprets it. Although the PIC architecture is not adequate for a stack machine, it can calculate the first 100 digits of the value of Pi in 8 seconds using a 20 MHZ clock. This language is also implemented with a PIC12F683, R8C/Tiny and ATmega88. An interrupt mechanism is available in R8C/Tiny and ATmega88. Thus it can easily activate tasks at regular intervals and process multiple tasks in quasi-parallel fashion.
ForCy-USB Schematic (pdf 15KB)
6. Summary
This method was invented and is being developed mainly to reduce development loads of embedded systems and to ensure ease of long-term system maintenance. The following applications are expected to be available:
(1) Control of microcomputers in FA systems for a long-term maintenance.
(2) Customization of behavior for experimental equipment and sequencers.
(3) Integrated management of multiple processors in standalone systems (e.g. robots).
(4) Educational material for microcomputer applications (programmable with only text editors and user interface software).7. Download
I publish the ForCy code as free software (LGPL). See the License.txt.
All the documentation, and the source code for Atmel ATmega88 are included:ForCy.2007-01-27.tgz (497KB)
ForCy.2007-01-27.zip (531KB)mailto: Osamu Tamura
27 Jan. 2006
27 Jan. 2007 : ATmega88 fuse bits corrected.
17 Jun. 2008 : linked to ForCy-Arduino.