Quantcast
Channel: EFY Bureau – Electronics For You
Viewing all articles
Browse latest Browse all 5960

Programming The Mizar32 Board in Lisp Programming Language

$
0
0

This article aims to revive Lisp programming language for native, interactive and incremental microcontroller (MCU) program development by running a dialect of Lisp programming (PicoLisp) as virtual machine on the target. It also demonstrates the power of Lisp through execution of expressive Lisp programs on a 32-bit MCU.

Lisp programming offers a practical mathematical notation to write computer programs, mostly influenced by lambda calculus. It is still the most-favoured programming language for artificial intelligence research.

Dynamic languages like Lisp have been in existence as a versatile tool for rapid application development. Many interesting, practical embedded solutions have been developed so far with such languages, supported as part of a virtual machine (VM). Fig. 1 shows the system architecture of a natively-programmable, digitally-controlled system.

lisp programming
Fig. 1: General MCU software system with a VM layer

With the above architecture, it is possible to write abstract, self-adapting, middle-level drivers for hardware modules on the MCU. This enables the possibility of platform-independent, native embedded software development.

Lisp programming is the second-oldest high-level programming language (the first being FORTRAN). Linked lists are one of its major data structures. A program written in Lisp is constructed with lists. One of the most interesting properties of this language is its homo-iconic nature.

Although projects like PICOBIT and ARMPIT Scheme already implement a compact Lisp programming language for an MCU, there are many reasons to consider PicoLisp for programming MCUs.

PicoLisp is constructed as a VM. It is written in portable C and is easily extendable. After much research and programming to narrow down on a Lisp programming implementation, PicoLisp was chosen as a VM for the following reasons:

1. Dynamic data types and structures

2. Formally homo-iconic

3. Functional programming paradigm

4. An interactive REPL(read-eval-print loop)

5. Pilog, a declarative language with semantics of Prolog in PicoLisp

6. Small memory footprint

7. Permissive, non-copyleft free software licence

At the lowest level, PicoLisp programs are constructed from a single data structure called cell. A cell is a pair of machine words, which are traditionally called CAR and CDR in Lisp programming terminology. These words can represent either a numeric value (scalar) or address of another cell (pointer). All higher-level data structures are built out of these cells.

Basic data types that PicoLisp supports are numbers, symbols and lists. As a result, it is one of the fastest Lisp dialects available, since only fewer options are checked at runtime to parse a value.

PicoLisp in addition supports an integrated database system. This is a huge advantage for embedded system applications that require a convenient facility to perform data transactions.
Overall logical software structure for running full-fledged PicoLisp on the MCU is shown in Fig. 2. It shows the communication between PicoLisp VM and various other modules in code base.

lisp programming
Fig. 2: Software system architecture for PicoLisp

The code base remains highly portable across various platforms and architectures simply by using the following key principles:

1. Code that is platform-independent is common code and should be written in portable ANSI C as much as possible. PicoLisp itself is a part of the common code section and is written in this way.

2. Code that is not generic (mostly peripheral and CPU-specific code) must still be made as portable as possible by using a common interface that must be implemented by all platforms on which PicoLisp runs. This interface is called platform interface.

3. Platforms vary greatly in capabilities. The platform interface tries to group only common attributes of different platforms.

Platform interface is declared in inc/platform.h header file from source distribution. It is a collection of various components like UART, SPI and timers. Each component has an identifier, which is a number that identifies that component in PicoLisp. Generally, numbers are assigned to components in their natural order. For example, Port A will have identifier value 0, Port B will have 1 and so on.

Similarly, second SPI interface (SPII) of the MCU will probably have an identifier value of 1. Pin 0 in Port 1 on Infineon XMC4500 will be called ‘P1_0 in PicoLisp. Similarly, pin 27 in Port B on Atmel AT32UC3A0256 will be called ‘PB_27 (notice the single opening quote).

Some issues

PicoLisp cannot be directly compiled for a 32-bit RISC machine. There are many issues to address before one can use PicoLisp REPL over UART or TCP/IP interface on the MCU. For instance, supporting programs such as memory allocators are required for PicoLisp to function correctly. We use Newlib C library and implement stubs of code for the memory allocator. We have to deal with issues like routing plain I/O over UART or TCP/IP interface of the MCU.

We also require support for a multimedia card memory interface to store PicoLisp programs. We can then load PicoLisp programs at runtime. This implies a requisite for a file system. We also need to implement stubs of code for file I/O support over SPI protocol. For the file system, we use FatFs FAT file system module.

Once all supporting programs are in place, getting PicoLisp to run on the MCU is then fairly straightforward. On account of its small size, it can be easily embedded on an MCU in less than 256kB of flash. It can also be easily compiled for a given architecture with a toolchain like GNU gcc. Currently, a Python based build system called SCons is being used to compile the code base.

Booting PicoLisp on the MCU

Given below is the sequence of events that occur after the MCU is powered up. The platform-initialisation code is executed. This program does very low-level platform setup, copies ROM contents to internal RAM, zeroes out BSS section, sets up the stack pointer and long jumps to the main function.

1. The main function calls the platform-specific initialisation function and returns a result that can be either a value indicating success or failure. If it fails, main instantly gets blocked. A debugger can then inspect the internals of the state machine.

2. The main function then initialises the rest of the system: ROM file system, XMODEM and terminal support.

3. If files /rom/autorun.l or /mmc/autorun.l exist, these are executed. If one file is found before the other, it terminates further execution of the other file and the context jumps to the next step. If it returns after execution, or if files are not found, boot process continues with the next step.

4. If boot parameter is set to standard and the shell was compiled in the image, it is started. In the absence of the shell, standard PicoLisp server is started.

The post Programming The Mizar32 Board in Lisp Programming Language appeared first on Electronics For You.


Viewing all articles
Browse latest Browse all 5960

Trending Articles