From 454d3af95168259d620ee7c4965dd3ec5fc179a6 Mon Sep 17 00:00:00 2001 From: Matthew Else Date: Wed, 21 Sep 2016 14:48:03 +0100 Subject: [PATCH] Initial support for mbed OS 5.1 (#1318) - Wrappers for mbed I/O drivers - Makefile for automating build process - Script to generate pin definitions from mbed OS source tree - Updates to js2c to enable building without a main.js file JerryScript-DCO-1.0-Signed-off-by: Matthew Else Matthew.Else@arm.com --- .gitignore | 2 +- targets/mbedos5/.gitignore | 8 + targets/mbedos5/Makefile | 89 ++++++ targets/mbedos5/README.md | 75 +++++ .../jerryscript-mbed-drivers/DigitalOut-js.h | 22 ++ .../jerryscript-mbed-drivers/I2C-js.h | 22 ++ .../jerryscript-mbed-drivers/InterruptIn-js.h | 22 ++ .../jerryscript-mbed-drivers/assert-js.h | 23 ++ .../jerryscript-mbed-drivers/gc-js.h | 23 ++ .../jerryscript-mbed-drivers/lib_drivers.h | 36 +++ .../jerryscript-mbed-drivers/setInterval-js.h | 22 ++ .../jerryscript-mbed-drivers/setTimeout-js.h | 22 ++ .../source/DigitalOut.cpp | 131 +++++++++ .../jerryscript-mbed-drivers/source/I2C.cpp | 270 ++++++++++++++++++ .../source/InterruptIn.cpp | 218 ++++++++++++++ .../source/assert.cpp | 34 +++ .../jerryscript-mbed-drivers/source/gc.cpp | 25 ++ .../source/setInterval.cpp | 36 +++ .../source/setTimeout.cpp | 37 +++ .../BoundCallback.h | 114 ++++++++ .../jerryscript-mbed-event-loop/EventLoop.h | 104 +++++++ .../source/EventLoop.cpp | 27 ++ .../jerryscript-mbed-launcher/launcher.h | 21 ++ .../jerryscript-mbed-launcher/setup.h | 22 ++ .../source/launcher.cpp | 90 ++++++ .../source/setup.cpp | 49 ++++ .../registry.h | 57 ++++ .../source/registry.cpp | 17 ++ .../source/wrap_tools.cpp | 78 +++++ .../wrap_tools.h | 43 +++ .../jerryscript-mbed-util/js_source.h | 24 ++ .../jerryscript-mbed-util/logging.h | 26 ++ .../jerryscript-mbed-util/wrappers.h | 93 ++++++ targets/mbedos5/js/flash_leds.js | 76 +++++ targets/mbedos5/js/main.js | 20 ++ targets/mbedos5/mbed-events.lib | 1 + targets/mbedos5/mbed-os.lib | 1 + targets/mbedos5/mbed_app.json | 7 + targets/mbedos5/source/jerry_port_mbed.c | 85 ++++++ targets/mbedos5/source/main.cpp | 48 ++++ targets/mbedos5/template-mbedignore.txt | 8 + targets/mbedos5/tools/check_pins.sh | 31 ++ targets/mbedos5/tools/cmsis.h | 17 ++ targets/mbedos5/tools/generate_pins.py | 224 +++++++++++++++ targets/mbedos5/tools/jshint.conf | 4 + targets/mbedos5/tools/requirements.txt | 3 + targets/tools/js2c.py | 30 +- 47 files changed, 2427 insertions(+), 10 deletions(-) create mode 100644 targets/mbedos5/.gitignore create mode 100644 targets/mbedos5/Makefile create mode 100644 targets/mbedos5/README.md create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/DigitalOut-js.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/I2C-js.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/InterruptIn-js.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/assert-js.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/gc-js.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/lib_drivers.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/setInterval-js.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/setTimeout-js.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/DigitalOut.cpp create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/I2C.cpp create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/InterruptIn.cpp create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/assert.cpp create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/gc.cpp create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/setInterval.cpp create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/setTimeout.cpp create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-event-loop/BoundCallback.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-event-loop/EventLoop.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-event-loop/source/EventLoop.cpp create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/launcher.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/setup.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/source/launcher.cpp create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/source/setup.cpp create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/registry.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/source/registry.cpp create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/source/wrap_tools.cpp create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/wrap_tools.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-util/js_source.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-util/logging.h create mode 100644 targets/mbedos5/jerryscript-mbed/jerryscript-mbed-util/wrappers.h create mode 100644 targets/mbedos5/js/flash_leds.js create mode 100644 targets/mbedos5/js/main.js create mode 100644 targets/mbedos5/mbed-events.lib create mode 100644 targets/mbedos5/mbed-os.lib create mode 100644 targets/mbedos5/mbed_app.json create mode 100644 targets/mbedos5/source/jerry_port_mbed.c create mode 100644 targets/mbedos5/source/main.cpp create mode 100644 targets/mbedos5/template-mbedignore.txt create mode 100755 targets/mbedos5/tools/check_pins.sh create mode 100644 targets/mbedos5/tools/cmsis.h create mode 100644 targets/mbedos5/tools/generate_pins.py create mode 100644 targets/mbedos5/tools/jshint.conf create mode 100644 targets/mbedos5/tools/requirements.txt diff --git a/.gitignore b/.gitignore index da51a4dc1..3acc32791 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # Produced files - +.mbedignore build/* # IDE related files diff --git a/targets/mbedos5/.gitignore b/targets/mbedos5/.gitignore new file mode 100644 index 000000000..a432fa5ba --- /dev/null +++ b/targets/mbedos5/.gitignore @@ -0,0 +1,8 @@ +mbed-os +mbed-events +.build +.mbed +mbed_settings.py +js/pins.js +source/pins.cpp +source/jerry_targetjs.h diff --git a/targets/mbedos5/Makefile b/targets/mbedos5/Makefile new file mode 100644 index 000000000..0a0a105c1 --- /dev/null +++ b/targets/mbedos5/Makefile @@ -0,0 +1,89 @@ +# Copyright (c) 2016 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# USAGE: +# specify the board using the command line: +# make BOARD=[mbed board name] + +BOARD=$(subst [mbed] ,,$(shell mbed target)) +HEAPSIZE=16 + +DEBUG=0 +NO_JS=0 +MBED_VERBOSE=0 + +MBED_CLI_FLAGS=-j0 --source . --source ../../ + +EXTRA_SRC= + +ifneq ($(EXTRA_SRC),) +EXTRA_SRC_MOD=--source $(subst :, --source ,$(EXTRA_SRC)) +MBED_CLI_FLAGS += $(EXTRA_SRC_MOD) +endif + +EXTERN_BUILD_DIR= + +ifneq ($(EXTERN_BUILD_DIR),) +MBED_CLI_FLAGS += --build $(EXTERN_BUILD_DIR) +endif + +ifeq ($(DEBUG), 1) +MBED_CLI_FLAGS += -o debug-info +endif + +ifeq ($(MBED_VERBOSE), 1) +MBED_CLI_FLAGS += -v +else ifeq ($(MBED_VERBOSE), 2) +MBED_CLI_FLAGS += -vv +endif + +MBED_CLI_FLAGS += -D "CONFIG_MEM_HEAP_AREA_SIZE=(1024*$(HEAPSIZE))" +MBED_CLI_FLAGS += -t GCC_ARM + +.PHONY: all js2c getlibs rebuild library +all: source/jerry_targetjs.h source/pins.cpp .mbed ../../.mbedignore + mbed target $(BOARD) + mbed compile $(MBED_CLI_FLAGS) + +library: .mbed ../../.mbedignore + # delete encoded js code if it exists + rm -f source/jerry_targetjs.h + mbed target $(BOARD) + mbed compile $(MBED_CLI_FLAGS) --library + +clean: + rm -rf .build/$(BOARD) + +js2c: js/main.js js/flash_leds.js + python ../tools/js2c.py --ignore pins.js + +source/pins.cpp: + python tools/generate_pins.py ${BOARD} + +ifeq ($(NO_JS),0) +source/jerry_targetjs.h: js2c +else +source/jerry_targetjs.h: ; +endif + +getlibs: .mbed + +.mbed: + mbed config root . + mbed toolchain GCC_ARM + mbed target $(BOARD) + mbed deploy + +../../.mbedignore: + cp ./template-mbedignore.txt ../../.mbedignore diff --git a/targets/mbedos5/README.md b/targets/mbedos5/README.md new file mode 100644 index 000000000..bd72e52e0 --- /dev/null +++ b/targets/mbedos5/README.md @@ -0,0 +1,75 @@ +# JerryScript with mbed OS 5 + +TL;DR? jump straight to [quickstart](#quick-start) + +## Introduction + +This directory contains the necessary code to build JerryScript for devices +capable of running mbed OS 5. It has been tested with the following boards +so far: + +- [Nordic Semiconductor NRF52 Development Kit](https://developer.mbed.org/platforms/Nordic-nRF52-DK/) +- [NXP Freedom K64F](https://developer.mbed.org/platforms/FRDM-K64F/) +- [STM NUCLEO F401RE](https://developer.mbed.org/platforms/ST-Nucleo-F401RE/) +- [Silicon Labs EFM32 Giant Gecko](https://developer.mbed.org/platforms/EFM32-Giant-Gecko/) + +## Features + +### Peripheral Drivers + +Peripheral Drivers are intended as a 1-to-1 mapping to mbed C++ APIs, with a few +differences (due to differences between JavaScript and C++ like lack of operator +overloading). + +- [DigitalOut](https://docs.mbed.com/docs/mbed-os-api-reference/en/5.1/APIs/io/DigitalOut/) +- [InterruptIn](https://docs.mbed.com/docs/mbed-os-api-reference/en/5.1/APIs/io/InterruptIn/) +- [I2C](https://docs.mbed.com/docs/mbed-os-api-reference/en/5.1/APIs/interfaces/digital/I2C/) +- setInterval and setTimeout using [mbed-event](https://github.com/ARMmbed/mbed-events) + +## Dependencies + +### mbed CLI + +mbed CLI is used as the build tool for mbed OS 5. You can find out how to install +it in the [official documentation](https://docs.mbed.com/docs/mbed-os-handbook/en/5.1/dev_tools/cli/#installing-mbed-cli). + +### arm-none-eabi-gcc + +arm-none-eabi-gcc is the only currently tested compiler for jerryscript on mbed, +and instructions for building can be found as part of the mbed-cli installation +instructions above. + +### make + +make is used to automate the process of fetching dependencies, and making sure that +mbed-cli is called with the correct arguments. + +### (optional) jshint + +jshint is used to statically check your JavaScript code, as part of the build process. +This ensures that pins you are using in your code are available on your chosen target +platform. + +## Quick Start + +Once you have all of your dependencies installed, you can build the project as follows: + +```bash +git clone https://github.com/Samsung/jerryscript +cd jerryscript/targets/mbedos5 +make getlibs +# NRF52 Development Kit: +make BOARD=NRF52_DK +# FRDM K64F +make BOARD=K64F +``` + +The produced file (in .build/**[BOARD]**/GCC_ARM) can then be uploaded to your board, and will +run when you press reset. + +If you make a modification to main.js, you can simply rerun make, and it will remember your +previous choice of board: + +```bash +make +``` diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/DigitalOut-js.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/DigitalOut-js.h new file mode 100644 index 000000000..a9bf1a660 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/DigitalOut-js.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_DRIVERS_DIGITALOUT_H +#define _JERRYSCRIPT_MBED_DRIVERS_DIGITALOUT_H + +#include "jerryscript-mbed-library-registry/wrap_tools.h" + +DECLARE_CLASS_CONSTRUCTOR(DigitalOut); + +#endif // _JERRYSCRIPT_MBED_DRIVERS_DIGITALOUT_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/I2C-js.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/I2C-js.h new file mode 100644 index 000000000..74f4c952f --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/I2C-js.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_DRIVERS_I2C_H +#define _JERRYSCRIPT_MBED_DRIVERS_I2C_H + +#include "jerryscript-mbed-library-registry/wrap_tools.h" + +DECLARE_CLASS_CONSTRUCTOR(I2C); + +#endif // _JERRYSCRIPT_MBED_DRIVERS_I2C_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/InterruptIn-js.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/InterruptIn-js.h new file mode 100644 index 000000000..f3c363089 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/InterruptIn-js.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_DRIVERS_INTERRUPTIN_H +#define _JERRYSCRIPT_MBED_DRIVERS_INTERRUPTIN_H + +#include "jerryscript-mbed-library-registry/wrap_tools.h" + +DECLARE_CLASS_CONSTRUCTOR(InterruptIn); + +#endif // _JERRYSCRIPT_MBED_DRIVERS_INTERRUPTIN_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/assert-js.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/assert-js.h new file mode 100644 index 000000000..5cbc592a7 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/assert-js.h @@ -0,0 +1,23 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_DRIVERS_ASSERT_H +#define _JERRYSCRIPT_MBED_DRIVERS_ASSERT_H + +#include "jerryscript-mbed-library-registry/wrap_tools.h" +#include "jerryscript-mbed-util/logging.h" + +DECLARE_GLOBAL_FUNCTION(assert); + +#endif // _JERRYSCRIPT_MBED_DRIVERS_ASSERT_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/gc-js.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/gc-js.h new file mode 100644 index 000000000..bfffcd669 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/gc-js.h @@ -0,0 +1,23 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_DRIVERS_GC_H +#define _JERRYSCRIPT_MBED_DRIVERS_GC_H + +#include "jerryscript-mbed-library-registry/wrap_tools.h" +#include "jerryscript-mbed-util/logging.h" + +DECLARE_GLOBAL_FUNCTION(gc); + +#endif // _JERRYSCRIPT_MBED_DRIVERS_GC_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/lib_drivers.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/lib_drivers.h new file mode 100644 index 000000000..52978b044 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/lib_drivers.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_DRIVERS_LIB_DRIVERS_H +#define _JERRYSCRIPT_MBED_DRIVERS_LIB_DRIVERS_H + +#include "jerryscript-mbed-drivers/InterruptIn-js.h" +#include "jerryscript-mbed-drivers/DigitalOut-js.h" +#include "jerryscript-mbed-drivers/setInterval-js.h" +#include "jerryscript-mbed-drivers/setTimeout-js.h" +#include "jerryscript-mbed-drivers/assert-js.h" +#include "jerryscript-mbed-drivers/I2C-js.h" +#include "jerryscript-mbed-drivers/gc-js.h" + +DECLARE_JS_WRAPPER_REGISTRATION (base) { + REGISTER_GLOBAL_FUNCTION(assert); + REGISTER_GLOBAL_FUNCTION(gc); + REGISTER_GLOBAL_FUNCTION(setInterval); + REGISTER_GLOBAL_FUNCTION(setTimeout); + REGISTER_CLASS_CONSTRUCTOR(DigitalOut); + REGISTER_CLASS_CONSTRUCTOR(I2C); + REGISTER_CLASS_CONSTRUCTOR(InterruptIn); +} + +#endif // _JERRYSCRIPT_MBED_DRIVERS_LIB_DRIVERS_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/setInterval-js.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/setInterval-js.h new file mode 100644 index 000000000..255af2523 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/setInterval-js.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_DRIVERS_SET_INTERVAL_H +#define _JERRYSCRIPT_MBED_DRIVERS_SET_INTERVAL_H + +#include "jerryscript-mbed-library-registry/wrap_tools.h" + +DECLARE_GLOBAL_FUNCTION(setInterval); + +#endif // _JERRYSCRIPT_MBED_DRIVERS_SET_INTERVAL_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/setTimeout-js.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/setTimeout-js.h new file mode 100644 index 000000000..d3812cbcb --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/setTimeout-js.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_DRIVERS_SET_TIMEOUT_H +#define _JERRYSCRIPT_MBED_DRIVERS_SET_TIMEOUT_H + +#include "jerryscript-mbed-library-registry/wrap_tools.h" + +DECLARE_GLOBAL_FUNCTION(setTimeout); + +#endif // _JERRYSCRIPT_MBED_DRIVERS_SET_TIMEOUT_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/DigitalOut.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/DigitalOut.cpp new file mode 100644 index 000000000..919ec3d8e --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/DigitalOut.cpp @@ -0,0 +1,131 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "jerryscript-mbed-util/logging.h" +#include "jerryscript-mbed-library-registry/wrap_tools.h" + +#include "mbed.h" + +/** + * DigitalOut#write (native JavaScript method) + * + * Writes a binary value to a DigitalOut. + * + * @param value 1 or 0, specifying whether the output pin is high or low, + * respectively + * @returns undefined, or an error if invalid arguments are provided. + */ +DECLARE_CLASS_FUNCTION(DigitalOut, write) { + CHECK_ARGUMENT_COUNT(DigitalOut, write, (args_count == 1)); + CHECK_ARGUMENT_TYPE_ALWAYS(DigitalOut, write, 0, number); + + // Extract native DigitalOut pointer + uintptr_t ptr_val; + jerry_get_object_native_handle(this_obj, &ptr_val); + + DigitalOut* native_ptr = reinterpret_cast(ptr_val); + + int arg0 = jerry_get_number_value(args[0]); + native_ptr->write(arg0); + + return jerry_create_undefined(); +} + +/** + * DigitalOut#read (native JavaScript method) + * + * Reads the current status of a DigitalOut + * + * @returns 1 if the pin is currently high, or 0 if the pin is currently low. + */ +DECLARE_CLASS_FUNCTION(DigitalOut, read) { + CHECK_ARGUMENT_COUNT(DigitalOut, read, (args_count == 0)); + + // Extract native DigitalOut pointer + uintptr_t ptr_val; + jerry_get_object_native_handle(this_obj, &ptr_val); + + DigitalOut* native_ptr = reinterpret_cast(ptr_val); + + int result = native_ptr->read(); + return jerry_create_number(result); +} + +/** + * DigitalOut#is_connected (native JavaScript method) + * + * @returns 0 if the DigitalOut is set to NC, or 1 if it is connected to an + * actual pin + */ +DECLARE_CLASS_FUNCTION(DigitalOut, is_connected) { + CHECK_ARGUMENT_COUNT(DigitalOut, is_connected, (args_count == 0)); + + // Extract native DigitalOut pointer + uintptr_t ptr_val; + jerry_get_object_native_handle(this_obj, &ptr_val); + + DigitalOut* native_ptr = reinterpret_cast(ptr_val); + + int result = native_ptr->is_connected(); + return jerry_create_number(result); +} + +/** + * DigitalOut#destructor + * + * Called if/when the DigitalOut is GC'ed. + */ +void NAME_FOR_CLASS_NATIVE_DESTRUCTOR(DigitalOut)(const uintptr_t native_handle) { + delete reinterpret_cast(native_handle); +} + +/** + * DigitalOut (native JavaScript constructor) + * + * @param pin_name mbed pin to connect the DigitalOut to. + * @param value (optional) Initial value of the DigitalOut. + * @returns a JavaScript object representing a DigitalOut. + */ +DECLARE_CLASS_CONSTRUCTOR(DigitalOut) { + CHECK_ARGUMENT_COUNT(DigitalOut, __constructor, (args_count == 1 || args_count == 2)); + CHECK_ARGUMENT_TYPE_ALWAYS(DigitalOut, __constructor, 0, number); + CHECK_ARGUMENT_TYPE_ON_CONDITION(DigitalOut, __constructor, 1, number, (args_count == 2)); + + uintptr_t native_ptr; + + // Call correct overload of DigitalOut::DigitalOut depending on the + // arguments passed. + PinName pin_name = PinName(jerry_get_number_value(args[0])); + + switch (args_count) { + case 1: + native_ptr = (uintptr_t) new DigitalOut(pin_name); + break; + case 2: + int value = static_cast(jerry_get_number_value(args[1])); + native_ptr = (uintptr_t) new DigitalOut(pin_name, value); + break; + } + + // create the jerryscript object + jerry_value_t js_object = jerry_create_object(); + jerry_set_object_native_handle(js_object, native_ptr, NAME_FOR_CLASS_NATIVE_DESTRUCTOR(DigitalOut)); + + // attach methods + ATTACH_CLASS_FUNCTION(js_object, DigitalOut, write); + ATTACH_CLASS_FUNCTION(js_object, DigitalOut, read); + ATTACH_CLASS_FUNCTION(js_object, DigitalOut, is_connected); + + return js_object; +} diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/I2C.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/I2C.cpp new file mode 100644 index 000000000..2c080532b --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/I2C.cpp @@ -0,0 +1,270 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "jerryscript-mbed-util/logging.h" +#include "jerryscript-mbed-drivers/I2C-js.h" +#include "jerryscript-mbed-library-registry/wrap_tools.h" + +#include "mbed.h" + +/** + * I2C#frequency (native JavaScript method) + * + * Set the frequency of the I2C bus. + * + * @param frequency New I2C Frequency + */ +DECLARE_CLASS_FUNCTION(I2C, frequency) { + CHECK_ARGUMENT_COUNT(I2C, frequency, (args_count == 1)); + CHECK_ARGUMENT_TYPE_ALWAYS(I2C, frequency, 0, number); + + // Unwrap native I2C object + uintptr_t native_handle; + jerry_get_object_native_handle(this_obj, &native_handle); + I2C* native_ptr = reinterpret_cast(native_handle); + + int hz = jerry_get_number_value(args[0]); + native_ptr->frequency(hz); + + return jerry_create_undefined(); +} + +/** + * I2C#read (native JavaScript method) + * + * Read data from the I2C bus. + * + * @overload I2C#read(int) + * Read a single byte from the I2C bus + * + * @param ack indicates if the byte is to be acknowledged (1 => acknowledge) + * + * @returns array: Data read from the I2C bus + * + * @overload I2C#read(int, array, int) + * Read a series of bytes from the I2C bus + * + * @param address I2C address to read from + * @param data Array to read into + * @param length Length of data to read + * + * @returns array: Data read from the I2C bus + */ +DECLARE_CLASS_FUNCTION(I2C, read) { + CHECK_ARGUMENT_COUNT(I2C, read, (args_count == 1 || args_count == 3 || args_count == 4)); + + if (args_count == 1) { + CHECK_ARGUMENT_TYPE_ALWAYS(I2C, read, 0, number); + uintptr_t native_handle; + jerry_get_object_native_handle(this_obj, &native_handle); + I2C *native_ptr = reinterpret_cast(native_handle); + + int data = jerry_get_number_value(args[0]); + int result = native_ptr->read(data); + + return jerry_create_number(result); + } else { + CHECK_ARGUMENT_TYPE_ALWAYS(I2C, read, 0, number); + CHECK_ARGUMENT_TYPE_ALWAYS(I2C, read, 1, array); + CHECK_ARGUMENT_TYPE_ALWAYS(I2C, read, 2, number); + + CHECK_ARGUMENT_TYPE_ON_CONDITION(I2C, read, 3, boolean, (args_count == 4)); + + uintptr_t native_handle; + jerry_get_object_native_handle(this_obj, &native_handle); + I2C *native_ptr = reinterpret_cast(native_handle); + + const uint32_t data_len = jerry_get_array_length(args[1]); + + int address = jerry_get_number_value(args[0]); + int length = jerry_get_number_value(args[2]); + + char *data = new char[data_len]; + + bool repeated = false; + if (args_count == 4) { + repeated = jerry_get_boolean_value(args[3]); + } + + int result = native_ptr->read(address, data, length, repeated); + + jerry_value_t out_array = jerry_create_array(data_len); + + for (uint32_t i = 0; i < data_len; i++) { + jerry_value_t val = jerry_create_number(double(data[i])); + jerry_set_property_by_index(out_array, i, val); + jerry_release_value(val); + } + + delete[] data; + + if (result == 0) { + // ACK + return out_array; + } else { + // NACK + const char *error_msg = "NACK received from I2C bus"; + + jerry_release_value(out_array); + return jerry_create_error(JERRY_ERROR_COMMON, reinterpret_cast(error_msg)); + } + } +} + +/** + * I2C#write (native JavaScript method) + * + * @overload I2C#write(int) + * Write a single byte to the I2C bus + * + * @param data Data byte to write to the I2C bus + * + * @returns 1 on success, 0 on failure + * + * @overload I2C#write(int, array, int, bool) + * Write an array of data to a certain address on the I2C bus + * + * @param address 8-bit I2C slave address + * @param data Array of bytes to send + * @param length Length of data to write + * @param repeated (optional) If true, do not send stop at end. + * + * @returns 0 on success, non-0 on failure + */ +DECLARE_CLASS_FUNCTION(I2C, write) { + CHECK_ARGUMENT_COUNT(I2C, write, (args_count == 1 || args_count == 3 || args_count == 4)); + + if (args_count == 1) { + CHECK_ARGUMENT_TYPE_ALWAYS(I2C, write, 0, number); + + // Extract native I2C object + uintptr_t native_handle; + jerry_get_object_native_handle(this_obj, &native_handle); + + I2C *native_ptr = reinterpret_cast(native_handle); + + // Unwrap arguments + int data = jerry_get_number_value(args[0]); + + int result = native_ptr->write(data); + return jerry_create_number(result); + } else { + // 3 or 4 + CHECK_ARGUMENT_TYPE_ALWAYS(I2C, write, 0, number); + CHECK_ARGUMENT_TYPE_ALWAYS(I2C, write, 1, array); + CHECK_ARGUMENT_TYPE_ALWAYS(I2C, write, 2, number); + CHECK_ARGUMENT_TYPE_ON_CONDITION(I2C, write, 3, boolean, (args_count == 4)); + + // Extract native I2C object + uintptr_t native_handle; + jerry_get_object_native_handle(this_obj, &native_handle); + + I2C *native_ptr = reinterpret_cast(native_handle); + + // Unwrap arguments + int address = jerry_get_number_value(args[0]); + const uint32_t data_len = jerry_get_array_length(args[1]); + int length = jerry_get_number_value(args[2]); + bool repeated = args_count == 4 && jerry_get_boolean_value(args[3]); + + // Construct data byte array + char *data = new char[data_len]; + for (uint32_t i = 0; i < data_len; i++) { + data[i] = jerry_get_number_value(jerry_get_property_by_index(args[1], i)); + } + + int result = native_ptr->write(address, data, length, repeated); + + // free dynamically allocated resources + delete[] data; + + return jerry_create_number(result); + } +} + +/** + * I2C#start (native JavaScript method) + * + * Creates a start condition on the I2C bus. + */ +DECLARE_CLASS_FUNCTION(I2C, start) +{ + CHECK_ARGUMENT_COUNT(I2C, start, (args_count == 0)); + + // Extract native I2C object + uintptr_t native_handle; + jerry_get_object_native_handle(this_obj, &native_handle); + + I2C *native_ptr = reinterpret_cast(native_handle); + + native_ptr->start(); + return jerry_create_undefined(); +} + +/** + * I2C#stop (native JavaScript method) + * + * Creates a stop condition on the I2C bus. + */ +DECLARE_CLASS_FUNCTION(I2C, stop) +{ + CHECK_ARGUMENT_COUNT(I2C, stop, (args_count == 0)); + + // Extract native I2C object + uintptr_t native_handle; + jerry_get_object_native_handle(this_obj, &native_handle); + + I2C *native_ptr = reinterpret_cast(native_handle); + + native_ptr->stop(); + return jerry_create_undefined(); +} + +/** + * I2C#destructor + * + * Called if/when the I2C object is GC'ed. + */ +void NAME_FOR_CLASS_NATIVE_DESTRUCTOR(I2C) (uintptr_t handle) { + delete reinterpret_cast(handle); +} + +/** + * I2C (native JavaScript constructor) + * + * @param sda mbed pin for I2C data + * @param scl mbed pin for I2C clock + * @returns a JavaScript object representing the I2C bus. + */ +DECLARE_CLASS_CONSTRUCTOR(I2C) { + CHECK_ARGUMENT_COUNT(I2C, __constructor, (args_count == 2)); + CHECK_ARGUMENT_TYPE_ALWAYS(I2C, __constructor, 0, number); + CHECK_ARGUMENT_TYPE_ALWAYS(I2C, __constructor, 1, number); + + int sda = jerry_get_number_value(args[0]); + int scl = jerry_get_number_value(args[1]); + + uintptr_t native_handle = (uintptr_t)new I2C((PinName)sda, (PinName)scl); + + jerry_value_t js_object = jerry_create_object(); + jerry_set_object_native_handle(js_object, native_handle, NAME_FOR_CLASS_NATIVE_DESTRUCTOR(I2C)); + + ATTACH_CLASS_FUNCTION(js_object, I2C, frequency); + ATTACH_CLASS_FUNCTION(js_object, I2C, read); + ATTACH_CLASS_FUNCTION(js_object, I2C, write); + ATTACH_CLASS_FUNCTION(js_object, I2C, start); + ATTACH_CLASS_FUNCTION(js_object, I2C, stop); + + return js_object; +} diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/InterruptIn.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/InterruptIn.cpp new file mode 100644 index 000000000..dcdcf16cf --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/InterruptIn.cpp @@ -0,0 +1,218 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "jerryscript-mbed-util/logging.h" +#include "jerryscript-mbed-event-loop/EventLoop.h" +#include "jerryscript-mbed-library-registry/wrap_tools.h" + +#include "mbed.h" + +/** + * InterruptIn#rise (native JavaScript method) + * + * Register a rise callback for an InterruptIn + * + * @param cb Callback function, or null to detach previously attached callback. + */ +DECLARE_CLASS_FUNCTION(InterruptIn, rise) { + CHECK_ARGUMENT_COUNT(InterruptIn, rise, (args_count == 1)); + + // Detach the rise callback when InterruptIn::rise(null) is called + if (jerry_value_is_null(args[1])) { + uintptr_t native_handle; + jerry_get_object_native_handle(this_obj, &native_handle); + + InterruptIn *this_interruptin = (InterruptIn*) native_handle; + + jerry_value_t property_name = jerry_create_string((const jerry_char_t*)"cb_rise"); + jerry_value_t cb_func = jerry_get_property(this_obj, property_name); + jerry_release_value(property_name); + + // Only drop the callback if it exists + if (jerry_value_is_function(cb_func)) { + // Ensure that the EventLoop frees memory used by the callback. + mbed::js::EventLoop::getInstance().dropCallback(cb_func); + } + + this_interruptin->rise(0); + + return jerry_create_undefined(); + } + + // Assuming we actually have a callback now... + CHECK_ARGUMENT_TYPE_ALWAYS(InterruptIn, rise, 0, function); + + uintptr_t native_handle; + jerry_get_object_native_handle(this_obj, &native_handle); + InterruptIn *this_interruptin = reinterpret_cast(native_handle); + + jerry_value_t f = args[0]; + + // Pass the function to EventLoop. + mbed::Callback cb = mbed::js::EventLoop::getInstance().wrapFunction(f); + this_interruptin->rise(cb); + + // Keep track of our callback internally. + jerry_value_t property_name = jerry_create_string((const jerry_char_t*)"cb_rise"); + jerry_set_property(this_obj, property_name, f); + jerry_release_value(property_name); + + return jerry_create_undefined(); +} + +/** + * InterruptIn#fall (native JavaScript method) + * + * Register a fall callback for an InterruptIn + * + * @param cb Callback function, or null to detach previously attached callback. + */ +DECLARE_CLASS_FUNCTION(InterruptIn, fall) { + CHECK_ARGUMENT_COUNT(InterruptIn, fall, (args_count == 1)); + + // Detach the fall callback when InterruptIn::fall(null) is called + if (jerry_value_is_null(args[1])) { + uintptr_t native_handle; + jerry_get_object_native_handle(this_obj, &native_handle); + + InterruptIn *this_interruptin = (InterruptIn*) native_handle; + + jerry_value_t property_name = jerry_create_string((const jerry_char_t*)"cb_fall"); + jerry_value_t cb_func = jerry_get_property(this_obj, property_name); + jerry_release_value(property_name); + + // Only drop the callback if it exists + if (jerry_value_is_function(cb_func)) { + // Ensure that the EventLoop frees memory used by the callback. + mbed::js::EventLoop::getInstance().dropCallback(cb_func); + } + + this_interruptin->fall(0); + + return jerry_create_undefined(); + } + + // Assuming we actually have a callback now... + CHECK_ARGUMENT_TYPE_ALWAYS(InterruptIn, fall, 0, function); + + uintptr_t native_handle; + jerry_get_object_native_handle(this_obj, &native_handle); + InterruptIn *this_interruptin = reinterpret_cast(native_handle); + + jerry_value_t f = args[0]; + + // Pass the function to EventLoop. + mbed::Callback cb = mbed::js::EventLoop::getInstance().wrapFunction(f); + this_interruptin->fall(cb); + + // Keep track of our callback internally. + jerry_value_t property_name = jerry_create_string((const jerry_char_t*)"cb_fall"); + jerry_set_property(this_obj, property_name, f); + jerry_release_value(property_name); + + return jerry_create_undefined(); +} + +/** + * InterruptIn#mode (native JavaScript method) + * + * Set the mode of the InterruptIn pin. + * + * @param mode PullUp, PullDown, PullNone + */ +DECLARE_CLASS_FUNCTION(InterruptIn, mode) { + CHECK_ARGUMENT_COUNT(InterruptIn, mode, (args_count == 1)); + CHECK_ARGUMENT_TYPE_ALWAYS(InterruptIn, mode, 0, number); + + uintptr_t native_handle; + jerry_get_object_native_handle(this_obj, &native_handle); + + InterruptIn *native_ptr = reinterpret_cast(native_handle); + + int pull = jerry_get_number_value(args[0]); + native_ptr->mode((PinMode)pull); + + return jerry_create_undefined(); +} + +/** + * InterruptIn#disable_irq (native JavaScript method) + * + * Disable IRQ. See InterruptIn.h in mbed-os sources for more details. + */ +DECLARE_CLASS_FUNCTION(InterruptIn, disable_irq) { + CHECK_ARGUMENT_COUNT(InterruptIn, disable_irq, (args_count == 0)); + + uintptr_t native_handle; + jerry_get_object_native_handle(this_obj, &native_handle); + InterruptIn *native_ptr = reinterpret_cast(native_handle); + + native_ptr->disable_irq(); + return jerry_create_undefined(); +} + +/** + * InterruptIn#enable_irq (native JavaScript method) + * + * Enable IRQ. See InterruptIn.h in mbed-os sources for more details. + */ +DECLARE_CLASS_FUNCTION(InterruptIn, enable_irq) { + CHECK_ARGUMENT_COUNT(InterruptIn, enable_irq, (args_count == 0)); + + uintptr_t native_handle; + jerry_get_object_native_handle(this_obj, &native_handle); + InterruptIn *native_ptr = reinterpret_cast(native_handle); + + native_ptr->enable_irq(); + return jerry_create_undefined(); +} + +/** + * InterruptIn#destructor + * + * Called if/when the InterruptIn object is GC'ed. + */ +void NAME_FOR_CLASS_NATIVE_DESTRUCTOR(InterruptIn) (uintptr_t handle) { + InterruptIn *native_ptr = reinterpret_cast(handle); + + native_ptr->rise(0); + native_ptr->fall(0); + delete native_ptr; +} + +/** + * InterruptIn (native JavaScript constructor) + * + * @param pin PinName + * + * @returns JavaScript object wrapping InterruptIn native object + */ +DECLARE_CLASS_CONSTRUCTOR(InterruptIn) { + CHECK_ARGUMENT_COUNT(InterruptIn, __constructor, (args_count == 1)); + CHECK_ARGUMENT_TYPE_ALWAYS(InterruptIn, __constructor, 0, number); + int pin = jerry_get_number_value(args[0]); + + uintptr_t native_handle = (uintptr_t)new InterruptIn((PinName)pin); + jerry_value_t js_object = jerry_create_object(); + + jerry_set_object_native_handle(js_object, native_handle, NAME_FOR_CLASS_NATIVE_DESTRUCTOR(InterruptIn)); + + ATTACH_CLASS_FUNCTION(js_object, InterruptIn, rise); + ATTACH_CLASS_FUNCTION(js_object, InterruptIn, fall); + ATTACH_CLASS_FUNCTION(js_object, InterruptIn, mode); + ATTACH_CLASS_FUNCTION(js_object, InterruptIn, enable_irq); + ATTACH_CLASS_FUNCTION(js_object, InterruptIn, disable_irq); + + return js_object; +} diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/assert.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/assert.cpp new file mode 100644 index 000000000..539945a0e --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/assert.cpp @@ -0,0 +1,34 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "jerryscript-mbed-drivers/assert-js.h" + +/** + * assert (native JavaScript function) + * + * @param condition The condition to assert to be true + * @returns undefined if the assertion passes, returns an error if the assertion + * fails. + */ +DECLARE_GLOBAL_FUNCTION(assert) { + CHECK_ARGUMENT_COUNT(global, assert, (args_count == 1)); + CHECK_ARGUMENT_TYPE_ALWAYS(global, assert, 0, boolean); + + if (!jerry_get_boolean_value(args[0])) { + const char* error_msg = "Assertion failed"; + return jerry_create_error(JERRY_ERROR_TYPE, reinterpret_cast(error_msg)); + } + + return jerry_create_undefined(); +} diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/gc.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/gc.cpp new file mode 100644 index 000000000..45cc6fa91 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/gc.cpp @@ -0,0 +1,25 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "jerryscript-mbed-drivers/gc-js.h" + +/** + * gc (native JavaScript function) + * + * Manually cause JerryScript to run garbage collection. + */ +DECLARE_GLOBAL_FUNCTION(gc) { + jerry_gc(); + return jerry_create_undefined(); +} diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/setInterval.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/setInterval.cpp new file mode 100644 index 000000000..4953e5001 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/setInterval.cpp @@ -0,0 +1,36 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "jerryscript-mbed-drivers/setInterval-js.h" +#include "jerryscript-mbed-event-loop/EventLoop.h" + +/** + * setInterval (native JavaScript function) + * + * Call a JavaScript function at fixed intervals. + * + * @param function Function to call + * @param interval Time between function calls, in ms. + */ +DECLARE_GLOBAL_FUNCTION(setInterval) { + CHECK_ARGUMENT_COUNT(global, setInterval, (args_count == 2)); + CHECK_ARGUMENT_TYPE_ALWAYS(global, setInterval, 0, function); + CHECK_ARGUMENT_TYPE_ALWAYS(global, setInterval, 1, number); + + jerry_acquire_value(args[0]); + int interval = int(jerry_get_number_value(args[1])); + + mbed::js::EventLoop::getInstance().getQueue().call_every(interval, jerry_call_function, args[0], jerry_create_null(), (jerry_value_t*)NULL, 0); + return jerry_create_undefined(); +} diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/setTimeout.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/setTimeout.cpp new file mode 100644 index 000000000..f0df78f82 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/setTimeout.cpp @@ -0,0 +1,37 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "jerryscript-mbed-drivers/setTimeout-js.h" +#include "jerryscript-mbed-event-loop/EventLoop.h" + +/** + * setTimeout (native JavaScript function) + * + * Call a JavaScript function once, after a fixed time period. + * + * @param function Function to call + * @param wait_time Time before function is called, in ms. + */ +DECLARE_GLOBAL_FUNCTION(setTimeout) { + CHECK_ARGUMENT_COUNT(global, setTimeout, (args_count == 2)); + CHECK_ARGUMENT_TYPE_ALWAYS(global, setTimeout, 0, function); + CHECK_ARGUMENT_TYPE_ALWAYS(global, setTimeout, 1, number); + + jerry_acquire_value(args[0]); + int interval = int(jerry_get_number_value(args[1])); + + mbed::js::EventLoop::getInstance().getQueue().call_in(interval, jerry_call_function, args[0], jerry_create_null(), (jerry_value_t*)NULL, 0); + + return jerry_create_undefined(); +} diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-event-loop/BoundCallback.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-event-loop/BoundCallback.h new file mode 100644 index 000000000..c0244b715 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-event-loop/BoundCallback.h @@ -0,0 +1,114 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_EVENT_LOOP_BOUND_CALLBACK_H +#define _JERRYSCRIPT_MBED_EVENT_LOOP_BOUND_CALLBACK_H + +#include "Callback.h" + +namespace mbed { +namespace js { + +template +class BoundCallback; + +template +class BoundCallback { + public: + BoundCallback(Callback cb, A0 a0) : a0(a0), cb(cb) { } + + void call() { + cb(a0); + } + + operator Callback() { + Callback cb(this, &BoundCallback::call); + return cb; + } + + private: + A0 a0; + Callback cb; +}; + +template +class BoundCallback { + public: + BoundCallback(Callback cb, A0 a0, A1 a1) : a0(a0), a1(a1), cb(cb) { } + + void call() { + cb(a0, a1); + } + + operator Callback() { + Callback cb(this, &BoundCallback::call); + return cb; + } + + private: + A0 a0; + A0 a1; + + Callback cb; +}; + +template +class BoundCallback { + public: + BoundCallback(Callback cb, A0 a0, A1 a1, A2 a2) : a0(a0), a1(a1), a2(a2), cb(cb) { } + + void call() { + cb(a0, a1, a2); + } + + operator Callback() { + Callback cb(this, &BoundCallback::call); + return cb; + } + + private: + A0 a0; + A1 a1; + A2 a2; + + Callback cb; +}; + +template +class BoundCallback { + public: + BoundCallback(Callback cb, A0 a0, A1 a1, A2 a2, A3 a3) : a0(a0), a1(a1), a2(a2), a3(a3), cb(cb) { } + + void call() { + cb(a0, a1, a2, a3); + } + + operator Callback() { + Callback cb(this, &BoundCallback::call); + return cb; + } + + private: + A0 a0; + A1 a1; + A2 a2; + A3 a3; + + Callback cb; +}; + +} // namespace js +} // namespace mbed + +#endif // _JERRYSCRIPT_MBED_EVENT_LOOP_BOUND_CALLBACK_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-event-loop/EventLoop.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-event-loop/EventLoop.h new file mode 100644 index 000000000..4f6c3f86b --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-event-loop/EventLoop.h @@ -0,0 +1,104 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_EVENT_LOOP_EVENT_LOOP_H +#define _JERRYSCRIPT_MBED_EVENT_LOOP_EVENT_LOOP_H + +#include + +#include "jerry-core/jerry-api.h" + +#include "Callback.h" +#include "mbed_assert.h" + +#include "mbed-events/EventQueue.h" + +#include "jerryscript-mbed-util/logging.h" +#include "jerryscript-mbed-event-loop/BoundCallback.h" + +extern "C" void exit(int return_code); + +namespace mbed { +namespace js { + +static const uint32_t EVENT_INTERVAL_MS = 1; + +class EventLoop { + private: + static EventLoop instance; + + public: + static EventLoop& getInstance() { + return instance; + } + + void go() { + while (true) { + queue.dispatch(); + } + } + + Callback wrapFunction(jerry_value_t f) { + MBED_ASSERT(jerry_value_is_function(f)); + + // not sure if this is necessary? + jerry_acquire_value(f); + + // we need to return a callback that'll schedule this + Callback cb_raw(this, &EventLoop::callback); + BoundCallback *cb = new BoundCallback(cb_raw, f); + + bound_callbacks.push_back(std::make_pair(f, cb)); + + return *cb; + } + + void dropCallback(jerry_value_t f) { + jerry_release_value(f); + + for (std::vector*> >::iterator it = bound_callbacks.begin(); it != bound_callbacks.end(); it++) { + std::pair*> element = *it; + + if (element.first == f) { + delete element.second; + break; + } + } + } + + void callback(jerry_value_t f) { + queue.call(jerry_call_function, f, jerry_create_null(), (const jerry_value_t*)NULL, 0); + } + + void nativeCallback(Callback cb) { + queue.call(cb); + } + + events::EventQueue& getQueue() { + return queue; + } + + private: + EventLoop() {} + + std::vector*> > bound_callbacks; + events::EventQueue queue; +}; + +void event_loop(); + +} // namespace js +} // namespace mbed + +#endif // _JERRYSCRIPT_MBED_EVENT_LOOP_EVENT_LOOP_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-event-loop/source/EventLoop.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-event-loop/source/EventLoop.cpp new file mode 100644 index 000000000..7f1af7531 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-event-loop/source/EventLoop.cpp @@ -0,0 +1,27 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "jerryscript-mbed-event-loop/EventLoop.h" + +namespace mbed { +namespace js { + +EventLoop EventLoop::instance; + +void event_loop() { + EventLoop::getInstance().go(); +} + +} // namespace js +} // namespace mbed diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/launcher.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/launcher.h new file mode 100644 index 000000000..13181b0c4 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/launcher.h @@ -0,0 +1,21 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_LAUNCHER_LAUNCHER_H +#define _JERRYSCRIPT_MBED_LAUNCHER_LAUNCHER_H + +void jsmbed_js_launch(void); +void jsmbed_js_exit(void); + +#endif // _JERRYSCRIPT_MBED_LAUNCHER_LAUNCHER_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/setup.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/setup.h new file mode 100644 index 000000000..8ad316473 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/setup.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_LAUNCHER_SETUP_H +#define _JERRYSCRIPT_MBED_LAUNCHER_SETUP_H + +#include "jerry-core/jerry-api.h" + +void jsmbed_js_load_magic_strings(void); + +#endif // _JERRYSCRIPT_MBED_LAUNCHER_SETUP_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/source/launcher.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/source/launcher.cpp new file mode 100644 index 000000000..5ce31f7e3 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/source/launcher.cpp @@ -0,0 +1,90 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include "rtos.h" + +#include "jerry-core/jerry-api.h" + +#include "jerryscript-mbed-event-loop/EventLoop.h" + +#include "jerryscript-mbed-util/js_source.h" +#include "jerryscript-mbed-library-registry/registry.h" + +#include "jerryscript-mbed-launcher/launcher.h" +#include "jerryscript-mbed-launcher/setup.h" + +#include "jerry_targetjs.h" + +DECLARE_JS_CODES; + +/** + * load_javascript + * + * Parse and run javascript files specified in jerry_targetjs.h + */ +static int load_javascript() { + for (int src = 0; js_codes[src].source; src++) { + LOG_PRINT("running js file %s\r\n", js_codes[src].name); + + const jerry_char_t* code = reinterpret_cast(js_codes[src].source); + const size_t length = js_codes[src].length; + + jerry_value_t parsed_code = jerry_parse(code, length, false); + + if (jerry_value_has_error_flag(parsed_code)) { + LOG_PRINT_ALWAYS("jerry_parse failed [%s]\r\n", js_codes[src].name); + jsmbed_js_exit(); + return -1; + } + + jerry_value_t returned_value = jerry_run(parsed_code); + + if (jerry_value_has_error_flag(returned_value)) { + LOG_PRINT_ALWAYS("jerry_run failed [%s]\r\n", js_codes[src].name); + jsmbed_js_exit(); + return -1; + } + + jerry_release_value(parsed_code); + jerry_release_value(returned_value); + } + + return 0; +} + +int jsmbed_js_init() { + jerry_init_flag_t flags = JERRY_INIT_EMPTY; + jerry_init(flags); + + jsmbed_js_load_magic_strings(); + mbed::js::LibraryRegistry::getInstance().register_all(); + + return 0; +} + +void jsmbed_js_exit() { + jerry_cleanup(); +} + +void jsmbed_js_launch() { + jsmbed_js_init(); + + puts(" JerryScript in mbed\r\n"); + puts(" build date: " __DATE__ " \r\n"); + + if (load_javascript() == 0) { + mbed::js::event_loop(); + } +} diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/source/setup.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/source/setup.cpp new file mode 100644 index 000000000..1e58976c6 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/source/setup.cpp @@ -0,0 +1,49 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include "jerryscript-mbed-launcher/setup.h" +#include "jerryscript-mbed-util/logging.h" + +extern uint32_t jsmbed_js_magic_string_count; +extern uint32_t jsmbed_js_magic_string_values[]; + +extern const jerry_char_ptr_t jsmbed_js_magic_strings[]; +extern const jerry_length_t jsmbed_js_magic_string_lengths[]; + +void jsmbed_js_load_magic_strings() { + if (jsmbed_js_magic_string_count == 0) { + return; + } + + jerry_register_magic_strings(jsmbed_js_magic_strings, + jsmbed_js_magic_string_count, + jsmbed_js_magic_string_lengths); + + jerry_value_t global = jerry_get_global_object(); + + for (unsigned int idx = 0; idx < jsmbed_js_magic_string_count; idx++) { + jerry_value_t constant_value = jerry_create_number(jsmbed_js_magic_string_values[idx]); + jerry_value_t magic_string = jerry_create_string(jsmbed_js_magic_strings[idx]); + + jerry_set_property(global, magic_string, constant_value); + + jerry_release_value(constant_value); + jerry_release_value(magic_string); + } + + jerry_release_value(global); +} diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/registry.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/registry.h new file mode 100644 index 000000000..70ccd31f1 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/registry.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_LIBRARY_REGISTRY_REGISTRY_H +#define _JERRYSCRIPT_MBED_LIBRARY_REGISTRY_REGISTRY_H + +#include +#include "stdint.h" + +#define JERRY_USE_MBED_LIBRARY(NAME) \ + mbed::js::LibraryRegistry::getInstance().add(jsmbed_wrap_registry_entry__ ## NAME) + +namespace mbed { +namespace js { + +typedef void (*library_registration_function_t)(void); + +class LibraryRegistry { + private: + static LibraryRegistry instance; + + public: + static LibraryRegistry& getInstance() { + return instance; + } + + void add(library_registration_function_t lib_func) { + funcs.push_back(lib_func); + } + + void register_all() { + for (std::size_t i = 0; i < funcs.size(); i++) { + funcs[i](); + } + } + + private: + LibraryRegistry() {} + + std::vector funcs; +}; + +} // namespace js +} // namespace mbed + +#endif // _JERRYSCRIPT_MBED_LIBRARY_REGISTRY_REGISTRY_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/source/registry.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/source/registry.cpp new file mode 100644 index 000000000..3d3c13b10 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/source/registry.cpp @@ -0,0 +1,17 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "jerryscript-mbed-library-registry/registry.h" + +mbed::js::LibraryRegistry mbed::js::LibraryRegistry::instance; diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/source/wrap_tools.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/source/wrap_tools.cpp new file mode 100644 index 000000000..007539b3b --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/source/wrap_tools.cpp @@ -0,0 +1,78 @@ +/* Copyright 2014-2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 ARM Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include "jerryscript-mbed-library-registry/wrap_tools.h" + +bool jsmbed_wrap_register_global_function(const char* name, jerry_external_handler_t handler) { + jerry_value_t global_object_val = jerry_get_global_object(); + jerry_value_t reg_function = jerry_create_external_function(handler); + + bool is_ok = true; + + if (!(jerry_value_is_function(reg_function) + && jerry_value_is_constructor(reg_function))) { + is_ok = false; + LOG_PRINT_ALWAYS("Error: jerry_create_external_function failed!\r\n"); + jerry_release_value(global_object_val); + jerry_release_value(reg_function); + return is_ok; + } + + if (jerry_value_has_error_flag(reg_function)) { + is_ok = false; + LOG_PRINT_ALWAYS("Error: jerry_create_external_function has error flag! \r\n"); + jerry_release_value(global_object_val); + jerry_release_value(reg_function); + return is_ok; + } + + jerry_value_t jerry_name = jerry_create_string((jerry_char_t *) name); + + jerry_value_t set_result = jerry_set_property(global_object_val, jerry_name, reg_function); + + + if (jerry_value_has_error_flag(set_result)) { + is_ok = false; + LOG_PRINT_ALWAYS("Error: jerry_create_external_function failed: [%s]\r\n", name); + } + + jerry_release_value(jerry_name); + jerry_release_value(global_object_val); + jerry_release_value(reg_function); + jerry_release_value(set_result); + + return is_ok; +} + +bool jsmbed_wrap_register_class_constructor(const char* name, jerry_external_handler_t handler) { + // Register class constructor as a global function + return jsmbed_wrap_register_global_function(name, handler); +} + +bool jsmbed_wrap_register_class_function(jerry_value_t this_obj, const char* name, jerry_external_handler_t handler) { + jerry_value_t property_name = jerry_create_string(reinterpret_cast(name)); + jerry_value_t handler_obj = jerry_create_external_function(handler); + + jerry_set_property(this_obj, property_name, handler_obj); + + jerry_release_value(handler_obj); + jerry_release_value(property_name); + + // TODO: check for errors, and return false in the case of errors + return true; +} diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/wrap_tools.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/wrap_tools.h new file mode 100644 index 000000000..7a6f77ed6 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/wrap_tools.h @@ -0,0 +1,43 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_LIBRARY_REGISTRY_WRAP_TOOLS_H +#define _JERRYSCRIPT_MBED_LIBRARY_REGISTRY_WRAP_TOOLS_H + +#include + +#include "jerry-core/jerry-api.h" + +#include "jerryscript-mbed-util/logging.h" +#include "jerryscript-mbed-util/wrappers.h" + + +// +// Functions used by the wrapper registration API. +// + +bool +jsmbed_wrap_register_global_function (const char* name, + jerry_external_handler_t handler); + +bool +jsmbed_wrap_register_class_constructor (const char* name, + jerry_external_handler_t handler); + +bool +jsmbed_wrap_register_class_function (jerry_value_t this_obj_p, + const char* name, + jerry_external_handler_t handler); + +#endif // _JERRYSCRIPT_MBED_LIBRARY_REGISTRY_WRAP_TOOLS_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-util/js_source.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-util/js_source.h new file mode 100644 index 000000000..6cabd3594 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-util/js_source.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_UTIL_JS_SOURCE_H +#define _JERRYSCRIPT_MBED_UTIL_JS_SOURCE_H + +struct jsmbed_js_source_t { + const char* name; + const char* source; + const int length; +}; + +#endif // _JERRYSCRIPT_MBED_UTIL_JS_SOURCE_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-util/logging.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-util/logging.h new file mode 100644 index 000000000..0127e60ec --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-util/logging.h @@ -0,0 +1,26 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_UTIL_LOGGING_H +#define _JERRYSCRIPT_MBED_UTIL_LOGGING_H + +#ifdef DEBUG_WRAPPER +#define LOG_PRINT(...) printf(__VA_ARGS__) +#else +#define LOG_PRINT(...) while(0) { } +#endif + +#define LOG_PRINT_ALWAYS(...) printf(__VA_ARGS__) + +#endif // _JERRYSCRIPT_MBED_UTIL_LOGGING_H diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-util/wrappers.h b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-util/wrappers.h new file mode 100644 index 000000000..11dbb2170 --- /dev/null +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-util/wrappers.h @@ -0,0 +1,93 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _JERRYSCRIPT_MBED_UTIL_WRAPPERS_H +#define _JERRYSCRIPT_MBED_UTIL_WRAPPERS_H + +/* + * Used in header/source files for wrappers, to declare the signature of the + * registration function. + */ +#define DECLARE_JS_WRAPPER_REGISTRATION(NAME) \ + void jsmbed_wrap_registry_entry__ ## NAME (void) + +// +// 2. Wrapper function declaration/use macros +// + +// Global functions +#define DECLARE_GLOBAL_FUNCTION(NAME) \ +jerry_value_t \ +NAME_FOR_GLOBAL_FUNCTION(NAME) (const jerry_value_t function_obj_p, \ + const jerry_value_t this_obj, \ + const jerry_value_t args[], \ + const jerry_length_t args_count) + +#define REGISTER_GLOBAL_FUNCTION(NAME) \ + jsmbed_wrap_register_global_function ( # NAME, NAME_FOR_GLOBAL_FUNCTION(NAME) ) + +// Class constructors +#define DECLARE_CLASS_CONSTRUCTOR(CLASS) \ +jerry_value_t \ +NAME_FOR_CLASS_CONSTRUCTOR(CLASS) (const jerry_value_t function_obj, \ + const jerry_value_t this_obj, \ + const jerry_value_t args[], \ + const jerry_length_t args_count) + +#define REGISTER_CLASS_CONSTRUCTOR(CLASS) \ + jsmbed_wrap_register_class_constructor ( # CLASS, NAME_FOR_CLASS_CONSTRUCTOR(CLASS) ) + +// Class functions +#define DECLARE_CLASS_FUNCTION(CLASS, NAME) \ +jerry_value_t \ +NAME_FOR_CLASS_FUNCTION(CLASS, NAME) (const jerry_value_t function_obj, \ + const jerry_value_t this_obj, \ + const jerry_value_t args[], \ + const jerry_length_t args_count) + +#define ATTACH_CLASS_FUNCTION(OBJECT, CLASS, NAME) \ + jsmbed_wrap_register_class_function (OBJECT, # NAME, NAME_FOR_CLASS_FUNCTION(CLASS, NAME) ) + +// +// 3. Argument checking macros +// +#define CHECK_ARGUMENT_COUNT(CLASS, NAME, EXPR) \ + if (!(EXPR)) { \ + const char* error_msg = "ERROR: wrong argument count for " # CLASS "." # NAME ", expected " # EXPR "."; \ + return jerry_create_error(JERRY_ERROR_TYPE, reinterpret_cast(error_msg)); \ + } + +#define CHECK_ARGUMENT_TYPE_ALWAYS(CLASS, NAME, INDEX, TYPE) \ + if (!jerry_value_is_ ## TYPE (args[INDEX])) { \ + const char* error_msg = "ERROR: wrong argument type for " # CLASS "." # NAME ", expected argument " # INDEX " to be a " # TYPE ".\n"; \ + return jerry_create_error(JERRY_ERROR_TYPE, reinterpret_cast(error_msg)); \ + } + +#define CHECK_ARGUMENT_TYPE_ON_CONDITION(CLASS, NAME, INDEX, TYPE, EXPR) \ + if ((EXPR)) { \ + if (!jerry_value_is_ ## TYPE (args[INDEX])) { \ + const char* error_msg = "ERROR: wrong argument type for " # CLASS "." # NAME ", expected argument " # INDEX " to be a " # TYPE ".\n"; \ + return jerry_create_error(JERRY_ERROR_TYPE, reinterpret_cast(error_msg)); \ + } \ + } + +#define NAME_FOR_GLOBAL_FUNCTION(NAME) __gen_jsmbed_global_func_ ## NAME +#define NAME_FOR_CLASS_CONSTRUCTOR(CLASS) __gen_jsmbed_class_constructor_ ## CLASS +#define NAME_FOR_CLASS_FUNCTION(CLASS, NAME) __gen_jsmbed_func_c_ ## CLASS ## _f_ ## NAME + +#define NAME_FOR_CLASS_NATIVE_CONSTRUCTOR(CLASS, TYPELIST) __gen_native_jsmbed_ ## CLASS ## __Special_create_ ## TYPELIST +#define NAME_FOR_CLASS_NATIVE_DESTRUCTOR(CLASS) __gen_native_jsmbed_ ## CLASS ## __Special_destroy +#define NAME_FOR_CLASS_NATIVE_FUNCTION(CLASS, NAME) __gen_native_jsmbed_ ## CLASS ## _ ## NAME + +#endif // _JERRYSCRIPT_MBED_UTIL_WRAPPERS_H diff --git a/targets/mbedos5/js/flash_leds.js b/targets/mbedos5/js/flash_leds.js new file mode 100644 index 000000000..5c99cb184 --- /dev/null +++ b/targets/mbedos5/js/flash_leds.js @@ -0,0 +1,76 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var led = 0; + +// Setting the pin to 0 turns the LED on +var led_off = 1; +var led_on = 0; + +var digital_outs = []; + +var leds = [LED1, LED2, LED3, LED4]; + +function connect_pins() { + print("Creating new DigitalOuts"); + digital_outs = []; + for (var i = 0; i < 4; i++) { + digital_outs.push(DigitalOut(leds[i], led_off)); + if (digital_outs[i].is_connected()) { + print("LED " + i + " is connected."); + } + else { + print("LED " + i + " is not connected."); + } + } +} + +connect_pins(); + +function blink() { + digital_outs[0].write(led_off); + digital_outs[1].write(led_off); + digital_outs[2].write(led_off); + digital_outs[3].write(led_off); + + digital_outs[led].write(led_on); + + print("Finished with LED " + led); + led = (led + 1) % 4; +} + +// BUTTON2 on NRF52 +// USER_BUTTON on NUCLEO +// SW2 on the K64F +// BTN0 on EFM32GG +var button; + +/* global BUTTON2, SW2, USER_BUTTON, BTN0 */ +if (typeof BUTTON2 !== 'undefined') { + button = InterruptIn(BUTTON2); +} else if (typeof SW2 !== 'undefined') { + button = InterruptIn(SW2); +} else if (typeof USER_BUTTON !== 'undefined') { + button = InterruptIn(USER_BUTTON); +} else if (typeof BTN0 !== 'undefined') { + button = InterruptIn(BTN0); +} else { + print("no button specified"); +} +button.fall(function() { + print("YOU PUSHED THE BUTTON!"); +}); + +print("flash_leds.js has finished executing."); diff --git a/targets/mbedos5/js/main.js b/targets/mbedos5/js/main.js new file mode 100644 index 000000000..ee75bd0a7 --- /dev/null +++ b/targets/mbedos5/js/main.js @@ -0,0 +1,20 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +setInterval(function() { + blink(); +}, 1000); + +print("main.js has finished executing."); diff --git a/targets/mbedos5/mbed-events.lib b/targets/mbedos5/mbed-events.lib new file mode 100644 index 000000000..2fdfa9da4 --- /dev/null +++ b/targets/mbedos5/mbed-events.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-events/#a4ba1b08ef90e2b3b6d442696f4d80a8587494e3 diff --git a/targets/mbedos5/mbed-os.lib b/targets/mbedos5/mbed-os.lib new file mode 100644 index 000000000..60a60347c --- /dev/null +++ b/targets/mbedos5/mbed-os.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os/#bdab10dc0f90748b6989c8b577771bb403ca6bd8 diff --git a/targets/mbedos5/mbed_app.json b/targets/mbedos5/mbed_app.json new file mode 100644 index 000000000..67a1c8ccd --- /dev/null +++ b/targets/mbedos5/mbed_app.json @@ -0,0 +1,7 @@ +{ + "target_overrides": { + "NRF52_DK": { + "target.uart_hwfc": 0 + } + } +} diff --git a/targets/mbedos5/source/jerry_port_mbed.c b/targets/mbedos5/source/jerry_port_mbed.c new file mode 100644 index 000000000..a5dee7659 --- /dev/null +++ b/targets/mbedos5/source/jerry_port_mbed.c @@ -0,0 +1,85 @@ +/* Copyright 2016 University of Szeged. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _BSD_SOURCE +#include +#include +#include + +#include "jerry-core/jerry-port.h" + +#include "us_ticker_api.h" + +/** + * Provide console message implementation for the engine. + */ +void +jerry_port_console (const char *format, /**< format string */ + ...) /**< parameters */ +{ + va_list args; + va_start (args, format); + vfprintf (stdout, format, args); + va_end (args); +} /* jerry_port_console */ + +/** + * Provide log message implementation for the engine. + */ +void +jerry_port_log (jerry_log_level_t level, /**< log level */ + const char *format, /**< format string */ + ...) /**< parameters */ +{ + (void) level; /* ignore log level */ + + va_list args; + va_start (args, format); + vfprintf (stderr, format, args); + va_end (args); +} /* jerry_port_log */ + +/** + * Implementation of jerry_port_fatal. + */ +void +jerry_port_fatal (jerry_fatal_code_t code) /**< fatal code enum item */ +{ + exit (code); +} /* jerry_port_fatal */ + +/** + * Implementation of jerry_port_get_time_zone. + * + * @return true - if success + */ +bool +jerry_port_get_time_zone (jerry_time_zone_t *tz_p) /**< timezone pointer */ +{ + tz_p->offset = 0; + tz_p->daylight_saving_time = 0; + return true; +} /* jerry_port_get_time_zone */ + +/** + * Implementation of jerry_port_get_current_time. + * + * @return current timer's counter value in microseconds + */ +double +jerry_port_get_current_time () +{ + return (double) us_ticker_read (); +} /* jerry_port_get_current_time */ diff --git a/targets/mbedos5/source/main.cpp b/targets/mbedos5/source/main.cpp new file mode 100644 index 000000000..b6d7922e5 --- /dev/null +++ b/targets/mbedos5/source/main.cpp @@ -0,0 +1,48 @@ +/* Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Provides jsmbed_js_launch() +#include "jerryscript-mbed-launcher/launcher.h" + +// Provides JSMBED_USE_WRAPPER() +#include "jerryscript-mbed-library-registry/registry.h" + +// Provides the base wrapper registration symbol that JSMBED_USE_WRAPPER uses. +// This means all of the base handlers will be registered. +#include "jerryscript-mbed-drivers/lib_drivers.h" + +#include "jerryscript-mbed-event-loop/EventLoop.h" + +#include "Callback.h" +#include "Serial.h" + +using mbed::js::EventLoop; +using mbed::Callback; + +int main() { + mbed::Serial pc(USBTX, USBRX); + pc.baud(115200); + + JERRY_USE_MBED_LIBRARY(base); + + // Incude more wrapper packages here if you want to use them. For exmaple: + // JERRY_USE_MBED_LIBRARY(lwip_interface); + // JERRY_USE_MBED_LIBRARY(esp8266_interface); + // JERRY_USE_MBED_LIBRARY(simple_mbed_client); + + jsmbed_js_launch(); + + return 0; +} diff --git a/targets/mbedos5/template-mbedignore.txt b/targets/mbedos5/template-mbedignore.txt new file mode 100644 index 000000000..97a2f04ad --- /dev/null +++ b/targets/mbedos5/template-mbedignore.txt @@ -0,0 +1,8 @@ +cmake/* +docs/* +jerry-libc/* +jerry-main/* +targets/* +tests/* +third-party/* +tools/* diff --git a/targets/mbedos5/tools/check_pins.sh b/targets/mbedos5/tools/check_pins.sh new file mode 100755 index 000000000..7bc4396a3 --- /dev/null +++ b/targets/mbedos5/tools/check_pins.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Copyright (c) 2016 ARM Limited. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# If we're checking only for global variable definitions of pins, then +# file ordering doesn't matter. This is because: +# +# var a = b; +# var b = 7; +# +# will be accepted by jshint, just 'a' will evaluate to 'undefined'. +# Awkward, but at least it means we can have pins.js included at any +# point in the clump of files and it won't give us false positives. + +cat js/*.js | jshint -c tools/jshint.conf - | grep "not defined" +if [ "$?" == 0 ]; then + exit 1 +fi +exit 0 diff --git a/targets/mbedos5/tools/cmsis.h b/targets/mbedos5/tools/cmsis.h new file mode 100644 index 000000000..8eb71f738 --- /dev/null +++ b/targets/mbedos5/tools/cmsis.h @@ -0,0 +1,17 @@ +/* Copyright (c) 2016 ARM Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is intentionally blank, and is used as a dummy cmsis.h file + * when preprocessing generate_pins.py. + */ diff --git a/targets/mbedos5/tools/generate_pins.py b/targets/mbedos5/tools/generate_pins.py new file mode 100644 index 000000000..462e15059 --- /dev/null +++ b/targets/mbedos5/tools/generate_pins.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Generate pins.js for a specified target, using target definitions from the +mbed OS source tree. + +It's expecting to be run from the targets/mbedos5 directory. +""" + +from __future__ import print_function + +from pycparser import parse_file, c_ast, c_generator +from pycparserext.ext_c_parser import GnuCParser + +from simpleeval import SimpleEval, DEFAULT_OPERATORS + +import ast + +import argparse +import json +import sys +import os + +# import mbed tools +sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'mbed-os')) +from tools.targets import Target + + +def find_file(root_dir, directories, name): + """ + Find the first instance of file with name 'name' in the directory tree + starting with 'root_dir'. + + Filter out directories that are not in directories, or do not start with + TARGET_. + + Since this looks in (essentially )the same directories as the compiler would + when compiling mbed OS, we should only find one PinNames.h. + """ + + for root, dirs, files in os.walk(root_dir, topdown=True): + # modify dirs in place + dirs[:] = filter(lambda x: x in directories or not x.startswith('TARGET_'), dirs) + + if name in files: + return os.path.join(root, name) + +def enumerate_includes(root_dir, directories): + """ + Walk through the directory tree, starting at root_dir, and enumerate all + valid include directories. + """ + for root, dirs, files in os.walk(root_dir, topdown=True): + # modify dirs in place + dirs[:] = filter(lambda x: x in directory_labels + or ( not x.startswith('TARGET_') + and not x.startswith('TOOLCHAIN_')), dirs) + yield root + + +class TypeDeclVisitor(c_ast.NodeVisitor): + def __init__(self, filter_names=[]): + self.names = filter_names + + def visit(self, node): + value = None + + if node.__class__.__name__ == "TypeDecl": + value = self.visit_TypeDecl(node) + + if value is None: + for name, c in node.children(): + value = value or self.visit(c) + + return value + + def visit_TypeDecl(self, node): + if node.declname in self.names: + c_gen = c_generator.CGenerator() + pins = {} + + operators = DEFAULT_OPERATORS + operators[ast.BitOr] = lambda a, b: a | b + operators[ast.LShift] = lambda a, b: a << b + operators[ast.RShift] = lambda a, b: a << b + evaluator = SimpleEval(DEFAULT_OPERATORS ) + + for pin in node.type.values.enumerators: + expr = c_gen.visit(pin.value) + + if "(int)" in expr: + expr = expr.replace('(int)', '') + + if expr in pins: + pins[pin.name] = pins[expr] + else: + pins[pin.name] = evaluator.eval(expr.strip()) + + return pins + +def enumerate_pins(c_source_file, include_dirs, definitions): + """ + Enumerate pins specified in PinNames.h, by looking for a PinName enum + typedef somewhere in the file. + """ + definitions += ['__attribute(x)__=', '__extension__(x)=', 'register=', '__IO=', 'uint32_t=unsigned int'] + + gcc_args = ['-E', '-fmerge-all-constants'] + gcc_args += ['-I' + directory for directory in include_dirs] + + gcc_args += ['-D' + definition for definition in definitions] + ast = parse_file(c_source_file, + use_cpp=True, + cpp_path='arm-none-eabi-gcc', + cpp_args=gcc_args, + parser=GnuCParser()) + + # now, walk the AST + v = TypeDeclVisitor(['PinName']) + return v.visit(ast) + + +if __name__ == "__main__": + if not os.path.exists('./mbed-os'): + print("Fatal: mbed-os directory does not exist.") + print("Try running 'make getlibs'") + sys.exit(1) + + description = """ + Generate pins.js for a specified mbed board, using target definitions from the + mbed OS source tree. + """ + + parser = argparse.ArgumentParser(description=description) + + parser.add_argument('board', help='mbed board name') + parser.add_argument('-o', + help='Output JavaScript file (default: %(default)s)', + default='js/pins.js', + type=argparse.FileType('w')) + parser.add_argument('-c', + help='Output C++ file (default: %(default)s)', + default='source/pins.cpp', + type=argparse.FileType('w')) + + args = parser.parse_args() + board_name = args.board.upper() + + target = Target(board_name) + + directory_labels = ['TARGET_' + label for label in target.get_labels()] + target.macros + + targets_dir = os.path.join('.', 'mbed-os', 'hal', 'targets') + hal_dir = os.path.join(targets_dir, 'hal') + + pins_file = find_file(hal_dir, directory_labels, 'PinNames.h') + + + includes = enumerate_includes(targets_dir, directory_labels) + defines = list(directory_labels) + + # enumerate pins from PinNames.h + pins = enumerate_pins(pins_file, ['./tools'] + list(includes), defines) + + out_file = '\r\n'.join(['var %s = %s;' % pin for pin in pins.iteritems()]) + args.o.write(out_file) + + LICENSE = '''/* Copyright 2016 ARM, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the \"License\"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an \"AS IS\" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is generated by generate_pins.py. Please do not modify. + */ + ''' + + COUNT = ''' +unsigned int jsmbed_js_magic_string_count = {}; + '''.format(len(pins)) + + LENGTHS = ',\n '.join(str(len(name)) for name in pins.iterkeys()) + LENGTHS_SOURCE = ''' +unsigned int jsmbed_js_magic_string_lengths[] = { + %s +}; + ''' % LENGTHS + + MAGIC_VALUES = ',\n '.join(str(value) for value in pins.itervalues()) + MAGIC_SOURCE = ''' +unsigned int jsmbed_js_magic_string_values[] = { + %s +}; + ''' % MAGIC_VALUES + + MAGIC_STRINGS = ',\n '.join('"' + name + '"' for name in pins.iterkeys()) + MAGIC_STRING_SOURCE = ''' +const char * jsmbed_js_magic_strings[] = { + %s +}; + ''' % MAGIC_STRINGS + + args.c.write(LICENSE + COUNT + LENGTHS_SOURCE + MAGIC_SOURCE + MAGIC_STRING_SOURCE) diff --git a/targets/mbedos5/tools/jshint.conf b/targets/mbedos5/tools/jshint.conf new file mode 100644 index 000000000..26379e221 --- /dev/null +++ b/targets/mbedos5/tools/jshint.conf @@ -0,0 +1,4 @@ +{ + "undef": true, + "predef": ["print", "BLEDevice", "BLEService", "BLECharacteristic", "DigitalOut", "I2C", "setInterval", "setTimeout", "InterruptIn", "LWIPInterface", "SimpleMbedClient", "M2MBase"] +} diff --git a/targets/mbedos5/tools/requirements.txt b/targets/mbedos5/tools/requirements.txt new file mode 100644 index 000000000..54b167dc1 --- /dev/null +++ b/targets/mbedos5/tools/requirements.txt @@ -0,0 +1,3 @@ +pycparser +simpleeval +pycparserext diff --git a/targets/tools/js2c.py b/targets/tools/js2c.py index c866c3b2c..1926a5f86 100755 --- a/targets/tools/js2c.py +++ b/targets/tools/js2c.py @@ -21,8 +21,12 @@ import glob import os import re +import argparse + +special_chars = re.compile(r'[-\\?\'".]') + def extractName(path): - return os.path.splitext(os.path.basename(path))[0] + return special_chars.sub('_', os.path.splitext(os.path.basename(path))[0]) def writeLine(fo, content, indent=0): buf = ' ' * indent + content + '\n' @@ -77,10 +81,16 @@ FOOTER = ''' OUT_PATH = './source/' SRC_PATH = './js/' +parser = argparse.ArgumentParser(description="js2c") +parser.add_argument('build_type', help='build type', default='release', nargs='?') +parser.add_argument('--ignore', help='files to ignore', dest='ignore_files', default=[], action='append') +parser.add_argument('--no-main', help='don\'t require a main.js file', dest='main', action='store_false', default=True) + +args = parser.parse_args() + # argument processing -buildtype = 'release' -if len(sys.argv) >= 2: - buildtype = sys.argv[1] +buildtype = args.build_type +ignore_files = args.ignore_files fout = open(OUT_PATH + 'jerry_targetjs.h', 'w') fout.write(LICENSE); @@ -115,7 +125,8 @@ def exportOneName(name): files = glob.glob(SRC_PATH + '*.js') for path in files: name = extractName(path) - exportOneFile(path, name) + if os.path.basename(path) not in ignore_files: + exportOneFile(path, name) NATIVE_STRUCT = ''' @@ -131,10 +142,11 @@ struct js_source_all js_codes[] = \\ ''' fout.write(NATIVE_STRUCT) -exportOneName('main') -filenames = map(extractName, files) -for name in filenames: - if name != 'main': +if args.main: + exportOneName('main') +for filename in files: + name = extractName(filename) + if name != 'main' and os.path.basename(filename) not in ignore_files: exportOneName(name) writeLine(fout, '{ NULL, NULL, 0 } \\', 1)