aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 8d234b4c95f453adaadf13e7b01b013d3a08f9fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
# JavaScript\* Runtime for Zephyr™ OS

The JavaScript\* Runtime for the Zephyr™ OS project (ZJS for short) provides an IoT
web runtime environment with JavaScript APIs for the Zephyr operating system,
based on the JerryScript engine. It is intended for systems with little memory
where Node.js with V8 is too big.

This code requires a local copy of JerryScript and Zephyr OS source.  We
will upstream patches to those projects as appropriate, but this repo is for
everything else.

## Getting Started

This section will walk you through building and running your first ZJS
application on Arduino 101\*.

### Prerequisites
* [Arduino 101 board](https://www.arduino.cc/en/Main/ArduinoBoard101)
* Ubuntu\* 16.04 host; adapt as necessary for other platforms.
* If you're behind a proxy, go through all the [usual pain]
(https://github.com/01org/zephyr.js/wiki/Proxy) to get ssh working to
github.com and http working to zephyrproject.org.

### Initial Setup
***Windows and OSX users***: These instructions are for Ubuntu 16.04. Be sure to
also consult Zephyr Project's [Getting Started](https://www.zephyrproject.org/doc/getting_started/getting_started.html)
documentation for [Windows](https://www.zephyrproject.org/doc/getting_started/installation_win.html)
or [OSX](https://www.zephyrproject.org/doc/getting_started/installation_mac.html).

#### Install dependencies
First, install these packages that you will need beyond those installed by
default with Ubuntu:

```bash
$ sudo apt-get update
$ sudo apt-get install cmake dfu-util git python-yaml screen sysvbanner uglifyjs
```

Note: python-yaml is a recent requirement for the frdm-k64f build due to some
change in Zephyr, so it could be left out currently if you don't use k64f.

Note: sysvbanner is just used to identify tests as they run in the trlite test
build script, so it could be left out.

#### Clone the ZJS repo
Next, clone this git repo:
```bash
$ git clone http://github.com/01org/zephyr.js.git
```

#### Check out the desired version
If you want to use a stable release version, the latest is 0.2:

```bash
$ git checkout v0.2
```

If you do nothing and remain on master, you will be looking at the very latest
changes which may have regressions or instability. You can read the `version`
file in the root of the source tree to see what version you're on. If you're on
the master development branch it will just say 'devel'.

#### Install the Zephyr SDK
Download the [latest Zephyr SDK] (https://www.zephyrproject.org/downloads), then:
```bash
$ chmod +x /path/to/zephyr-sdk-<VERSION>-setup.run
$ sudo /path/to/zephyr-sdk-<VERSION>-setup.run
```

Follow the prompts, but the defaults should be fine.

#### Set up Zephyr SDK environment variables
Add the following two lines to your `~/.bashrc`. If you installed your Zephyr SDK
elsewhere, adjust as needed.
```bash
export ZEPHYR_GCC_VARIANT=zephyr
export ZEPHYR_SDK_INSTALL_DIR=/opt/zephyr-sdk
```

Then source the .bashrc :
```bash
$ source ~/.bashrc
```

#### Join the plugdev group
Add your user to the plugdev group with this command:

```bash
$ sudo usermod -a -G plugdev USERNAME
```

#### Add udev rules
Copy these two files into your /etc/udev/rules.d directory (/etc/udev.rules for Ubuntu 14.04):

* [60-openocd.rules](https://raw.githubusercontent.com/arduino/OpenOCD/master/contrib/60-openocd.rules) (from this [Arduino github project](https://github.com/arduino/OpenOCD/blob/master/contrib/60-openocd.rules))
* [99-dfu.rules](https://raw.githubusercontent.com/01org/CODK-A-ARC/master/bin/99-dfu.rules) (from this [01org github project](https://github.com/01org/CODK-A-ARC/blob/master/bin/99-dfu.rules))

Then run this command:

```bash
$ sudo udevadm control --reload-rules
```

This should cause your `/dev/tty*` entries to have the plugdev group, which will
let you use them without root privileges. Otherwise, you will have to run some
of the following commands with `sudo`.

### Shell setup
Whenever you open a new terminal to work with this repo, you need to set up
environment variables.

#### Set up ZJS environment variables
First, the ZJS variables:

```bash
$ cd zephyr.js
$ source zjs-env.sh
```

#### Get source dependencies
Next, this command will check out additional git repos into the deps/
subdirectory, if you haven't done so before:

```bash
$ make update
```

(If this is the first time you've run this, will see an error.)

#### Set up Zephyr OS environment variables
As the previous command will complain, you need to set up some Zephyr OS
environment variables, too. Here's the right way to do that:

```bash
$ source deps/zephyr/zephyr-env.sh
```

### Build and Flash
#### x86 application image and ARC support image
Now you're ready to build the x86 and ARC images. The x86 image
includes the JerryScript engine and the ZJS runtime support, along with
your JavaScript application, and the ARC support image acts as a helper
library that channels some of the data needed from the ARC processor to the
x86 processor.

**Note**, you'll need to build both the x86 and ARC images
with the same JS file so the required sub-modules are enabled on both images.

You can build both with a single command:

```bash
$ make JS=samples/TrafficLight.js
```

The JS= argument lets you provide the path to your application. The TrafficLight
sample is a good first choice because you don't need to wire up any additional
hardware. It just blinks onboard LEDs on your Arduino 101. Also, for many of
the samples you will want to hook up the serial console (see below), but for
this one it's not really needed.

Then connect the Arduino 101 to your host with a USB A/B cable. Press the
Master Reset button on the Arduino 101 and after a few seconds type:

```bash
$ make dfu
```

This will flash both the images to the device using the dfu-util program.

If you get a permission error, make sure you followed the 'Join the plugdev
group' instructions above for this user. You shouldn't need to run this command
with `sudo`.

After this flashing completes successfully, reboot the device with the Master
Reset button to start the application. After a few seconds the onboard LEDs
should start cycling.

You have built and run your first ZJS application!

If you want to make changes to the application, or run a different .js sample,
you just need to repeat the steps the desired JavaScript filename.

### Next steps

#### Set up serial console

Without the serial console set up, you won't be able to see error messages and
other output from your ZJS application. To hook up the serial console, you need
a USB to TTL Serial Cable, such as the TTL-232R-3V3. On that particular cable,
you wire the black wire to ground on the Arduino 101 board, the orange wire to GPIO pin 0
(RX), and the yellow wire to GPIO pin 1 (TX). The other three are unused.

When you plug this in, the device should show up as something such as
`/dev/ttyUSB0`. You can then use the screen command to connect to the device
with a command such as this:

```bash
$ watch screen /dev/ttyUSB0 115200
```

The `watch` utility will restart screen when you disconnect and reconnect your
Arduino 101, so you shouldn't miss anything. You can leave a dedicated terminal
running to watch the output.

In `screen`, you can scroll back the output with Ctrl-A, Esc, followed by PgUp/PgDn.
Then Esc again to get back to the latest output (out of "Copy Mode").

#### Debugging

You can use the commands `make debug` and `make gdb` in two separate terminals
to connect to the device with a debugger. Then you can set breakpoints such as
`b main` and `run` to start debugging as usual with gdb.

#### Additional details

See below for a few more tips, such as increasing the space available for your
application on the Arduino 101, or how to use ZJS with the FRDM-K64F.

## Contributing

If you want to contribute code to the ZJS project, first you need to fork the
project. The next step is to send a pull request (PR) for review to the ZJS
repository. The PR will be reviewed by the project team members. You need at
least two plus-ones (+1) , "Look Good To Me (LGTM)" or other positive signals
for the project members. Once you have gained the required signals the project
maintainers will merge the PR.

## File Descriptions
* `zjs-env.sh` - Source this file to set environment variables and path to be
able to use tools from ```scripts/``` anywhere.
* `prj.conf` - The main configuration file for a Zephyr application; overrides
settings from a defconfig file in the Zephyr tree. In the ZJS builds, we
assemble the prj.conf file at build time from other fragments.
* `prj.mdef` - Another configuration file for a Zephyr application; we use it to
configure the heap size available to the ZJS API.

## Subdirectories
- `arc/` - Contains sensor subsystem code for ARC side of the Arduino 101.
- `deps/` - Contains dependency repos and scripts for working with them.
- `docs/` - Documentation in Markdown format (use API.md as index).
- `outdir/` - Directory generated by build, can be safely removed.
- `samples/` - Sample JavaScript files that can be built with make JS=<path>.
- `scripts/` - Subdirectory containing tools useful during development.
- `src/` - JS API bindings for JerryScript written directly on top of Zephyr.
- `tests/` - JavaScript unit tests (incomplete).

## Getting more space on your Arduino 101
Arduino 101 comes with a **144K** X86 partition, but we're able to use more
space by telling Zephyr there is more space and then splicing the images we
flash to the device. You can control this with the ROM= flag to make. So if
you want to allocated 256KB for x86, use ROM=256.

You can also just build without it until you see a message like this:
```
lfiamcu/5.2.1/real-ld: region `ROM' overflowed by 53728 bytes
```

That implies you need an extra 53K of space, so you could try passing ROM=200.
If it's the ARC image that needs more space, you should decrease the ROM you're
passing instead.

**NOTE**: Earlier, we would physically repartition the device and install a new
bootloader that knew about it. This is no longer necessary, so if you have such
a device you should restore it to factory condition with the 256-to-144
flashpack.

You can also influence the amount of RAM allocated to the X86 side with a new
RAM= argument. Here the default is 55 but it can theoretically go as high as
79 if ARC was disabled; realistically up to maybe 75 or so depending on how
few modules you require in the ARC build.

The RAM and ROM sizes being used are now displayed at the top of the make
output when you do build for Arduino 101.

## Building system images
The ZJS project uses a top-level Makefile to control the building of code from
he project itself as well as the JerryScript and Zephyr projects it depends on.

To see the available make commands, type:

```bash
$ make help
```

On Arduino 101, there are two embedded microcontrollers, an X86 and an ARC one.
If you only need the x86 side, you can disable ARC with CONFIG_ARC_INIT=n in
the Zephyr prj.conf. Otherwise, you need a working image running on it.

## Build the *Hello World* sample
```bash
$ make JS=samples/HelloWorld.js
```

This will build both an X86 and an ARC image, resulting in
`outdir/arduino_101/zephyr.bin` and `arc/outdir/arduino_101_sss/zephyr.bin`
as the final output. Then adjusted versions are created with a `.dfu` suffix.
To flash them to your device with dfu-util, first press the Master Reset button
on your Arduino 101, and about three seconds later type:

```bash
$ make dfu
```

There is a window of about five seconds where the DFU server is available,
starting a second or two after the device resets.

Now both images on your device have been updated. Press the Master Reset button
one more time to boot your new images.

## Build other samples
The other samples may require some hardware to be set up and connected; read
the top of each JS file, but then simply pass in the path to the JS file to make
as with `HelloWorld.js` above.

## JS Minifier

To save space it is recommended to use a minifier. In `convert.sh`, the script
used to encode your JS into a source file, we use `uglifyjs`. If you didn't
install this earlier, you can do so with the command:
```bash
sudo apt-get install node-uglify
```

## FRDM-K64F Platform

See the
[Zephyr Project Wiki] (https://wiki.zephyrproject.org/view/NXP_FRDM-K64F)
for general information about running Zephyr OS on the FRDM-K64F.

The instructions below assume Ubuntu 14.04 on the host PC.

Connect a micro-USB cable from the device to your PC.

If you hit the Reset switch and wait about five seconds, you should be able to
start up a serial console. Either:

```bash
$ screen /dev/ttyACM0 115200
```
or
```bash
$ minicom -D /dev/ttyACM0
```

(I typically had to try either command several times before it
would work.) The benefit of minicom is it will keep running even if you unplug
the cable and then plug it back in later.

Check your dmesg output or watch your /dev directory to know what device it
shows up as.

Then, follow [these instructions] (https://developer.mbed.org/handbook/Firmware-FRDM-K64F) to update your firmware.

Next, you can try to build ZJS for the platform:
```bash
$ make BOARD=frdm_k64f JS=samples/HelloWorld.js
$ cp outdir/frdm_k64f/zephyr.bin /media/<USERNAME>/MBED/
```

After you copy the new `.bin` file to that directory, the device will reboot,
blink an LED quickly as it writes the image, and then you should see
the device reconnect as a USB storage device to your PC. Then you can press the
Reset button to run the Zephyr image. You should see "Hello, ZJS world!" output
on the serial console in less than a second.

If something doesn't work, you may want to establish that you're able to
upload the K64F [hello world application] (https://developer.mbed.org/platforms/FRDM-K64F/#flash-a-project-binary).

Then, you could try the Zephyr OS `hello_world` sample to narrow down the
problem:
```bash
$ cd deps/zephyr/samples/hello_world/nanokernel
$ make pristine && make BOARD=frdm_k64f
$ cp outdir/frdm_k64f/zephyr.bin /media/<USERNAME>/MBED/
```

Using the same procedure as above, once you hit Reset you should see
"Hello World!" within a second on your serial console.

Zephyr is a trademark of the Linux Foundation. *Other names and brands may be claimed as the property of others.

## Building and running on Linux/Mac OSX
In addition to Zephyr there is a "linux" target which does not use Zephyr at all
and instead uses the host OS. This can be build on Linux or Mac OSX using the
command:

```bash
make BOARD=linux
```

The executable will be outputted to `outdir/linux/<variant>/jslinux`. Where
`<variant>` is either `debug` or `release`. This is specified the same as the
Zephyr target by passing in `VARIANT=` when running `make`. The default is
release.

What makes the linux target convenient is that a JS script does not have to be
bundled with the final executable. By default `samples/HelloWorld.js` will be
bundled but you can always just pass in a script on the command line when running
jslinux e.g.:

```bash
./outdir/linux/release/jslinux samples/Timers.js
```

If a script is passed in on the command line it will take the priority over any
script bundled with the executable (using `JS=`).

By default jslinux will run forever (as Zephyr does) but if this is not desired,
there are two flags which can be used to cause jslinux to exit under certain
conditions. The first is the `--autoexit` flag. If this flag is used, jslinux
will continually check to see if there are any pending events, like timers,
callbacks or service functions. If there have no been any events processed on the
last and most current loop cycle it will exit. The second flag (`-t`) will cause
jslinux to exit after a specified timeout in milliseconds. This flag can be used like:

```bash
./jslinux -t <ms>
```

The `--autoexit` and `-t <ms>` flags can be used together, which will cause
jslinux to exit on whichever condition is met first.

It should be noted that the Linux target has only very partial support to hardware
compared to Zephyr. This target runs the core code, but most modules do not run
on it, specifically the hardware modules (AIO, I2C, GPIO etc.). There are some
modules which can be used though like Events, Promises, Performance and OCF. This
list may grow if other modules are ported to the Linux target.

## Supported modules (Linux vs Zephyr)
There is only partial support for modules on Linux compared to Zephyr. Any hardware
specific module (I2C, UART, GPIO, ADC etc.) is not supported on Linux. Trying
to run a Zephyr specific module on Linux will result in the JavaScript not running
successfully. Below is a complete table of modules and target support.

| Module    | Linux                    | Zephyr                   |
| :---:     | :---:                    | :---:                    |
|  ADC      | <ul><li>- [ ] </li></ul> | <ul><li>- [x] </li></ul> |
|  PWM      | <ul><li>- [ ] </li></ul> | <ul><li>- [x] </li></ul> |
|  GPIO     | <ul><li>- [ ] </li></ul> | <ul><li>- [x] </li></ul> |
|  I2C      | <ul><li>- [ ] </li></ul> | <ul><li>- [x] </li></ul> |
|  BLE      | <ul><li>- [ ] </li></ul> | <ul><li>- [x] </li></ul> |
|  UART     | <ul><li>- [ ] </li></ul> | <ul><li>- [x] </li></ul> |
| Sensor    | <ul><li>- [ ] </li></ul> | <ul><li>- [x] </li></ul> |
| Buffer    | <ul><li>- [x] </li></ul> | <ul><li>- [x] </li></ul> |
| Console   | <ul><li>- [x] </li></ul> | <ul><li>- [x] </li></ul> |
| Event     | <ul><li>- [x] </li></ul> | <ul><li>- [x] </li></ul> |
| OCF       | <ul><li>- [x] </li></ul> | <ul><li>- [x] </li></ul> |
|Performance| <ul><li>- [x] </li></ul> | <ul><li>- [x] </li></ul> |
| Timers    | <ul><li>- [x] </li></ul> | <ul><li>- [x] </li></ul> |

## OCF over BLE
There is a dedicated [document](./docs/ocf-ble.md) for building and running OCF over
BLE on the Arduino 101.