Skip to content

Lua support #8434

@danpetry

Description

@danpetry

Description

There is an external developer who wants to build a modular piece of hardware with a coprocessor running RIOT, with potential to be a commercial product. For this, he wishes to use Lua to control part of it, and therefore Lua support could enable commercial use of RIOT. Additionally, dynamic language support (see also #7796 and #2968) could be an approach to achieve over-the-air update of an application and a multi-application development paradigm for the RAPstore project (RIOT app store).

There is a benefit/cost tradeoff: the above description is the benefit, and time spent to implement Lua support (and eg not develop other features) is the cost. Therefore part of the earlier stages of development will be to judge the total amount of time that would be required.

Approach

The current approach followed is to adapt other FOSS projects which have implemented Lua in an embedded context. The ones that have been considered are as follows.

  1. Currently the most promising vector of approach seems to be to use the LuaRTOS project, where the Lua engine has been implemented on top of FreeRTOS, including a range of API bindings we would need to implement such as I2C, ADCs, and LoRAWAN. They have implemented supporting threads which can handle concurrent Lua programs with the same Lua state. The project would probably be pretty stable (as it is developed by a company, Whitecat, and used in their commercial product), and it is currently under active development. It also uses Google Blockly, a simple graphical programming language which is being considered to develop RIOT programs in Javascript. It uses a BSD license and the build system is based on Make.

  2. NutOS also includes a Lua interpreter on top of an RTOS. It also uses a BSD license and a make-based build system. However, the Lua engine is not under current development (with the last substantial work done in 2012) and it seems that there is no implementation of supporting threads, just a callable library of functions.

  3. eLua, a standalone Lua runtime environment for embedded devices, was also investigated in some detail. However, it was clear that the Lua interpreter was not designed to be separated from the rest of the program (which was designed to be loaded onto a microchip on its own, not used on top of an RTOS). Some of the reasons for this, along with other reasons that suggested that eLua wouldn't be a suitable approach, are as follows:

    • eLua is very ingrained in its own build system and intended to be built as a whole with it, which means that picking components out and building them separately was difficult. I tried porting using the eLua build system but came across an issue where there were symbols defined in the eLua linker files which were used in core functions. Which meant that I couldn't link the generated object files with the rest of RIOT using the RIOT build system. This was found fairly immediately and suggested that it wouldn't have been the only issue I would have come across by using this approach.

    • The eLua build system is based on Lua and depends on some Lua libraries too, introducing several dependencies for users to use this library.

    • I also tried using RIOT's build system to build using source files from eLua. As would be expected there were a range of errors to sort out including eLua specific typedefs, #defines, generated header files, and cflags, so this would also have proved to be a lot of work.

    • The eLua "sim" configuration, which is their simulator which runs on Linux, is currently not working. This is because eLua has a dependency on newlib, which doesn't work on Linux. Someone tried "hard" to fix this but failed: reent.h is missing elua/elua#108. This makes a port to RIOT native difficult

Design and implementation

Currently, development is proceeding using LuaRTOS as a starting point. As a very high level set of milestones, the approach will be as follows:

  1. Get the relevant LuaRTOS files building into a binary with the rest of RIOT
  2. Get a simple Lua function working (e.g. serial print or LED flash)
  3. Implement the RIOT API bindings

Regarding how the lua commands and code are input, there are a few options:

  • manual input via RIOT shell
  • lua scripts in an example directory at compile time
  • lua scripts able to be dynamically loaded into RAM

Which of these are going to be implemented needs considering

Issues

  • Lua is an interpreted language, which inherently requires dynamic allocation, in case e.g. callbacks are redefined during runtime. We try and avoid dynamic memory allocation as far as possible. We should keep an eye on how Lua handles this without potentally running out of heap space.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type: new featureThe issue requests / The PR implemements a new feature for RIOT

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions