LUA programming language
on LPC2148
A project by:
Dror Marcus & Roza Pogalnikova
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.
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.
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.
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.
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.
· 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.
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.