diff --git a/examples/javascript/Makefile b/examples/javascript/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..1a285d390cf8bf5e59afad7266bbfaead0fd5280 --- /dev/null +++ b/examples/javascript/Makefile @@ -0,0 +1,33 @@ +# application name +APPLICATION = riot_javascript + +# default BOARD environment +BOARD ?= native + +BOARD_INSUFFICIENT_MEMORY := airfy-beacon calliope-mini cc2650stk maple-mini \ + microbit nrf51dongle nrf6310 nucleo-f030 nucleo-f070 \ + nucleo-f072 nucleo-f103 nucleo-f302 nucleo-f334 nucleo-f410 \ + nucleo-l053 nucleo-l073 nucleo32-f031 nucleo32-f042 \ + nucleo32-f303 nucleo32-l031 opencm904 pca10000 \ + pca10005 spark-core stm32f0discovery weio yunjia-nrf51822 \ + +BOARD_BLACKLIST := arduino-duemilanove arduino-mega2560 arduino-uno chronos \ + msb-430 msb-430h qemu-i386 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: +CFLAGS += -DDEVELHELP + +# Set stack size to something (conservatively) enormous +CFLAGS += -DTHREAD_STACKSIZE_MAIN=9092 + +# Add the shell and some shell commands +USEMODULE += shell +USEMODULE += shell_commands + +# Add the package for Jerryscript +USEPKG += jerryscript + +include $(CURDIR)/../../Makefile.include diff --git a/examples/javascript/README.md b/examples/javascript/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4886781423bd39151501d7f3c2c35e3a8ca60ed0 --- /dev/null +++ b/examples/javascript/README.md @@ -0,0 +1,39 @@ +### About + +This example enables to execute arbitrary Javascript directly from the command line on the RIOT shell. + +### Acknowledgement +This example is based on [Jerryscript](https://github.com/jerryscript-project/jerryscript) which does all the heavy lifting, providing full ECMAScript 5.1 profile on your IoT device (kudos guys!). + +### Caveats + +- On your local board: best used with a serial communication program such [minicom](https://help.ubuntu.com/community/Minicom) instead of PyTerm (see why below). + +- On a testbed: you can try it on [IoT-lab](https://www.iot-lab.info). Tested and works so far on [IoT-lab M3](https://www.iot-lab.info/hardware/m3/), upload and flash the .elf, ssh into the node, and script away! + +- Except in the `print` instruction in your script, you have to replace single brackets `'` with `\'`. + +- Expect some issues with PyTerm which interprets by default the first `;` as the end of the script command. Furthermore, if the script is long, PyTerm seems to get confused (hence the recommended use of minicom). To start playing with PyTerm, first edit `;` line 256 of RIOT/dist/tools/pyterm/pyterm + +### How to build + +Type `make flash`. Then use your preferred serial communication tool to land in the RIOT shell. +Note: you may have to type `reboot` or to press `RESET` on the board (after the flash). + +### Running the example + +In the RIOT shell, `help` will provide the list of available commands. + +The `script` command will run the test script code that you input in the command line. +Some examples of scripts you can try: +``` +script print ('hello'); +``` +``` +script var x = Math.sqrt (64); var txt = \'\'; while (x>1) { txt += --x + \'\\n\';} print (txt); +``` +``` +script var person = { fname:\'John\', lname:\'Doe\', age:25 }; var text = \'\'; var x; for (x in person) { text += person[x] + \'\\n\'; } print (text); +``` + +Remark: outside of the print command, you may have to replace single brackets ' with \'. \ No newline at end of file diff --git a/examples/javascript/main.c b/examples/javascript/main.c new file mode 100644 index 0000000000000000000000000000000000000000..ae1b162bc25f3a402238d88d05f577d0e24eb414 --- /dev/null +++ b/examples/javascript/main.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2017 Inria + * + * 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 Showing an example of scripting (javascript) from command line + * + * @author Emmanuel Baccelli <emmanuel.baccelli@inria.fr> + * + * @} + */ + +#include <string.h> +#include "shell.h" +#include "jerryscript.h" + +int shell_script(int argc, char **argv) +{ + if (argc < 2) { + puts("Usage: script <your script here!> \n" + "For example, try: \n" + "script var txt = \\'\\'; txt += Math.PI; print (\\'Pi=\\'+txt); \n" + "Note: you need to substitute usual quotes with \\' \n"); + return -1; + } + + jerry_char_t script[(2 * SHELL_DEFAULT_BUFSIZE + 1)]; + *script = '\0'; + for(int i = 1; i < argc; i++) { + if (i>1) { + strcat((char *)script, " "); + } + strcat((char *)script, argv[i]); + } + + size_t script_size = strlen((char *) script); + printf("Executing script: [%s]\n\n", script); + bool ret_value = jerry_run_simple(script, script_size, JERRY_INIT_EMPTY); + + return (ret_value != 0); +} + +const shell_command_t shell_commands[] = { + { "script", "Shell scripting ", shell_script }, + { NULL, NULL, NULL } +}; + +int main(void) +{ + printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD); + printf("This board features a(n) %s MCU.\n", RIOT_MCU); + + /* start the shell */ + char line_buf[2 * SHELL_DEFAULT_BUFSIZE]; + /* for longer script support shell buffer should be bigger */ + shell_run(shell_commands, line_buf, sizeof(line_buf)); + + return 0; +} diff --git a/pkg/jerryscript/Makefile b/pkg/jerryscript/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..b43d427ce77c517593ba41c2f334a6d0eb87ad20 --- /dev/null +++ b/pkg/jerryscript/Makefile @@ -0,0 +1,13 @@ +PKG_NAME=jerryscript +PKG_URL=https://github.com/jerryscript-project/jerryscript.git +PKG_VERSION=b140158104064ef082ddb58052f8c7c7cee9675c +PKG_LICENSE=Apache-2.0 + +.PHONY: all + +all: git-download + @cp Makefile.jerryscript $(PKG_BUILDDIR)/Makefile + $(MAKE) -C $(PKG_BUILDDIR) + cp $(PKG_BUILDDIR)/riot/lib/libjerry-core.a ${BINDIR}/libjerrycore.a + +include $(RIOTBASE)/pkg/pkg.mk diff --git a/pkg/jerryscript/Makefile.include b/pkg/jerryscript/Makefile.include new file mode 100644 index 0000000000000000000000000000000000000000..557b55a3c8bb7e5c7e055ad2b231bb6b774f864e --- /dev/null +++ b/pkg/jerryscript/Makefile.include @@ -0,0 +1 @@ +INCLUDES += -I$(PKGDIRBASE)/jerryscript/jerry-core/ diff --git a/pkg/jerryscript/Makefile.jerryscript b/pkg/jerryscript/Makefile.jerryscript new file mode 100644 index 0000000000000000000000000000000000000000..43b47dbda7707e79ca9b142cc7b647849ad5e1ee --- /dev/null +++ b/pkg/jerryscript/Makefile.jerryscript @@ -0,0 +1,31 @@ +BUILD_DIR ?= $(CURDIR)/riot + +JERRYHEAP ?= 16 + + EXT_CFLAGS :=-D__TARGET_RIOT + + EXT_CFLAGS += $(CFLAGS) + +.PHONY: libjerry riot-jerry flash clean + +# all: libjerry riot-jerry + +libjerry: + mkdir -p $(BUILD_DIR) + cmake -B$(BUILD_DIR) -H./ \ + -DENABLE_LTO=OFF \ + -DFEATURE_VALGRIND=OFF \ + -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain_external.cmake \ + -DJERRY_LIBC=OFF \ + -DJERRY_CMDLINE=OFF \ + -DENABLE_ALL_IN_ONE=OFF \ + -DEXTERNAL_CMAKE_SYSTEM_PROCESSOR="$(MCPU)" \ + -DEXTERNAL_CMAKE_C_COMPILER=$(CC) \ + -DEXTERNAL_CMAKE_C_COMPILER_ID=GNU \ + -DEXTERNAL_COMPILE_FLAGS="$(EXT_CFLAGS)" \ + -DMEM_HEAP_SIZE_KB=$(JERRYHEAP) + + make -C $(BUILD_DIR) jerry-core + cp $(BUILD_DIR)/lib/libjerry-core.a $(BINDIR)/jerryscript.a + +include $(RIOTBASE)/Makefile.base