diff --git a/examples/lua/Makefile b/examples/lua/Makefile new file mode 100644 index 0000000000..030e7e3d95 --- /dev/null +++ b/examples/lua/Makefile @@ -0,0 +1,65 @@ +APPLICATION = lua + +# If no BOARD is found in the environment, use this default: +BOARD ?= native + +# This has to be the absolute path to the RIOT base directory: +RIOTBASE ?= $(CURDIR)/../.. + +BOARD_INSUFFICIENT_MEMORY := bluepill calliope-mini cc2650-launchpad \ + cc2650stk maple-mini microbit nrf51dongle \ + nucleo-f030r8 nucleo-f031k6 nucleo-f042k6 \ + nucleo-f070rb nucleo-f072rb nucleo-f103rb \ + nucleo-f302r8 nucleo-f303k8 nucleo-f334r8 \ + nucleo-f410rb nucleo-l031k6 nucleo-l053r8 \ + opencm904 spark-core stm32f0discovery + +BOARD_BLACKLIST := arduino-duemilanove arduino-mega2560 arduino-uno \ + chronos jiminy-mega256rfr2 mega-xplained mips-malta \ + msb-430 msb-430h pic32-clicker pic32-wifire telosb \ + waspmote-pro wsn430-v1_3b wsn430-v1_4 z1 + + +# Comment this out to disable code in RIOT that does safety checking +# which is not needed in a production environment but helps in the +# development process: +DEVELHELP ?= 1 + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +USEMODULE += ps + +ifneq ($(BOARD),native) + # This stack size is large enough to run Lua print() functions of + # various lengths. Other functions untested. + CFLAGS += -DTHREAD_STACKSIZE_MAIN=4096 +endif + +USEPKG += lua + +include $(RIOTBASE)/Makefile.include + +# The code below generates a header file from any .lua scripts in the +# example directory. The header file contains a byte array of the +# ASCII characters in the .lua script. + +LUA_PATH := $(BINDIR)/lua + +# add directory of generated *.lua.h files to include path +CFLAGS += -I$(LUA_PATH) + +# generate .lua.h header files of .lua files +LUA = $(wildcard *.lua) + +LUA_H := $(LUA:%.lua=$(LUA_PATH)/%.lua.h) + +$(LUA_PATH)/: + @mkdir -p $@ + +$(LUA_H): | $(LUA_PATH)/ +$(LUA_H): $(LUA_PATH)/%.lua.h: %.lua + + xxd -i $< | sed 's/^unsigned/const/g' > $@ + +$(RIOTBUILD_CONFIG_HEADER_C): $(LUA_H) diff --git a/examples/lua/README.md b/examples/lua/README.md new file mode 100644 index 0000000000..15dd3488f0 --- /dev/null +++ b/examples/lua/README.md @@ -0,0 +1,22 @@ +### About + +This example shows how to write IoT applications using Lua. + +### Caveats + +Currently, the only actual function available is "print" + +### How to use + +Put your lua code into "main.lua" (check the example). The file will +be included in your application as an ASCII byte array. This is done in the +last 20 or so lines of the example's Makefile. + +The script will then be run immediately after RIOT has started up. + +### How to run + +Type `make flash term` + +Note: you may have to press `RESET` on the board (after the flash) if the board +reboots faster than the terminal program can start.. diff --git a/examples/lua/main.c b/examples/lua/main.c new file mode 100644 index 0000000000..22458153e0 --- /dev/null +++ b/examples/lua/main.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2018 FU Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @file + * @brief Basic lua example application + * + * @author Daniel Petry + * + * @} + */ + +#include +#include +#include "lauxlib.h" +#include "lualib.h" + +#include "main.lua.h" + +int lua_run_script(const char *buffer, size_t buffer_len) +{ + + lua_State *L = luaL_newstate(); + + if (L == NULL) { + puts("cannot create state: not enough memory"); + return ENOMEM; + } + + luaL_openlibs(L); + luaL_loadbuffer(L, buffer, buffer_len, "lua input script"); + + if (lua_pcall(L, 0, 0, 0) != LUA_OK){ + puts("Lua script running failed"); + return EINTR; + } + + lua_close(L); + return 0; +} + +int main(void) +{ + puts("Lua RIOT build"); + lua_run_script(main_lua, main_lua_len); + return 0; +} diff --git a/examples/lua/main.lua b/examples/lua/main.lua new file mode 100644 index 0000000000..9b7d28397f --- /dev/null +++ b/examples/lua/main.lua @@ -0,0 +1 @@ +print("Hello world, this is lua!") diff --git a/pkg/lua/Makefile b/pkg/lua/Makefile new file mode 100644 index 0000000000..d2f1a775de --- /dev/null +++ b/pkg/lua/Makefile @@ -0,0 +1,12 @@ +PKG_NAME=lua +PKG_URL=https://github.com/lua/lua.git +PKG_VERSION=e354c6355e7f48e087678ec49e340ca0696725b1 +PKG_LICENSE=MIT + +.PHONY: all + +all: + @cp Makefile.lua $(PKG_BUILDDIR) + "$(MAKE)" -C $(PKG_BUILDDIR) -f Makefile.lua + +include $(RIOTBASE)/pkg/pkg.mk diff --git a/pkg/lua/Makefile.include b/pkg/lua/Makefile.include new file mode 100644 index 0000000000..9fb515a3b4 --- /dev/null +++ b/pkg/lua/Makefile.include @@ -0,0 +1 @@ +INCLUDES += -I$(PKGDIRBASE)/lua diff --git a/pkg/lua/Makefile.lua b/pkg/lua/Makefile.lua new file mode 100644 index 0000000000..f0bd4d8a38 --- /dev/null +++ b/pkg/lua/Makefile.lua @@ -0,0 +1,9 @@ +SRC := $(filter-out lua.c luac.c,$(wildcard *.c)) + +# This builds for native using POSIX system calls and some extra libraries, and +# removes a compiler warning that warns against using tmpnam(). +ifeq ($(BOARD),native) + CFLAGS += -DLUA_USE_LINUX +endif + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/lua/doc.txt b/pkg/lua/doc.txt new file mode 100644 index 0000000000..944d45c632 --- /dev/null +++ b/pkg/lua/doc.txt @@ -0,0 +1,6 @@ +/** + * @defgroup pkg_lua Lua ported to RIOT + * @ingroup pkg + * @brief Provides Lua support for RIOT + * @see https://github.com/lua/lua + */ diff --git a/pkg/lua/patches/0001-Remove-dependency-on-nonexistent-RIOT-syscalls.patch b/pkg/lua/patches/0001-Remove-dependency-on-nonexistent-RIOT-syscalls.patch new file mode 100644 index 0000000000..b4017f5382 --- /dev/null +++ b/pkg/lua/patches/0001-Remove-dependency-on-nonexistent-RIOT-syscalls.patch @@ -0,0 +1,62 @@ +From b681cb20ee6bfc31b8ba23ec321140aae6e53e9d Mon Sep 17 00:00:00 2001 +From: danpetry +Date: Wed, 23 May 2018 14:09:17 +0200 +Subject: [PATCH 1/1] Remove dependency on nonexistent RIOT syscalls + +Os.rename and os.clock, in Lua, now always return an error message. +Also, l_randomizePivot, which is used by table.sort, will always +supply 0 rather than a pseudorandom number. +--- + loslib.c | 7 ++----- + ltablib.c | 4 +++- + 2 files changed, 5 insertions(+), 6 deletions(-) + +diff --git a/loslib.c b/loslib.c +index dd2bb378..f9e5cbd2 100644 +--- a/loslib.c ++++ b/loslib.c +@@ -157,9 +157,7 @@ static int os_remove (lua_State *L) { + + + static int os_rename (lua_State *L) { +- const char *fromname = luaL_checkstring(L, 1); +- const char *toname = luaL_checkstring(L, 2); +- return luaL_fileresult(L, rename(fromname, toname) == 0, NULL); ++ return luaL_error(L, "This function is not implemented in RIOT yet"); + } + + +@@ -181,8 +179,7 @@ static int os_getenv (lua_State *L) { + + + static int os_clock (lua_State *L) { +- lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); +- return 1; ++ return luaL_error(L, "This function is not implemented in RIOT yet"); + } + + +diff --git a/ltablib.c b/ltablib.c +index 588bf40d..8895b653 100644 +--- a/ltablib.c ++++ b/ltablib.c +@@ -235,13 +235,15 @@ static int unpack (lua_State *L) { + /* type for array indices */ + typedef unsigned int IdxT; + +- + /* + ** Produce a "random" 'unsigned int' to randomize pivot choice. This + ** macro is used only when 'sort' detects a big imbalance in the result + ** of a partition. (If you don't want/need this "randomness", ~0 is a + ** good choice.) + */ ++ ++#define l_randomizePivot() 0 ++ + #if !defined(l_randomizePivot) /* { */ + + #include +-- +2.17.0 +