eLua logo

LUA programming language on LPC2148

A project by:

Dror Marcus & Roza Pogalnikova

Introduction

Design

Implementation

What Went Wrong

Possible Future Work

License

Introduction

LPC2148 Embedded Artists education board

This is a project for Prof. Sivan Toledo's Advanced Computer Systems: Embedded Systems course in Tel-Aviv University. The project's goal was to run a script-based compiler on the Embedded Artist's LPC2148 Education board.


The Lua scripting language was chosen as the best fit scripting language for the above requirements. Lua is powerful, fast, lightweight, embeddable and has easily extensible semantics. Our project made it possible to access the board hardware capabilities via scripts written in Lua.

eLua, a known Lua implementation designed for easy embedding, was chosen as the basis for our implementation. eLua provides a Lua development environment on a variety of platforms with additional interfaces and modules designed for small embedded devices. Our main contribution in this project was adding the LPC2148EDU board platform to eLua.

 

As a result, LUA scripts can be run on the LPC2148 EDU board using either Lua commands entered directly to a terminal, Lua files pre-saved in a RomFs file system on the board itself or by files sent via serial connection using the XMODEM protocol.

Usage

Please refer to the eLua usage instructions for more detailed instructions.

 

Building The Code

Before building make sure you have the required packages and the arm7 toolchain.

Building and loading the code to the board is done by entering 'scons cpu=LPC2148 prog' in the project root folder.

To clean the project append "-c": 'scons cpu=LPC2148 prog -c'.  

After the successive build, the code is automatically uploaded to the device via the UART connection (make sure to connect the device correctly).


Connecting the Board

Connect a USB cable to the USB port (you can use an additional cable or unplug the one previously connected to the UART).

In current code configuration one needs a serial terminal emulator (for example, minicom) to connect to the board (connection is done using a USB-serial emulation). (It was possible to avoid this by running eLua shell via UART, but this option was discarded as causing problems with file transfers (see What Went Wrong section)).

In order to send Lua files from your computer to the board (as opposed to using the ones stored in the board file system) you need a terminal with XMODEM capabilities (if using minicom, as we suggested, please make sure that you also have the lrzsz package).
Once the code image is uploaded to the board (and a cable is connected to its USB port) a new USB connection will be established. Tip: you can use 'dmesg | grep tty' to see its name, should be something like '/dev/ttyACM1'. Run 'minicom -s' to configure serial port connection.

Connect to the device using the following UART settings:

Once connected, you will see the eLua shell ("eLua# "). Write "help" for a list of available commands.

Using Lua
Enter "lua" for Lua interactive mode. Use script files in the RomFs by entering "lua /rom/[filename] ", where [filename] stands for the lua script to run (see available scripts by entering "ls"). Use script files from your computer by first entering "recv" and then sending a file via XMODEM (notice that after sending a file, it will be executed immediately "as-is"). See Lua code reference for more details.


Available board scripts
bisect.lua - solve x^3-x-1 in [1,2] by bisection with tolerance 1e-6
led.lua - blink led 13 until user input
hello.lua - print 'Hello, World!'
info.lua - print board info
rotate.lua - rotate step motor or board led colors according to given parameters. For example, run 'lua /rom/rotate.lua motor 30 100' or 'lua /rom/rotate.lua color 3 10000'.

 

New Lua commands( eLua and board specific)
Tip: you can see a list of available commands and constants from interactive lua by running 'for k in pairs([package]) do print(k) end'), where [package] can be uart, lpc.disp, pwm, pio.pin, tmr.

Implementation

Project Code Base

