Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,14 @@ USEPKG += nanocoap
USEMODULE += gnrc_sock_udp
endif

ifneq (,$(filter js,$(USEMODULE)))
USEPKG += jerryscript
USEMODULE += xtimer
USEMODULE += event
USEMODULE += saul_reg
USEMODULE += saul_default
endif

# always select gpio (until explicit dependencies are sorted out)
FEATURES_OPTIONAL += periph_gpio

Expand Down
3 changes: 1 addition & 2 deletions examples/javascript/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ CFLAGS += -DDEVELHELP
# Set stack size to something (conservatively) enormous
CFLAGS += -DTHREAD_STACKSIZE_MAIN=9092

# Add the package for Jerryscript
USEPKG += jerryscript
USEMODULE += js

include $(CURDIR)/../../Makefile.include

Expand Down
117 changes: 117 additions & 0 deletions examples/javascript/lib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
print("Hello from lib.js");

timer.setInterval = function (callback, interval) {
var next = timer.now() + interval;
var interval_handler = function () {
var res = callback();
if (res != false) {
now = timer.now();
while (next < now) {
next += interval;
}
next_interval = next - now;
timer.setTimeout(interval_handler, next_interval);
}
}

return timer.setTimeout(interval_handler, interval);
}

saul.type = {
CLASS_UNDEF : 0x00, /**< device class undefined */
ACT_ANY : 0x40, /**< any actuator - wildcard */
ACT_LED_RGB : 0x42, /**< actuator: RGB LED */
ACT_SERVO : 0x43, /**< actuator: servo motor */
ACT_MOTOR : 0x44, /**< actuator: motor */
ACT_SWITCH : 0x45, /**< actuator: simple on/off switch */
ACT_DIMMER : 0x46, /**< actuator: dimmable switch */
SENSE_ANY : 0x80, /**< any sensor - wildcard */
SENSE_BTN : 0x81, /**< sensor: simple button */
SENSE_TEMP : 0x82, /**< sensor: temperature */
SENSE_HUM : 0x83, /**< sensor: humidity */
SENSE_LIGHT : 0x84, /**< sensor: light */
SENSE_ACCEL : 0x85, /**< sensor: accelerometer */
SENSE_MAG : 0x86, /**< sensor: magnetometer */
SENSE_GYRO : 0x87, /**< sensor: gyroscope */
SENSE_COLOR : 0x88, /**< sensor: (light) color */
SENSE_PRESS : 0x89, /**< sensor: pressure */
SENSE_ANALOG : 0x8a, /**< sensor: raw analog value */
SENSE_UV : 0x8b, /**< sensor: UV index */
CLASS_ANY : 0xff /**< any device - wildcard */
}

saul.op = {
LT : 0,
LE : 1,
EQ : 2,
GE : 3,
GT : 4
}

saul.set_methods = function(saul_object) {
if (typeof saul_object !== 'undefined') {
saul_object.on_threshold = function(threshold, callback, operator) {
var sensor = this;
var operator = (typeof operator !== 'undefined') ? operator : saul.op.GE;
var wait_flank = true;

var poller = function() {
var val = sensor.read();
var trigger = false;
switch (operator) {
case saul.op.LT:
trigger = (val < threshold);
break;
case saul.op.LE:
trigger = (val <= threshold);
break;
case saul.op.EQ:
trigger = (val == threshold);
break;
case saul.op.GE:
trigger = (val >= threshold);
break;
case saul.op.GT:
trigger = (val > threshold);
break;
}

if (trigger && wait_flank) {
wait_flank = false;
return callback();
} else {
if (! (trigger || wait_flank)) {
wait_flank = true;
}
return true;
}
}

return timer.setInterval(poller, 100000);
}
saul_object.sample = function(n) {
var result = {
min : Number.MAX_VALUE,
max : Number.MIN_VALUE,
avg : 0
}

var left = n
while (left > 0) {
var val = this.read();
result.avg += val;
result.max = Math.max(result.max, val);
result.min = Math.min(result.min, val);
left -= 1;
}
result.avg /= n;
return result;
}
}
}

