Separate targets into os and baremetal-sdk parts (#4842)

JerryScript-DCO-1.0-Signed-off-by: Roland Takacs roland.takacs@h-lab.eu
This commit is contained in:
Roland Takacs
2021-12-06 11:02:52 +01:00
committed by GitHub
parent 9860d66a56
commit af297bc578
110 changed files with 119 additions and 85 deletions
+9
View File
@@ -0,0 +1,9 @@
mbed-os
mbed-events
.build
.mbed
.temp/
mbed_settings.py
js/pins.js
source/pins.cpp
source/jerry-targetjs.h
+94
View File
@@ -0,0 +1,94 @@
# Copyright JS Foundation and other contributors, http://js.foundation
#
# 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 += --profile ./mbed-os/tools/profiles/debug.json
endif
ifeq ($(MBED_VERBOSE), 1)
MBED_CLI_FLAGS += -v
else ifeq ($(MBED_VERBOSE), 2)
MBED_CLI_FLAGS += -vv
endif
MBED_CLI_FLAGS += -D "JERRY_GLOBAL_HEAP_SIZE=$(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:
echo 'ROOT=.' > .mbed
mbed config root .
mbed toolchain GCC_ARM
mbed target $(BOARD)
mbed deploy
../../../.mbedignore:
ifeq ($(OS),Windows_NT)
copy template-mbedignore.txt ..\..\..\.mbedignore
else
cp ./template-mbedignore.txt ../../../.mbedignore
endif
+40
View File
@@ -0,0 +1,40 @@
# Copyright JS Foundation and other contributors, http://js.foundation
#
# 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.
# Default target for running the build test outside the Travis CI environment.
all:
$(MAKE) install
$(MAKE) script
## Targets for installing build dependencies of the Mbed OS 5 JerryScript target.
# Deploy Mbed and install Mbed Python dependencies.
install:
pip install mbed-cli
cd targets/os/mbedos5 && mbed deploy
pip install idna==2.5 # FIXME: workaround
pip install -r targets/os/mbedos5/mbed-os/requirements.txt
pip install -r targets/os/mbedos5/tools/requirements.txt
## Targets for building Mbed OS 5 with JerryScript.
# Build the firmware (Mbed OS 5 with JerryScript).
script:
# HACK: `EXTRA_SRC[_MOD]` are abused to pass `--library` to `mbed compile` in the `all` make target that builds an app
# HACK: this is needed because the Mbed OS 5 target code does not contain any `main` function, so the `all` make target does not link
# HACK: but the `library` make target does not build either because the launcher sources require `jerry-targetjs.h` that are explicitly not generated for libraries
$(MAKE) -C targets/os/mbedos5 BOARD=K64F EXTRA_SRC=dummy EXTRA_SRC_MOD=--library
+74
View File
@@ -0,0 +1,74 @@
# 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.
### nodejs
npm is used to install the dependencies in the local node_modules folder.
### gulp
gulp is used to automate tasks, like cloning repositories or generate source files.
If you create an own project, for more info see [mbed-js-gulp](https://github.com/ARMmbed/mbed-js-gulp).
### (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 example project as follows:
```bash
git clone https://github.com/ARMmbed/mbed-js-example
cd mbed-js-example
npm install
gulp --target=YOUR_TARGET_NAME
```
The produced file (in build/out/YOUR_TARGET_NAME) can then be uploaded to your board, and will
run when you press reset.
@@ -0,0 +1,22 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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_ANALOGIN_H
#define _JERRYSCRIPT_MBED_DRIVERS_ANALOGIN_H
#include "jerryscript-mbed-library-registry/wrap_tools.h"
DECLARE_CLASS_CONSTRUCTOR(AnalogIn);
#endif // _JERRYSCRIPT_MBED_DRIVERS_ANALOGIN_H
@@ -0,0 +1,22 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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
@@ -0,0 +1,22 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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
@@ -0,0 +1,22 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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
@@ -0,0 +1,22 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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_PWMOUT_H
#define _JERRYSCRIPT_MBED_DRIVERS_PWMOUT_H
#include "jerryscript-mbed-library-registry/wrap_tools.h"
DECLARE_CLASS_CONSTRUCTOR(PwmOut);
#endif // _JERRYSCRIPT_MBED_DRIVERS_PWMOUT_H
@@ -0,0 +1,42 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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-ext/handler.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/I2C-js.h"
#include "jerryscript-mbed-drivers/AnalogIn-js.h"
#include "jerryscript-mbed-drivers/PwmOut-js.h"
DECLARE_JS_WRAPPER_REGISTRATION (base) {
REGISTER_GLOBAL_FUNCTION_WITH_HANDLER(assert, jerryx_handler_assert);
REGISTER_GLOBAL_FUNCTION_WITH_HANDLER(gc, jerryx_handler_gc);
REGISTER_GLOBAL_FUNCTION_WITH_HANDLER(print, jerryx_handler_print);
REGISTER_GLOBAL_FUNCTION(setInterval);
REGISTER_GLOBAL_FUNCTION(setTimeout);
REGISTER_GLOBAL_FUNCTION(clearInterval);
REGISTER_GLOBAL_FUNCTION(clearTimeout);
REGISTER_CLASS_CONSTRUCTOR(DigitalOut);
REGISTER_CLASS_CONSTRUCTOR(I2C);
REGISTER_CLASS_CONSTRUCTOR(InterruptIn);
REGISTER_CLASS_CONSTRUCTOR(AnalogIn);
REGISTER_CLASS_CONSTRUCTOR(PwmOut);
}
#endif // _JERRYSCRIPT_MBED_DRIVERS_LIB_DRIVERS_H
@@ -0,0 +1,23 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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);
DECLARE_GLOBAL_FUNCTION(clearInterval);
#endif // _JERRYSCRIPT_MBED_DRIVERS_SET_INTERVAL_H
@@ -0,0 +1,23 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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);
DECLARE_GLOBAL_FUNCTION(clearTimeout);
#endif // _JERRYSCRIPT_MBED_DRIVERS_SET_TIMEOUT_H
@@ -0,0 +1,114 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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/wrap_tools.h"
#include "jerryscript-mbed-util/logging.h"
#include "mbed.h"
/**
* AnalogIn#destructor
*
* Called if/when the AnalogIn is GC'ed.
*/
void
NAME_FOR_CLASS_NATIVE_DESTRUCTOR (AnalogIn) (void* void_ptr, jerry_object_native_info_t* info_p)
{
(void) info_p;
delete static_cast<AnalogIn*> (void_ptr);
}
/**
* Type infomation of the native AnalogIn pointer
*
* Set AnalogIn#destructor as the free callback.
*/
static const jerry_object_native_info_t native_obj_type_info = { .free_cb =
NAME_FOR_CLASS_NATIVE_DESTRUCTOR (AnalogIn) };
/**
* AnalogIn#read (native JavaScript method)
*
* Read the input voltage, represented as a float in the range [0.0, 1.0]
*
* @returns A floating-point value representing the current input voltage, measured as a percentage
*/
DECLARE_CLASS_FUNCTION (AnalogIn, read)
{
CHECK_ARGUMENT_COUNT (AnalogIn, read, (args_count == 0));
// Extract native AnalogIn pointer
void* void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native AnalogIn pointer");
}
AnalogIn* native_ptr = static_cast<AnalogIn*> (void_ptr);
float result = native_ptr->read ();
return jerry_number (result);
}
/**
* AnalogIn#read_u16 (native JavaScript method)
*
* Read the input voltage, represented as an unsigned short in the range [0x0, 0xFFFF]
*
* @returns 16-bit unsigned short representing the current input voltage, normalised to a 16-bit value
*/
DECLARE_CLASS_FUNCTION (AnalogIn, read_u16)
{
CHECK_ARGUMENT_COUNT (AnalogIn, read_u16, (args_count == 0));
// Extract native AnalogIn pointer
void* void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native AnalogIn pointer");
}
AnalogIn* native_ptr = static_cast<AnalogIn*> (void_ptr);
uint16_t result = native_ptr->read_u16 ();
return jerry_number (result);
}
/**
* AnalogIn (native JavaScript constructor)
*
* @param pin_name mbed pin to connect the AnalogIn to.
* @returns a JavaScript object representing a AnalogIn.
*/
DECLARE_CLASS_CONSTRUCTOR (AnalogIn)
{
CHECK_ARGUMENT_COUNT (AnalogIn, __constructor, args_count == 1);
CHECK_ARGUMENT_TYPE_ALWAYS (AnalogIn, __constructor, 0, number);
PinName pin_name = PinName (jerry_value_as_number (args[0]));
// create native object
AnalogIn* native_ptr = new AnalogIn (pin_name);
// create the jerryscript object
jerry_value_t js_object = jerry_object ();
jerry_object_set_native_ptr (js_object, &native_obj_type_info, native_ptr);
// attach methods
ATTACH_CLASS_FUNCTION (js_object, AnalogIn, read);
ATTACH_CLASS_FUNCTION (js_object, AnalogIn, read_u16);
return js_object;
}
@@ -0,0 +1,158 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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/wrap_tools.h"
#include "jerryscript-mbed-util/logging.h"
#include "mbed.h"
/**
* DigitalOut#destructor
*
* Called if/when the DigitalOut is GC'ed.
*/
void
NAME_FOR_CLASS_NATIVE_DESTRUCTOR (DigitalOut) (void* void_ptr, jerry_object_native_info_t* info_p)
{
(void) info_p;
delete static_cast<DigitalOut*> (void_ptr);
}
/**
* Type infomation of the native DigitalOut pointer
*
* Set DigitalOut#destructor as the free callback.
*/
static const jerry_object_native_info_t native_obj_type_info = { .free_cb =
NAME_FOR_CLASS_NATIVE_DESTRUCTOR (DigitalOut) };
/**
* 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
void* void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native DigitalOut pointer");
}
DigitalOut* native_ptr = static_cast<DigitalOut*> (void_ptr);
int arg0 = jerry_value_as_number (args[0]);
native_ptr->write (arg0);
return jerry_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
void* void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native DigitalOut pointer");
}
DigitalOut* native_ptr = static_cast<DigitalOut*> (void_ptr);
int result = native_ptr->read ();
return jerry_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
void* void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native DigitalOut pointer");
}
DigitalOut* native_ptr = static_cast<DigitalOut*> (void_ptr);
int result = native_ptr->is_connected ();
return jerry_number (result);
}
/**
* 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));
DigitalOut* native_ptr;
// Call correct overload of DigitalOut::DigitalOut depending on the
// arguments passed.
PinName pin_name = PinName (jerry_value_as_number (args[0]));
switch (args_count)
{
case 1:
native_ptr = new DigitalOut (pin_name);
break;
case 2:
int value = static_cast<int> (jerry_value_as_number (args[1]));
native_ptr = new DigitalOut (pin_name, value);
break;
}
// create the jerryscript object
jerry_value_t js_object = jerry_object ();
jerry_object_set_native_ptr (js_object, &native_obj_type_info, native_ptr);
// 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;
}
@@ -0,0 +1,327 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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/I2C-js.h"
#include "jerryscript-mbed-library-registry/wrap_tools.h"
#include "jerryscript-mbed-util/logging.h"
#include "mbed.h"
/**
* I2C#destructor
*
* Called if/when the I2C object is GC'ed.
*/
void
NAME_FOR_CLASS_NATIVE_DESTRUCTOR (I2C) (void *void_ptr, jerry_object_native_info_t *info_p)
{
(void) info_p;
delete static_cast<I2C *> (void_ptr);
}
/**
* Type infomation of the native I2C pointer
*
* Set I2C#destructor as the free callback.
*/
static const jerry_object_native_info_t native_obj_type_info = { .free_cb = NAME_FOR_CLASS_NATIVE_DESTRUCTOR (I2C) };
/**
* 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
void *void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native I2C pointer");
}
I2C *native_ptr = static_cast<I2C *> (void_ptr);
int hz = jerry_value_as_number (args[0]);
native_ptr->frequency (hz);
return jerry_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);
void *void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native I2C pointer");
}
I2C *native_ptr = static_cast<I2C *> (void_ptr);
int data = jerry_value_as_number (args[0]);
int result = native_ptr->read (data);
return jerry_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));
void *void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native I2C pointer");
}
I2C *native_ptr = static_cast<I2C *> (void_ptr);
const uint32_t data_len = jerry_array_length (args[1]);
int address = jerry_value_as_number (args[0]);
int length = jerry_value_as_number (args[2]);
char *data = new char[data_len];
bool repeated = false;
if (args_count == 4)
{
repeated = jerry_value_is_true (args[3]);
}
int result = native_ptr->read (address, data, length, repeated);
jerry_value_t out_array = jerry_array (data_len);
for (uint32_t i = 0; i < data_len; i++)
{
jerry_value_t val = jerry_number (double (data[i]));
jerry_value_free (jerry_object_set_index (out_array, i, val));
jerry_value_free (val);
}
delete[] data;
if (result == 0)
{
// ACK
return out_array;
}
else
{
// NACK
const char *error_msg = "NACK received from I2C bus";
jerry_value_free (out_array);
return jerry_throw_sz (JERRY_ERROR_COMMON, 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
void *void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native I2C pointer");
}
I2C *native_ptr = static_cast<I2C *> (void_ptr);
// Unwrap arguments
int data = jerry_value_as_number (args[0]);
int result = native_ptr->write (data);
return jerry_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
void *void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr != NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native I2C pointer");
}
I2C *native_ptr = static_cast<I2C *> (void_ptr);
// Unwrap arguments
int address = jerry_value_as_number (args[0]);
const uint32_t data_len = jerry_array_length (args[1]);
int length = jerry_value_as_number (args[2]);
bool repeated = args_count == 4 && jerry_value_is_true (args[3]);
// Construct data byte array
char *data = new char[data_len];
for (uint32_t i = 0; i < data_len; i++)
{
data[i] = jerry_value_as_number (jerry_object_get_index (args[1], i));
}
int result = native_ptr->write (address, data, length, repeated);
// free dynamically allocated resources
delete[] data;
return jerry_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
void *void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native I2C pointer");
}
I2C *native_ptr = static_cast<I2C *> (void_ptr);
native_ptr->start ();
return jerry_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
void *void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native I2C pointer");
}
I2C *native_ptr = static_cast<I2C *> (void_ptr);
native_ptr->stop ();
return jerry_undefined ();
}
/**
* 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_value_as_number (args[0]);
int scl = jerry_value_as_number (args[1]);
I2C *native_ptr = new I2C ((PinName) sda, (PinName) scl);
jerry_value_t js_object = jerry_object ();
jerry_object_set_native_ptr (js_object, &native_obj_type_info, native_ptr);
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;
}
@@ -0,0 +1,272 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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"
#include "jerryscript-mbed-library-registry/wrap_tools.h"
#include "jerryscript-mbed-util/logging.h"
#include "mbed.h"
/**
* InterruptIn#destructor
*
* Called if/when the InterruptIn object is GC'ed.
*/
void
NAME_FOR_CLASS_NATIVE_DESTRUCTOR (InterruptIn) (void *void_ptr, jerry_object_native_info_t *info_p)
{
(void) info_p;
InterruptIn *native_ptr = static_cast<InterruptIn *> (void_ptr);
native_ptr->rise (0);
native_ptr->fall (0);
delete native_ptr;
}
/**
* Type infomation of the native InterruptIn pointer
*
* Set InterruptIn#destructor as the free callback.
*/
static const jerry_object_native_info_t native_obj_type_info = { .free_cb =
NAME_FOR_CLASS_NATIVE_DESTRUCTOR (InterruptIn) };
/**
* 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[0]))
{
void *void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native InterruptIn pointer");
}
InterruptIn *native_ptr = static_cast<InterruptIn *> (void_ptr);
jerry_value_t property_name = jerry_string_sz ("cb_rise");
jerry_value_t cb_func = jerry_object_get (call_info_p->this_value, property_name);
jerry_value_free (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);
}
jerry_value_free (cb_func);
native_ptr->rise (0);
return jerry_undefined ();
}
// Assuming we actually have a callback now...
CHECK_ARGUMENT_TYPE_ALWAYS (InterruptIn, rise, 0, function);
void *void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native InterruptIn pointer");
}
InterruptIn *native_ptr = static_cast<InterruptIn *> (void_ptr);
jerry_value_t f = args[0];
// Pass the function to EventLoop.
mbed::Callback<void ()> cb = mbed::js::EventLoop::getInstance ().wrapFunction (f);
native_ptr->rise (cb);
// Keep track of our callback internally.
jerry_value_t property_name = jerry_string_sz ("cb_rise");
jerry_value_free (jerry_object_set (call_info_p->this_value, property_name, f));
jerry_value_free (property_name);
return jerry_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[0]))
{
void *void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native InterruptIn pointer");
}
InterruptIn *native_ptr = static_cast<InterruptIn *> (void_ptr);
jerry_value_t property_name = jerry_string_sz ("cb_fall");
jerry_value_t cb_func = jerry_object_get (call_info_p->this_value, property_name);
jerry_value_free (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);
}
jerry_value_free (cb_func);
native_ptr->fall (0);
return jerry_undefined ();
}
// Assuming we actually have a callback now...
CHECK_ARGUMENT_TYPE_ALWAYS (InterruptIn, fall, 0, function);
void *void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native InterruptIn pointer");
}
InterruptIn *native_ptr = static_cast<InterruptIn *> (void_ptr);
jerry_value_t f = args[0];
// Pass the function to EventLoop.
mbed::Callback<void ()> cb = mbed::js::EventLoop::getInstance ().wrapFunction (f);
native_ptr->fall (cb);
// Keep track of our callback internally.
jerry_value_t property_name = jerry_string_sz ("cb_fall");
jerry_value_free (jerry_object_set (call_info_p->this_value, property_name, f));
jerry_value_free (property_name);
return jerry_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);
void *void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native InterruptIn pointer");
}
InterruptIn *native_ptr = static_cast<InterruptIn *> (void_ptr);
int pull = jerry_value_as_number (args[0]);
native_ptr->mode ((PinMode) pull);
return jerry_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));
void *void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native InterruptIn pointer");
}
InterruptIn *native_ptr = static_cast<InterruptIn *> (void_ptr);
native_ptr->disable_irq ();
return jerry_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));
void *void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native InterruptIn pointer");
}
InterruptIn *native_ptr = static_cast<InterruptIn *> (void_ptr);
native_ptr->enable_irq ();
return jerry_undefined ();
}
/**
* 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_value_as_number (args[0]);
InterruptIn *native_ptr = new InterruptIn ((PinName) pin);
jerry_value_t js_object = jerry_object ();
jerry_object_set_native_ptr (js_object, &native_obj_type_info, native_ptr);
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;
}
@@ -0,0 +1,292 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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/wrap_tools.h"
#include "jerryscript-mbed-util/logging.h"
#include "mbed.h"
/**
* PwmOut#destructor
*
* Called if/when the PwmOut is GC'ed.
*/
void
NAME_FOR_CLASS_NATIVE_DESTRUCTOR (PwmOut) (void* void_ptr, jerry_object_native_info_t* info_p)
{
(void) info_p;
delete static_cast<PwmOut*> (void_ptr);
}
/**
* Type infomation of the native PwmOut pointer
*
* Set PwmOut#destructor as the free callback.
*/
static const jerry_object_native_info_t native_obj_type_info = { .free_cb = NAME_FOR_CLASS_NATIVE_DESTRUCTOR (PwmOut) };
/**
* PwmOut#write (native JavaScript method)
*
* Set the ouput duty-cycle, specified as a percentage (float)
*
* @param value A floating-point value representing the output duty-cycle,
* specified as a percentage. The value should lie between
* 0.0 (representing on 0%) and 1.0 (representing on 100%).
* Values outside this range will be saturated to 0.0f or 1.0f
* @returns undefined
*/
DECLARE_CLASS_FUNCTION (PwmOut, write)
{
CHECK_ARGUMENT_COUNT (PwmOut, write, (args_count == 1));
CHECK_ARGUMENT_TYPE_ALWAYS (PwmOut, write, 0, number);
// Extract native PwmOut pointer
void* void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native PwmOut pointer");
}
PwmOut* native_ptr = static_cast<PwmOut*> (void_ptr);
double arg0 = jerry_value_as_number (args[0]);
native_ptr->write (static_cast<float> (arg0));
return jerry_undefined ();
}
/**
* PwmOut#read (native JavaScript method)
*
* Return the current output duty-cycle setting, measured as a percentage (float)
*
* @returns
* A floating-point value representing the current duty-cycle being output on the pin,
* measured as a percentage. The returned value will lie between
* 0.0 (representing on 0%) and 1.0 (representing on 100%).
*
* @note
* This value may not match exactly the value set by a previous <write>.
*/
DECLARE_CLASS_FUNCTION (PwmOut, read)
{
CHECK_ARGUMENT_COUNT (PwmOut, read, (args_count == 0));
// Extract native PwmOut pointer
void* void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native PwmOut pointer");
}
PwmOut* native_ptr = static_cast<PwmOut*> (void_ptr);
float result = native_ptr->read ();
return jerry_number (result);
}
/**
* PwmOut#period (native JavaScript method)
*
* Set the PWM period, specified in seconds (float), keeping the duty cycle the same.
*
* @note
* The resolution is currently in microseconds; periods smaller than this
* will be set to zero.
*/
DECLARE_CLASS_FUNCTION (PwmOut, period)
{
CHECK_ARGUMENT_COUNT (PwmOut, period, (args_count == 1));
CHECK_ARGUMENT_TYPE_ALWAYS (PwmOut, period, 0, number);
// Extract native PwmOut pointer
void* void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native PwmOut pointer");
}
PwmOut* native_ptr = static_cast<PwmOut*> (void_ptr);
double arg0 = jerry_value_as_number (args[0]);
native_ptr->period (static_cast<float> (arg0));
return jerry_undefined ();
}
/**
* PwmOut#period_ms (native JavaScript method)
*
* Set the PWM period, specified in milli-seconds (int), keeping the duty cycle the same.
*/
DECLARE_CLASS_FUNCTION (PwmOut, period_ms)
{
CHECK_ARGUMENT_COUNT (PwmOut, period_ms, (args_count == 1));
CHECK_ARGUMENT_TYPE_ALWAYS (PwmOut, period_ms, 0, number);
// Extract native PwmOut pointer
void* void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native PwmOut pointer");
}
PwmOut* native_ptr = static_cast<PwmOut*> (void_ptr);
double arg0 = jerry_value_as_number (args[0]);
native_ptr->period_ms (static_cast<int> (arg0));
return jerry_undefined ();
}
/**
* PwmOut#period_us (native JavaScript method)
*
* Set the PWM period, specified in micro-seconds (int), keeping the duty cycle the same.
*/
DECLARE_CLASS_FUNCTION (PwmOut, period_us)
{
CHECK_ARGUMENT_COUNT (PwmOut, period_us, (args_count == 1));
CHECK_ARGUMENT_TYPE_ALWAYS (PwmOut, period_us, 0, number);
// Extract native PwmOut pointer
void* void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native PwmOut pointer");
}
PwmOut* native_ptr = static_cast<PwmOut*> (void_ptr);
double arg0 = jerry_value_as_number (args[0]);
native_ptr->period_us (static_cast<int> (arg0));
return jerry_undefined ();
}
/**
* PwmOut#pulsewidth (native JavaScript method)
*
* Set the PWM pulsewidth, specified in seconds (float), keeping the period the same.
*/
DECLARE_CLASS_FUNCTION (PwmOut, pulsewidth)
{
CHECK_ARGUMENT_COUNT (PwmOut, pulsewidth, (args_count == 1));
CHECK_ARGUMENT_TYPE_ALWAYS (PwmOut, pulsewidth, 0, number);
// Extract native PwmOut pointer
void* void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native PwmOut pointer");
}
PwmOut* native_ptr = static_cast<PwmOut*> (void_ptr);
double arg0 = jerry_value_as_number (args[0]);
native_ptr->pulsewidth (static_cast<float> (arg0));
return jerry_undefined ();
}
/**
* PwmOut#pulsewidth_ms (native JavaScript method)
*
* Set the PWM pulsewidth, specified in milli-seconds (int), keeping the period the same.
*/
DECLARE_CLASS_FUNCTION (PwmOut, pulsewidth_ms)
{
CHECK_ARGUMENT_COUNT (PwmOut, pulsewidth_ms, (args_count == 1));
CHECK_ARGUMENT_TYPE_ALWAYS (PwmOut, pulsewidth_ms, 0, number);
// Extract native PwmOut pointer
void* void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native PwmOut pointer");
}
PwmOut* native_ptr = static_cast<PwmOut*> (void_ptr);
double arg0 = jerry_value_as_number (args[0]);
native_ptr->pulsewidth_ms (static_cast<int> (arg0));
return jerry_undefined ();
}
/**
* PwmOut#pulsewidth_us (native JavaScript method)
*
* Set the PWM pulsewidth, specified in micro-seconds (int), keeping the period the same.
*/
DECLARE_CLASS_FUNCTION (PwmOut, pulsewidth_us)
{
CHECK_ARGUMENT_COUNT (PwmOut, pulsewidth_us, (args_count == 1));
CHECK_ARGUMENT_TYPE_ALWAYS (PwmOut, pulsewidth_us, 0, number);
// Extract native PwmOut pointer
void* void_ptr = jerry_object_get_native_ptr (call_info_p->this_value, &native_obj_type_info);
if (void_ptr == NULL)
{
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to get native PwmOut pointer");
}
PwmOut* native_ptr = static_cast<PwmOut*> (void_ptr);
double arg0 = jerry_value_as_number (args[0]);
native_ptr->pulsewidth_us (static_cast<int> (arg0));
return jerry_undefined ();
}
/**
* PwmOut (native JavaScript constructor)
*
* @param pin_name mbed pin to connect the PwmOut to.
* @returns a JavaScript object representing a PwmOut.
*/
DECLARE_CLASS_CONSTRUCTOR (PwmOut)
{
CHECK_ARGUMENT_COUNT (PwmOut, __constructor, args_count == 1);
CHECK_ARGUMENT_TYPE_ALWAYS (PwmOut, __constructor, 0, number);
PinName pin_name = PinName (jerry_value_as_number (args[0]));
// Create the native object
PwmOut* native_ptr = new PwmOut (pin_name);
// create the jerryscript object
jerry_value_t js_object = jerry_object ();
jerry_object_set_native_ptr (js_object, &native_obj_type_info, native_ptr);
// attach methods
ATTACH_CLASS_FUNCTION (js_object, PwmOut, write);
ATTACH_CLASS_FUNCTION (js_object, PwmOut, read);
ATTACH_CLASS_FUNCTION (js_object, PwmOut, period);
ATTACH_CLASS_FUNCTION (js_object, PwmOut, period_ms);
ATTACH_CLASS_FUNCTION (js_object, PwmOut, period_us);
ATTACH_CLASS_FUNCTION (js_object, PwmOut, pulsewidth);
ATTACH_CLASS_FUNCTION (js_object, PwmOut, pulsewidth_ms);
ATTACH_CLASS_FUNCTION (js_object, PwmOut, pulsewidth_us);
return js_object;
}
@@ -0,0 +1,82 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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);
int interval = int (jerry_value_as_number (args[1]));
int id = mbed::js::EventLoop::getInstance ().getQueue ().call_every (interval,
jerry_call,
args[0],
jerry_null (),
(jerry_value_t*) NULL,
0);
jerry_value_t result = jerry_object_set_index (call_info_p->function, id, args[0]);
if (jerry_value_is_exception (result))
{
jerry_value_free (result);
mbed::js::EventLoop::getInstance ().getQueue ().cancel (id);
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to run setInterval");
}
jerry_value_free (result);
return jerry_number (id);
}
/**
* clearInterval (native JavaScript function)
*
* Cancel an event that was previously scheduled via setInterval.
*
* @param id ID of the timeout event, returned by setInterval.
*/
DECLARE_GLOBAL_FUNCTION (clearInterval)
{
CHECK_ARGUMENT_COUNT (global, clearInterval, (args_count == 1));
CHECK_ARGUMENT_TYPE_ALWAYS (global, clearInterval, 0, number);
int id = int (jerry_value_as_number (args[0]));
mbed::js::EventLoop::getInstance ().getQueue ().cancel (id);
jerry_value_t global_obj = jerry_current_realm ();
jerry_value_t prop_name = jerry_string_sz ("setInterval");
jerry_value_t func_obj = jerry_object_get (global_obj, prop_name);
jerry_value_free (prop_name);
jerry_object_delete_index (func_obj, id);
jerry_value_free (func_obj);
jerry_value_free (global_obj);
return jerry_undefined ();
}
@@ -0,0 +1,82 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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);
int interval = int (jerry_value_as_number (args[1]));
int id = mbed::js::EventLoop::getInstance ().getQueue ().call_in (interval,
jerry_call,
args[0],
jerry_null (),
(jerry_value_t*) NULL,
0);
jerry_value_t result = jerry_object_set_index (call_info_p->function, id, args[0]);
if (jerry_value_is_exception (result))
{
jerry_value_free (result);
mbed::js::EventLoop::getInstance ().getQueue ().cancel (id);
return jerry_throw_sz (JERRY_ERROR_TYPE, "Failed to run setTimeout");
}
jerry_value_free (result);
return jerry_number (id);
}
/**
* clearTimeout (native JavaScript function)
*
* Cancel an event that was previously scheduled via setTimeout.
*
* @param id ID of the timeout event, returned by setTimeout.
*/
DECLARE_GLOBAL_FUNCTION (clearTimeout)
{
CHECK_ARGUMENT_COUNT (global, clearTimeout, (args_count == 1));
CHECK_ARGUMENT_TYPE_ALWAYS (global, clearTimeout, 0, number);
int id = int (jerry_value_as_number (args[0]));
mbed::js::EventLoop::getInstance ().getQueue ().cancel (id);
jerry_value_t global_obj = jerry_current_realm ();
jerry_value_t prop_name = jerry_string_sz ("setTimeout");
jerry_value_t func_obj = jerry_object_get (global_obj, prop_name);
jerry_value_free (prop_name);
jerry_object_delete_index (func_obj, id);
jerry_value_free (func_obj);
jerry_value_free (global_obj);
return jerry_undefined ();
}
@@ -0,0 +1,114 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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<typename T>
class BoundCallback;
template<typename R, typename A0>
class BoundCallback<R(A0)> {
public:
BoundCallback(Callback<R(A0)> cb, A0 a0) : a0(a0), cb(cb) { }
void call() {
cb(a0);
}
operator Callback<void()>() {
Callback<void()> cb(this, &BoundCallback::call);
return cb;
}
private:
A0 a0;
Callback<R(A0)> cb;
};
template<typename R, typename A0, typename A1>
class BoundCallback<R(A0, A1)> {
public:
BoundCallback(Callback<R(A0, A1)> cb, A0 a0, A1 a1) : a0(a0), a1(a1), cb(cb) { }
void call() {
cb(a0, a1);
}
operator Callback<void()>() {
Callback<void()> cb(this, &BoundCallback::call);
return cb;
}
private:
A0 a0;
A0 a1;
Callback<R(A0, A1)> cb;
};
template<typename R, typename A0, typename A1, typename A2>
class BoundCallback<R(A0, A1, A2)> {
public:
BoundCallback(Callback<R(A0, A1, A2)> cb, A0 a0, A1 a1, A2 a2) : a0(a0), a1(a1), a2(a2), cb(cb) { }
void call() {
cb(a0, a1, a2);
}
operator Callback<void()>() {
Callback<void()> cb(this, &BoundCallback::call);
return cb;
}
private:
A0 a0;
A1 a1;
A2 a2;
Callback<R(A0, A1, A2)> cb;
};
template<typename R, typename A0, typename A1, typename A2, typename A3>
class BoundCallback<R(A0, A1, A2, A3)> {
public:
BoundCallback(Callback<R(A0, A1, A2, A3)> 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<void()>() {
Callback<void()> cb(this, &BoundCallback::call);
return cb;
}
private:
A0 a0;
A1 a1;
A2 a2;
A3 a3;
Callback<R(A0, A1, A2, A3)> cb;
};
} // namespace js
} // namespace mbed
#endif // _JERRYSCRIPT_MBED_EVENT_LOOP_BOUND_CALLBACK_H
@@ -0,0 +1,99 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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 <vector>
#include "jerry-core/include/jerryscript.h"
#include "Callback.h"
#include "mbed_assert.h"
#include "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<void()> wrapFunction(jerry_value_t f) {
MBED_ASSERT(jerry_value_is_function(f));
// we need to return a callback that'll schedule this
Callback<void(uint32_t)> cb_raw(this, &EventLoop::callback);
BoundCallback<void(uint32_t)> *cb = new BoundCallback<void(uint32_t)>(cb_raw, f);
bound_callbacks.push_back(std::make_pair(f, cb));
return *cb;
}
void dropCallback(jerry_value_t f) {
for (std::vector<std::pair<jerry_value_t, BoundCallback<void(uint32_t)>*> >::iterator it = bound_callbacks.begin(); it != bound_callbacks.end(); it++) {
std::pair<jerry_value_t, BoundCallback<void(uint32_t)>*> element = *it;
if (element.first == f) {
delete element.second;
break;
}
}
}
void callback(jerry_value_t f) {
queue.call(jerry_call, f, jerry_null(), (const jerry_value_t*)NULL, 0);
}
void nativeCallback(Callback<void()> cb) {
queue.call(cb);
}
events::EventQueue& getQueue() {
return queue;
}
private:
EventLoop() {}
std::vector<std::pair<jerry_value_t, BoundCallback<void(uint32_t)>*> > bound_callbacks;
events::EventQueue queue;
};
void event_loop();
} // namespace js
} // namespace mbed
#endif // _JERRYSCRIPT_MBED_EVENT_LOOP_EVENT_LOOP_H
@@ -0,0 +1,27 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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
@@ -0,0 +1,21 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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
@@ -0,0 +1,22 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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/include/jerryscript.h"
void jsmbed_js_load_magic_strings(void);
#endif // _JERRYSCRIPT_MBED_LAUNCHER_SETUP_H
@@ -0,0 +1,95 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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/include/jerryscript.h"
#include "jerry-core/include/jerryscript-port.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<const jerry_char_t*>(js_codes[src].source);
const size_t length = js_codes[src].length;
jerry_value_t parsed_code = jerry_parse(code, length, NULL);
if (jerry_value_is_exception(parsed_code)) {
LOG_PRINT_ALWAYS("jerry_parse failed [%s]\r\n", js_codes[src].name);
jerry_value_free(parsed_code);
jsmbed_js_exit();
return -1;
}
jerry_value_t returned_value = jerry_run(parsed_code);
jerry_value_free(parsed_code);
if (jerry_value_is_exception(returned_value)) {
LOG_PRINT_ALWAYS("jerry_run failed [%s]\r\n", js_codes[src].name);
jerry_value_free(returned_value);
jsmbed_js_exit();
return -1;
}
jerry_value_free(returned_value);
}
return 0;
}
int jsmbed_js_init() {
union { double d; unsigned u; } now = { .d = jerry_port_get_current_time () };
srand (now.u);
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();
}
}
@@ -0,0 +1,54 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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-launcher/setup.h"
#include <stdio.h>
#include <stdlib.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 char *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 ((const jerry_char_t **) jsmbed_js_magic_strings,
jsmbed_js_magic_string_count,
jsmbed_js_magic_string_lengths);
jerry_value_t global = jerry_current_realm ();
for (unsigned int idx = 0; idx < jsmbed_js_magic_string_count; idx++)
{
jerry_value_t constant_value = jerry_number (jsmbed_js_magic_string_values[idx]);
jerry_value_t magic_string = jerry_string_sz (jsmbed_js_magic_strings[idx]);
jerry_value_free (jerry_object_set (global, magic_string, constant_value));
jerry_value_free (constant_value);
jerry_value_free (magic_string);
}
jerry_value_free (global);
}
@@ -0,0 +1,57 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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 <vector>
#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<library_registration_function_t> funcs;
};
} // namespace js
} // namespace mbed
#endif // _JERRYSCRIPT_MBED_LIBRARY_REGISTRY_REGISTRY_H
@@ -0,0 +1,17 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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;
@@ -0,0 +1,84 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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/wrap_tools.h"
#include <stdio.h>
#include <stdlib.h>
bool
jsmbed_wrap_register_global_function (const char* name, jerry_external_handler_t handler)
{
jerry_value_t global_object_val = jerry_current_realm ();
jerry_value_t reg_function = jerry_function_external (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_function_external failed!\r\n");
jerry_value_free (global_object_val);
jerry_value_free (reg_function);
return is_ok;
}
if (jerry_value_is_exception (reg_function))
{
is_ok = false;
LOG_PRINT_ALWAYS ("Error: jerry_function_external has error flag! \r\n");
jerry_value_free (global_object_val);
jerry_value_free (reg_function);
return is_ok;
}
jerry_value_t jerry_name = jerry_string_sz (name);
jerry_value_t set_result = jerry_object_set (global_object_val, jerry_name, reg_function);
if (jerry_value_is_exception (set_result))
{
is_ok = false;
LOG_PRINT_ALWAYS ("Error: jerry_function_external failed: [%s]\r\n", name);
}
jerry_value_free (jerry_name);
jerry_value_free (global_object_val);
jerry_value_free (reg_function);
jerry_value_free (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_string_sz (name);
jerry_value_t handler_obj = jerry_function_external (handler);
jerry_value_free (jerry_object_set (this_obj, property_name, handler_obj));
jerry_value_free (handler_obj);
jerry_value_free (property_name);
// TODO: check for errors, and return false in the case of errors
return true;
}
@@ -0,0 +1,43 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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 <stdlib.h>
#include "jerry-core/include/jerryscript.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
@@ -0,0 +1,24 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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
@@ -0,0 +1,28 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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
#include "mbed.h"
#ifdef DEBUG_WRAPPER
#define LOG_PRINT(...) printf(__VA_ARGS__)
#else /* !defined(DEBUG_WRAPPER) */
#define LOG_PRINT(...) while(0) { }
#endif /* defined(DEBUG_WRAPPER) */
#define LOG_PRINT_ALWAYS(...) printf(__VA_ARGS__)
#endif // _JERRYSCRIPT_MBED_UTIL_LOGGING_H
@@ -0,0 +1,91 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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_call_info_t* call_info_p, 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))
#define REGISTER_GLOBAL_FUNCTION_WITH_HANDLER(NAME, HANDLER) jsmbed_wrap_register_global_function (#NAME, HANDLER)
// Class constructors
#define DECLARE_CLASS_CONSTRUCTOR(CLASS) \
jerry_value_t NAME_FOR_CLASS_CONSTRUCTOR ( \
CLASS) (const jerry_call_info_t* call_info_p, 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_call_info_t* call_info_p, \
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_throw_sz (JERRY_ERROR_TYPE, 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_throw_sz (JERRY_ERROR_TYPE, 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_throw_sz (JERRY_ERROR_TYPE, 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
+76
View File
@@ -0,0 +1,76 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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.");
+20
View File
@@ -0,0 +1,20 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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.");
+1
View File
@@ -0,0 +1 @@
https://github.com/ARMmbed/mbed-os/#e4b81f67f939a0c0b11c147ce74aa367271e1279
+7
View File
@@ -0,0 +1,7 @@
{
"target_overrides": {
"NRF52_DK": {
"target.uart_hwfc": 0
}
}
}
@@ -0,0 +1,92 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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 <stdarg.h>
#include <stdlib.h>
#include <sys/time.h>
#include "jerry-core/include/jerryscript-port.h"
#include "us_ticker_api.h"
#ifndef JSMBED_OVERRIDE_JERRY_PORT_LOG
/**
* 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);
if (strlen (format) == 1 && format[0] == 0x0a) /* line feed (\n) */
{
printf ("\r"); /* add CR for proper display in serial monitors */
}
} /* jerry_port_log */
#endif /* JSMBED_OVERRIDE_JERRY_PORT_LOG */
/**
* Implementation of jerry_port_get_local_time_zone_adjustment.
*
* @return 0, as we live in UTC.
*/
double
jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc)
{
return 0;
} /* jerry_port_get_local_time_zone_adjustment */
/**
* Implementation of jerry_port_get_current_time.
*
* @return current timer's counter value in milliseconds
*/
double
jerry_port_get_current_time (void)
{
static uint64_t last_tick = 0;
static time_t last_time = 0;
static uint32_t skew = 0;
uint64_t curr_tick = us_ticker_read (); /* The value is in microseconds. */
time_t curr_time = time(NULL); /* The value is in seconds. */
double result = curr_time * 1000;
/* The us_ticker_read () has an overflow for each UINT_MAX microseconds
* (~71 mins). For each overflow event the ticker-based clock is about 33
* milliseconds fast. Without a timer thread the milliseconds part of the
* time can be corrected if the difference of two get_current_time calls
* are within the mentioned 71 mins. Above that interval we can assume
* that the milliseconds part of the time is negligibe.
*/
if (curr_time - last_time > (time_t) (((uint32_t) - 1) / 1000000)) {
skew = 0;
} else if (last_tick > curr_tick) {
skew = (skew + 33) % 1000;
}
result += (curr_tick / 1000 - skew) % 1000;
last_tick = curr_tick;
last_time = curr_time;
return result;
} /* jerry_port_get_current_time */
@@ -0,0 +1,10 @@
cmake/*
docs/*
jerry-main/*
jerry-math/*
jerry-port/default/default-date.c
jerry-port/default/default-io.c
targets/*
tests/*
third-party/*
tools/*
+31
View File
@@ -0,0 +1,31 @@
#!/bin/bash
# Copyright JS Foundation and other contributors, http://js.foundation
#
# 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
+17
View File
@@ -0,0 +1,17 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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.
*/
+221
View File
@@ -0,0 +1,221 @@
#!/usr/bin/env python
# Copyright JS Foundation and other contributors, http://js.foundation
#
# 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.cpp for a specified target, using target definitions from the
mbed OS source tree.
It's expecting to be run from the targets/os/mbedos5 directory.
"""
from __future__ import print_function
import argparse
import ast
import sys
import os
from pycparserext.ext_c_parser import GnuCParser
from pycparser import parse_file, c_ast
# import mbed tools
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'mbed-os'))
from tools.targets import Target
LICENSE = '''/* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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.
*/
'''
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[:] = [directory for directory in dirs if directory in directories or not directory.startswith('TARGET_')]
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, _ in os.walk(root_dir, topdown=True):
# modify dirs in place
dirs[:] = [dir_label for dir_label in dirs
if dir_label in directories
or (not dir_label.startswith('TARGET_')
and not dir_label.startswith('TOOLCHAIN_'))]
yield root
class TypeDeclVisitor(c_ast.NodeVisitor):
"""
A TypeDecl visitor class that walks the ast and calls a visitor function for every node found.
"""
def __init__(self, filter_names=None):
self.names = filter_names or []
def visit(self, node):
value = None
if node.__class__.__name__ == "TypeDecl":
value = self.visit_typedecl(node)
if value is None:
for _, child_node in node.children():
value = value or self.visit(child_node)
return value
def visit_typedecl(self, node):
"""
Visit a node.
"""
if node.declname in self.names:
return [pin.name for pin in node.type.values.enumerators]
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]
parsed_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
visitor = TypeDeclVisitor(['PinName'])
return visitor.visit(parsed_ast)
def write_pins_to_file(pins, pins_file, out_cpp_file):
"""
Write the generated pins for a specified mbed board into the output C++ file.
"""
include = '\n#include "../{}"'.format(pins_file)
count = '''
unsigned int jsmbed_js_magic_string_count = {};
'''.format(len(pins))
lengths = ',\n '.join(str(len(pin)) for pin in pins)
lenghts_source = '''
unsigned int jsmbed_js_magic_string_lengths[] = {
%s
};
''' % lengths
magic_values = ',\n '.join(pins)
magic_source = '''
int jsmbed_js_magic_string_values[] = {
%s
};
''' % magic_values
magic_strings = ',\n '.join('"' + pin + '"' for pin in pins)
magic_string_source = '''
const char * jsmbed_js_magic_strings[] = {
%s
};
''' % magic_strings
out_cpp_file.write(LICENSE + include + count + lenghts_source + magic_source + magic_string_source)
def main():
"""
Perform the main function of this program
"""
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.cpp 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('-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.get_target(board_name)
directory_labels = ['TARGET_' + label for label in target.labels] + target.macros
targets_dir = os.path.join('.', 'mbed-os', 'targets')
pins_file = find_file(targets_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)
# first sort alphabetically, then by length.
pins = sorted(pins, key=lambda x: (len(x), x.lower()))
write_pins_to_file(pins, pins_file, args.c)
if __name__ == "__main__":
main()
+4
View File
@@ -0,0 +1,4 @@
{
"undef": true,
"predef": ["print", "BLEDevice", "BLEService", "BLECharacteristic", "DigitalOut", "I2C", "setInterval", "setTimeout", "InterruptIn", "LWIPInterface", "SimpleMbedClient", "M2MBase"]
}
@@ -0,0 +1,2 @@
pycparserext
simpleeval