The project is based on the eLua V0.6 (http://www.eluaproject.net/) infrastructure which is written in C and contains the LUA code package along with added support modules and platform interface requirements. Building in eLua is done using the "scons" build system which is a build tool that uses python scripts to build the code. Module support was added in stages, initially only the PIO (general IO pin) support was implemented.

 

eLua architecture

The eLua Architecture (source: http://www.eluaproject.net/)

Porting the board platform

In order to add the Embedded Artists LPC2148 board support, code was implemented on the Platform layer which resides in the path src/platform/LPC2148/ (see drawing above).  The implemented code can be divided to four types:

        Interface implementations: Code that implemented the functions needed by the platform interface (inc/platform.h). The interface implementation was implemented in the file "platform.c".

        Drivers: Code implementing needed for the board to work. Theses included

o       UART (uart.c/ uart.h ) An initial uart driver used for the terminal (which was later replaced by the USB). These files are partly based on code in existing eLua project and code from the exercises in class.

o       LCD (lcd-driver.c/lcd-driver.h) Drivers for the LCD display based on a class exercise.

o       PWM (in platform.c) Drivers for the PWM (pulse width modulation) module, implemented using the board documentation.

o       GPIO pins (in platform.c)- Drivers to control the general purpose IO pins.

o       Timers (in platform.c)- Drivers to add timer functionality.

o       VIC (vic.c/vic.h) Drivers to add interrupt IRQ support (based on code given in class which was slightly modified).

o       LPC2148 Platform (target.c) Drivers needed for the startup (CPU speed was set to 60MHZ using PLL).

o       USB (usb-serial, usb.c) Drivers needed for the USB serial terminal. Code based on the serial USB exercise code.

o       Startup (startup.s) Assembler boot partly based on the code given in class. The main modification was for heap support and different stack sizes.

o       Load File (lpc2148-flash.ld) Linker file used to create the program image. Based on the linker given in class, modified to add heap support and eLUA LTR (ram optimization) support.

        Platform specific modules: Code that was implemented in-order to add functionality (new LUA commands) that are specific to the LPC2148 board.

o       Files "disp.c" and "disp.h" add the board LCD display functionality (using the implemented LCD drivers).

        Lua Scripts: Code to be compiled inside the board. These sometimes added additional board functionality (such as rotate.lua which rotates the propeller motor using the io pins interface).

 

In addition to the code above the project specific build tools and files were added to the "scons" build tool. Linker and Compile commands and flags were based on the existing ARM7 projects gcc commands, with slight modifications (initially it was based on calls used in the class exercise makefiles but these caused some errors). File "SConstruct" in the main folder was modified to add the LPC2148 platform. The "conf.py" in the platform folder defines build files and flags specific for the LPC2148 platform.

 

What Went Wrong

The hardest part in any project is the beginning (i.e., blinking a led J ). Major issues in implementing an initial port for the LPC2148 were the need for heap support, adjusting the boot/linker files and finally defining the correct build flags for it all to work.

 

We describe below only part of the problems that occurred. Most problems and solution we describe here might help future projects:

 

*     Empty output hex file created though no errors appeared in build: elf file was 400K but the final hex file was empty for some reason. Tried different compiling and linking flags. It turned out that, in order to work correctly with eLUA, the flag " --gc-sections" is needed. This flag determines that all unreferenced code compiled will be omitted from the linker. It turned out that without defining a start function entry point this flag removes all code (it cannot determine which code is called). We did not define a start function entry point flag since we though it was not needed since the start function was at the beginning.

*     Malloc Failed: Did not define heap pointers correctly in the loader file. _sbrk_r() which defines memory allocation was not added correctly.

*     Not enough memory: We did not have enough RAM to run lua. After adding the LTR support (see above in implementation section) most scripts works. *Since the ram size is small some large scrips cannot be loaded and run using this board.

*     UART Terminal connection was problematic: Initial terminal shell was implemented over the UART. When trying to connect to the terminal using a terminal software (e.g. "minicom") resets occurred. Turned out that the UART HW is only partially implemented. Only Rx\Tx lines are supported. Fixed this problem by switching to a serial terminal over the USB HW.

*     USB Connection failed sometimes: The USB connection is very sensitive to delays. Different debug printouts caused problems in connection that was not consistent (only occurred part of the time). Removing the printouts and converting some of the called functions to marco functions to improve delay times solved the problem.

*     XMODEM file transfer failed: Though minicom software printed that the file is being sent no file was received on the board. After a lot of debug, it turned out that the problem was in minicom itself: for some odd reason the package in charge of file transfers (lrzsz) is sometimes not distributed with it. Installing the package (using "sudo apt-get install lrzsz" command) solved this.

Future Work

        The LPC2148 board has little RAM memory, fitting with the minimal requirements. Some of the larger scripts cannot be run due to RAM space limitations, and further RAM optimizations might help in adding further functionality to the project (it seems that RAM optimization is possible).

        As of now, eLua V0.7 was released (the project is based on V0.6). The new eLua version has RPC (remote procedure call) support for embedded devices. It might be very interesting to add RPC support to the LPC2148 board.

        Additional modules including the I2C can be added to the eLua general modules interface and specific modules such as the temperature sensor may also be implemented. Implementing the Ethernet support might be possible using the LPC2148 Eth extension hardware.

License

The project is released with the MIT license it inherited from the eLua base project. Other included components might have different licenses as described in http://www.eluaproject.net/en_overview.html#license. Most components in the code follow the BSD license. Please refer to the license notes in each component for specific details.