saul.get_one = function(type) {
var res = saul._get_one(type);
saul.set_methods(res);
return res;
}
52 changes: 16 additions & 36 deletions examples/javascript/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,53 +23,33 @@
#include <stdio.h>
#include <string.h>

#include "jerryscript.h"
#include "jerryscript-ext/handler.h"
#include "js.h"

/* include header generated from main.js */
/* include headers generated from *.js */
#include "lib.js.h"
#include "main.js.h"

int js_run(const jerry_char_t *script, size_t script_size)
{
jerry_value_t ret_value;

/* Initialize engine */
jerry_init(JERRY_INIT_EMPTY);

/* Register the print function in the global object. */
jerryx_handler_register_global((const jerry_char_t *) "print", jerryx_handler_print);

/* Setup Global scope code */
ret_value = jerry_parse(script, script_size, false);

if (!jerry_value_has_error_flag(ret_value)) {
/* Execute the parsed source code in the Global scope */
ret_value = jerry_run(ret_value);
}

int res = 0;

if (jerry_value_has_error_flag(ret_value)) {
printf("js_run(): Script Error!");
res = -1;
}

jerry_release_value(ret_value);

/* Cleanup engine */
jerry_cleanup();

return res;
}
static event_queue_t event_queue;

int main(void)
{
printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
printf("This board features a(n) %s MCU.\n", RIOT_MCU);

printf("Executing main.js:\n");
event_queue_init(&event_queue);

puts("Initializing jerryscript...");
js_event_queue = &event_queue;
js_init();

puts("Executing lib.js...");
js_run(lib_js, lib_js_len);

puts("Executing main.js...");
js_run(main_js, main_js_len);

puts("Entering event loop...");
event_loop(&event_queue);

return 0;
}
13 changes: 12 additions & 1 deletion examples/javascript/main.js
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
print("Hello from JerryScript!");
print("Hello from JerryScript!!!!");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Real important change ^^!!!!


//var n = 0;
//timer.setInterval(function () { n += 1; print(n, "triggers, time is", timer.now()); }, 1000000);

button = saul.get_one(saul.type.SENSE_BTN);
led = saul.get_one(saul.type.ACT_SWITCH);

led.write(1);

button.on_threshold(0, function(){led.write(0); return true;}, saul.op.EQ);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kaspar030 how about showing some timer function too, for documentation purposes ;)
Something more or less like below, i.e. blink if you press the button?

blink = function () {
while (1) {
    value += 1 % 2;
    this.led.write(value);
    t = timer.setTimeout(this.blink, 500000);
   }
}
button.on_threshold(0, this.blink}, saul.op.EQ);

button.on_threshold(1, function(){led.write(1); return true;});
63 changes: 63 additions & 0 deletions sys/include/js.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#ifndef JS_H
#define JS_H

#include "clist.h"
#include "event.h"
#include "jerryscript.h"
#include "jerryscript-ext/handler.h"

extern event_queue_t *js_event_queue;

typedef struct {
const char *name;
jerry_external_handler_t handler;
} js_native_method_t;

typedef struct {
const char *name;
const js_native_method_t *methods;
} js_native_objects_t;

typedef struct {
list_node_t ref;
jerry_value_t object;
} js_native_ref_t;

typedef struct {
event_t event;
js_native_ref_t callback;
} js_callback_t;

void js_init(void);
int js_run(const jerry_char_t *script, size_t script_size);

/* internal */
void js_native_ref_add(js_native_ref_t *ref, jerry_value_t object);
void js_native_ref_rem(js_native_ref_t *ref);
void js_init_objects(void);
void js_add_external_handler(jerry_value_t object, const char *name, jerry_external_handler_t handler);
void js_add_object(jerry_value_t object, jerry_value_t other, const char *name);
void *js_get_object_native_pointer(jerry_value_t object, const jerry_object_native_info_t *type);
jerry_value_t js_object_create_with_methods(const js_native_method_t *methods, unsigned num_methods);
jerry_value_t js_object_native_create(size_t size, const jerry_object_native_info_t *native_obj_type_info);
void js_callback_isr(void *arg);
void js_call_function(jerry_value_t callback);
void js_callback_init(js_callback_t *js_callback, jerry_value_t callback);
void js_callback_run(js_callback_t *js_callback);
void js_callback_cancel(js_callback_t *callback);
void js_shutdown(event_t *shutdown_done_event);
char *js_strdup(jerry_value_t string);

double js_object_get_number(jerry_value_t object, const char *name);
jerry_value_t js_get_property(jerry_value_t object, const char *name);

#define js_check(x) if (jerry_value_has_error_flag(x)) printf("%s:%u: js_check("#x") failed!\n", __FILE__, __LINE__)

#define JS_EXTERNAL_HANDLER(name) \
jerry_value_t \
js_external_handler_ ## name (const jerry_value_t func_value, \
const jerry_value_t this_value, \
const jerry_value_t * args_p, \
const jerry_length_t args_cnt)

#endif /* JS_H */
1 change: 1 addition & 0 deletions sys/js/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base
48 changes: 48 additions & 0 deletions sys/js/callback.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "js.h"

#define ENABLE_DEBUG (0)
#include "debug.h"

void js_callback_isr(void *arg)
{
js_callback_t *js_callback = (js_callback_t *)arg;
DEBUG("trigger %p\n", js_callback);
event_post(js_event_queue, &js_callback->event);
}

static void js_event_callback(event_t *event)
{
js_callback_t *js_callback = (js_callback_t *) event;
js_callback_run(js_callback);
}

void js_callback_init(js_callback_t *js_callback, jerry_value_t callback)
{
DEBUG("init %p\n", js_callback);
js_callback->event.handler = js_event_callback;

DEBUG("acquire obj %lu\n", js_callback->callback.object);
js_native_ref_add(&js_callback->callback, callback);
}

static void js_callback_cleanup(js_callback_t *js_callback)
{
DEBUG("release %lu\n", callback);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sed 's/callback/js_callback'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(and add ->callback.object?)

js_native_ref_rem(&js_callback->callback);
}

void js_callback_run(js_callback_t *js_callback)
{
DEBUG("run %p\n", js_callback);
jerry_value_t callback = js_callback->callback.object;
js_call_function(callback);
js_callback_cleanup(js_callback);
}

void js_callback_cancel(js_callback_t *js_callback)
{
DEBUG("cancel %p\n", js_callback);
event_cancel(js_event_queue, &js_callback->event);
js_callback_cleanup(js_callback);
}

30 changes: 30 additions & 0 deletions sys/js/init.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "event.h"
#include "js.h"

extern const js_native_method_t riot_methods[];
extern const unsigned riot_methods_len;

extern const js_native_method_t timer_methods[];
extern const unsigned timer_methods_len;

extern const js_native_method_t saul_methods[];
extern const unsigned saul_methods_len;

void js_init_objects(void)
{
jerry_value_t global_object = jerry_get_global_object();

jerry_value_t riot_object = js_object_create_with_methods(riot_methods, riot_methods_len);
js_add_object(global_object, riot_object, "riot");
jerry_release_value(riot_object);

jerry_value_t timer_object = js_object_create_with_methods(timer_methods, timer_methods_len);
js_add_object(global_object, timer_object, "timer");
jerry_release_value(timer_object);

jerry_value_t saul_object = js_object_create_with_methods(saul_methods, saul_methods_len);
js_add_object(global_object, saul_object, "saul");
jerry_release_value(saul_object);

jerry_release_value(global_object);
}
Loading