How to run JavaScripts with JerryScript on mbed

Intro

This is a step-by-step tutorial to demonstrate how to build the mbed OS and JerryScript together into the STM32F4 and STM32F429ZI boards. At the end of this guide you will be able to run javascript code (with power of the JerryScript) on your STM32F4 boards under mbed OS.

If you immerse yourself in JerryScript you can make awesome projects, for example the first Atari game, Pong. We used STM32F4 board, shield and Raspberryi Pi 2 and obviously some led matrices for this project. So you can build an infinite number of projects, tasks… There is endless possibilites…

Pong game on boards Pong game on boards 2

JerryScript is a lightweight JavaScript engine intended to run on a very constrained devices such as microcontrollers:

  • only few kilobytes of RAM available to the engine (<64 KB RAM)
  • constrained ROM space for the code of the engine (<200 KB ROM).

The engine supports on-device compilation, execution and provides access to peripherals from JavaScript. If you want to know more about the JerryScript, check out its official project site.

mbed OS is an operating system which is created for mbed compatible boards. It allows your C++ applications to run on these boards by providing APIs that you can use from your application to control the hardware. The system is designed specifically for constrained devices. So, it works behind the scenes to automatically make the most of the limited hardware and network resources available. This is the first native OS support for Thread connectivity standard (single-threaded and event-driven), first inclusion of BLE. If you want know more about the details, visit this link.

Yotta is a software module system for mbed OS. It is responsible for assembling the software modules that your application needs and controlling the build system to make those modules available to you. We will get into the details of it later, but what you need to understand at this point is that mbed OS applications cannot be built without yotta. Yotta combines your application code with the mbed OS code-base and any other module that which might be needed. To tell yotta what your application needs, you have to add a list of dependencies to each new application. The easiest way to add this is to describe the component mbed-drivers as a dependency of your application. For more detailed information and guides you should check out the official guide of yotta.

Now, you probably see what we are up to. No? Let’s get into the details!

The mbed OS allows you to run your C++ application on your board. The JerryScript is a JavaScript engine implemented in C/C++. It means the JerryScript is able to run on your board under mbed OS. So, you can parse and run any JavaScript code on your board with extended hardware and network resources. There are so many people who do not want to (or do not know how to) implement an application in C++ language, but they already know how to implement an application in JavaScript language. So, there is a solution to run your JavaScript application, script, funny code on your own board with the help of JerryScript and mbed OS.

Dependencies

Yotta (version: 0.13.0)

Yotta is a tool that ARM team building at mbed to help themselves and others build better software for C-family languages by making it easier to share and re-use software modules.Yotta is not only a command line tool but also a culture of building software components that do one thing well, declare a clear interface, and can be re-used. Yotta installing link. There are Linux, Windows and Mac guide too on the yotta website. Let's see the Linux guide to install yotta to a computer. We use Ubuntu for all these tutorials.

GCC

If yotta is available on your machine, then let's check your gcc in terminal with

arm-none-eabi-gcc --version

command. The gcc version of 5.2.1 is the recommend, we have also used this. You need a cross toolchain for it. GCC is always configured to emit binaries for a specific target. So normally the gcc which is already available on Linux has the target "i486-linux-gnu". You can't cross-compile to an ARM target using this compiler.

A toolchain is a set of distinct software development tools that are linked (or chained) together by specific stages such as GCC. Optionally, a toolchain may contain other tools such as a Debugger or a Compiler for a specific programming language, such as ,C++. Quite often, the toolchain used for embedded development is a cross toolchain, or more commonly known as a cross compiler. All the programs (like GCC) run on a host system of a specific architecture (such as x86) but produce binary code (executables) to run on a different architecture (e.g. ARM). This is called cross compilation and is the typical way of building embedded software. It is possible to compile natively, running gcc on your target.

So you need to install another GCC configured for that target, then GCC and the other programs normally have a prefix indicating the target: In your case the prefix is arm-none-eabi, and then you call that GCC using arm-none-eabi-gcc. You can have multiple GCC installations, they do not interact:

sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded
sudo apt-get update
sudo apt-get install gcc-arm-none-eabi

NOTE: To remove installed toolchain, just input "sudo apt-get remove gcc-arm-none-eabi”.

Cross-compiling in general situation (in our case this options will be configured in a makefile):

In your Makefile you have to make sure that the cross-compiler is used. You could use $(CC) in your Makefile, and assign it like this:

TOOLCHAIN = arm-none-eabi-
CC = $(TOOLCHAIN)gcc

Compiler flags for Cortex-M0 are -mcpu=cortex-m0 -mthumb -mfloat-abi=soft which is by convention assigned to CFLAGS

CFLAGS += -mcpu=cortex-m0 -mthumb -mfloat-abi=soft

Then a (simple) rule to compile .c to .o looks like

%.o: %.c
    $(CC) $(CFLAGS) -o $@ -c $<

If you do not have ARM GCC compiler installed and you don’t have APT package handling utility, please check out this site to download GCC 5.2.1 which was tested for building JerryScript for stm boards.

GIT

Git allows groups of people to work on the same documents (often code) at the same time, and without stepping on each other's toes. It's a distributed version control system. So you will need to have git, you can install that with

sudo apt-get install git

command. There is some easy tutorial to learn about how to use it

Folders

In this tutorial we will use the following folder abbreviations.

  • ($JERRY) = The JerryScript root folder
  • ($JERRY_TARGETS) = The JerryScript/targets/ folder
  • ($TARGET) = The mbedstm32f4/ or mbedstm32f429i/ folder. Depends on your target board.
  • ($YOTTA_TARGET) = The stm32f4-disco-gcc or stm32f429zi-disco-gcc target names. Depends on your target board.

Boards

As we mentioned earlier in this tutorial we will use a STM32F4 board. To fully support the board you have to install software packages and learn a little bit about its usage.

ST-LINK

For the boards to flash files and binaries we use ST-LINK v2. It is a linux command line program. Here is a step-by-step guide how to download and use it for our microcontrollers: First of all, you need to install dependencies. In terminal, type

sudo apt-get install libusb-1.0-0-dev git

Now you need to create a directory where you install the ST-LINK. We have one more dependency, the pkg-config but it's already installed in most of GNU/Linux systems.

Download and build the project/sources by the following steps:

git clone https://github.com/texane/stlink stlink
cd stling.git
./autogen.sh
./configure
make

And we are ready, now if you connected the board for your computer, use the st-flash binary to flashing data to the board. This is not a necessary step, unless you don’t want to test the st-link.

st-flash write 0x08000000 file.bin

You can download the file.bin test from here (this is a zipped file).

The 0x0800000 is a memory code address, need to put here the first instruction of the program because the processor of the board start running here, but if you working with other board it might be different. For your information: when you use st-flash command you should be in the folder where the st-flash binary exists or use absolute or relative path. This command will result the binaries flashing to the boards. After flashing process it is recommended to restart the device.

Here is a trick that makes your life easier, put this command below to your .bashrc and you can use the ‘st-flash’ command everywhere in terminal.

export PATH="~/work/stlinkv2/stlink:$PATH"

Sometimes the tool drop the WARN src/stlink-common.c: unknown chip id!, you can solve this problem with this 3 simple steps:

  1. short the BOOT0 pin with VDD

  2. push the reset button on the board

  3. enter st-flash erase in terminal where you has the ST-LINK v2 files.

Here is some picture of that:

gpio_vdd gpio_vdd2

Minicom

Later if you want to benchmark your program, you have so many option. We used ‘minicom’. Minicom is a text-based serial communication program. It is used to talk to external devices such as mobile phones, microcontrollers. Install the program with

sudo apt-get install minicom

JerryScript (commit: 73a5fd7)

Repository download & make

Let's start with the JerryScript repository. Now, you have to clone the JerryScript into your local repository:

git clone https://github.com/Samsung/jerryscript.git

After you cloned the source from github, build a release for linux, for check everything is ok.

cd *($JERRY)*
make release.linux -j

Building about ~10-20 seconds, if everything finished with no error, let's enter to the targets folder.

cd *($JERRY_TARGETS)*

This folder contains the target board specific codes. There are a few official targets and a tools folder. So, if you need a new target go ahead and turn the page!

Create new targets

We need to create new targets to use other boards, because mbed OS does not support too much board… yet. So, we build JerryScript for the STM32F429ZI and the STM32F4 boards.The first one is easier, because ARM supports this board. The second one is more difficult, because there is no support, but it is not impossible. Let’s start with the easier.

New target for STM32F429ZI

Let's create a new target for STM32F429ZI board. We have a source repository for this board: here. Clone this repository into the current (jr/targets/) folder. The repository contains the source code for the target. Check readme for the details.

git clone https://github.com/knightburton/mbedstm32f429i

Now you have a new target source. Let's see what we’ve got in this repository.

  • js folder: This folder contains the JavaScript files, those files which will be executed by JerryScript. There are two JavaScript files at the moment: main.js and blink.js. In the main.js file there is a function called 'sysloop'. This function is the main entry point of the JavaScript.

  • There is a Makefile.mbedstm32f429i file. This file is necessary for build JerryScript, build yotta target and flash. In this file you can modify some extra switch for compiler (e.g.: compile optimisation). You can modify the JerryScript Heap size in kByte.

  • module.json: yotta configuration file that contains: the build name, the build version, description, author, licence information and dependencies. In the beginning there is just one dependency: mbed-drivers. This one pulls the other dependencies. If you want to know more about the yotta configuration and usage, please visit the yotta documentation site.

  • There is a .yotta.json file. Contains the build target name for yotta.

  • There is a source folder. This folder contains all of the c and c++ files and these headers. Let's look into it:

Let's see in order the source folder:

  • jerry_extapi - contains some macros for JerryScript object, function and number validation and this file contains the “low level” extended APIs. So if you want to reach some mbedOS function in your javascript, you have an opportunity to expand that js API with system calls, for example led blinking.

  • jerry_port - this file contains several helper routines for JerryScript (such as error and log message implementation).

  • jerry_run - contains the bindings for the core JerryScript API. If you want to know more about Jerry API, please visit the JerryScript API documentation site.

  • jerry_targetjs.h - this contains your JavaScript code in hexadecimal.

  • main - obviously this is the main entry point of the mbed OS. This file contains the app_start() function which is the main() function in the OS.

  • makejerry.cmake - The yotta build calls this cmake file. It performs preparation and initialization for the compilation, such as:

  • set application name
  • set compile flags
  • include the jerry-core
  • link the jerryscript

  • native_mbedstm32f429i - this contains the led blinky function implementation in C++. This file contains the “high level” API. These APIs will be used in the jerry_extapi file.

New target for STM32F4

This board is also supported, but more things have to be done with this compared to STM32F429ZI target. Fortunately they are just a few target specific dependency problems. Let’s fix this.

First of all, you have to enter into your targets folder.

cd *($JERRY_TARGETS)*

We have a separate repository for this target. So, you can simply clone our repository into this folder.

git clone https://github.com/knightburton/mbedstm32f4.git

You have to enter the mbedstm32f4 folder:

cd mbedstm32f4

Now, you have to select the yotta target. This board has not been supported yet (as I mentioned before), but there is an early target implementation for this. So, type the following command into the terminal:

yotta target stm32f4-disco-gcc

Now, you have to add the main module to the yotta dependencies for mbed OS. This is the mbed-drivers module. So, just type the following command into the terminal:

yotta install mbed-drivers

This command will install the mbed-drivers module, and some other module for your target, e.g.: uvisor-lib, ualloc, cmisi-core, … if you want to know more about this modules, please visit the official mbed OS GitHub page.

So, now you have an incorrect yotta dependency tree, because two board specific definitions are missing. You have to add the following modules:

  • hal-st-stm32f407vg
  • cmsis-core-stm32f407xg

Add them manually. These modules will define the missing headers. Let’s see the first module, the hal-st-stm32f407vg one. You have to enter the root of the mbed’s hal module.

cd yotta_modules/mbed-hal-st-stm32f4/

Now, you have to open the mbed-hal-st-stm32f4 module json file. Open the module.json file with favorite editor, and you have to add the following lines to the targetDependencies block:

"stm32f407vg": {
    "mbed-hal-st-stm32f407vg": "^0.0.1"
}

It should look like this:

"targetDependencies": {
    "stm32f407vg": {
        "mbed-hal-st-stm32f407vg": "^0.0.1"
    },
    "stm32f401re-no-inherit": {
      "mbed-hal-st-stm32f401re": "~0.1.0"
    },
    "stm32f429zi-no-inherit": {
      "mbed-hal-st-stm32f429zi": "^1.0.0"
    },
    "stm32f439zi-no-inherit": {
      "mbed-hal-st-stm32f429zi": "^1.0.0"
    }
  }

Let’s see the second module. Go to the cmsis-core folder:

cd ($TARGET)/yotta_modules/cmsis-core-stm32f4

There is a module.json file again, which is describe some information for this module (like before). You have to open an editor this file. After you opened this, you have to add the following lines into the targetDependencies block:

"stm32f407xg": {
    "cmsis-core-stm32f407xg": "^0.0.1"
}

it should look like:

"targetDependencies": {
    "stm32f407xg": {
      "cmsis-core-stm32f407xg": "^0.0.1"
    },
    "stm32f401xe-no-inherit": {
      "cmsis-core-stm32f401xe": "~0.1.0"
    },
    "stm32f429xi-no-inherit": {
      "cmsis-core-stm32f429xi": "^1.0.0"
    },
    "stm32f439zi-no-inherit": {
      "cmsis-core-stm32f439zi": "~0.1.0"
    }
  }

After you finished, go back to the target root folder, and execute the update:

yotta update

Note: if you run into a module version error after modified the modules tree, you have to check the mbed-hal-st-stm32f407vg module.json file’s dependencies block. The correct uvisor-lib version is “>=1.0.2”. It should look like this:

"dependencies": {
    "cmsis-core": "^1.0.0",
    "uvisor-lib": ">=1.0.2"
 }

Now dependencies are fixed. If you want to compare STM32F4 and STM32F429ZI dependency tree, just go back to the ($TARGET) folder, and run the yotta ls command.

jerry 0.0.0
┗━ mbed-drivers 1.1.0
  ┣━ mbed-hal 1.2.2 yotta_modules/mbed-hal
  ┃ ┗━ mbed-hal-st 1.0.0 yotta_modules/mbed-hal-st
  ┃   ┗━ mbed-hal-st-stm32f4 1.2.0 yotta_modules/mbed-hal-st-stm32f4
  ┃     ┣━ uvisor-lib 1.0.13 yotta_modules/uvisor-lib
  ┃     ┣━ mbed-hal-st-stm32cubef4 1.0.2 yotta_modules/mbed-hal-st-stm32cubef4
  ┃     ┗━ mbed-hal-st-stm32f407vg 0.0.1 yotta_modules/mbed-hal-st-stm32f407vg
  ┣━ cmsis-core 1.1.2 yotta_modules/cmsis-core
  ┃ ┗━ cmsis-core-st 1.0.0 yotta_modules/cmsis-core-st
  ┃   ┗━ cmsis-core-stm32f4 1.1.0 yotta_modules/cmsis-core-stm32f4
  ┃     ┗━ cmsis-core-stm32f407xg 0.0.1 yotta_modules/cmsis-core-stm32f407xg
  ┣━ ualloc 1.0.3 yotta_modules/ualloc
  ┃ ┗━ dlmalloc 1.0.0 yotta_modules/dlmalloc
  ┣━ minar 1.0.4 yotta_modules/minar
  ┃ ┗━ minar-platform 1.0.0 yotta_modules/minar-platform
  ┃   ┗━ minar-platform-mbed 1.1.2 yotta_modules/minar-platform-mbed
  ┣━ core-util 1.5.2 yotta_modules/core-util
  ┗━ compiler-polyfill 1.2.1 yotta_modules/compiler-polyfill

JerryScript & mbed build

Here is the tutorial to build JerryScript, end of the tutorial we make a little program which blinking the board’s leds. So, keep going on the tutorial. :) If the yotta, gcc and st-link are working fine, let's see how to build JerryScript for the board. There is a Makefile.mbedstm32f429i file in the cloned target source. You have to go back to the JerryScript root folder.

cd *($JERRY)*

First, clean the build:

make -f targets/($TARGET)/Makefile.($TARGET) clean

Then, you have to run the makefile with the jerry rule.

The jerry rule * creates the build folder in the targets/mbedstm32f429i/ * builds the JerryScript to the build folder, JerryScript/build*** * copy the **jerry libraries into the targets/mbedstm32f429i/libjerry/

make -f targets/($TARGET)/Makefile.($TARGET) jerry

Let’s create the mbed binary.

To achieve this you have to convert the JavaScript application (the main.js and the blink.js in the ($TARGET)/js/) to C language. This is gonna be easy, because there is a python script in the ($JERRY_TARGETS)/tools folder for this. This python script create a C header file which is contains your JavaScript code (without comment and whitespace) as String. You can use this script with the following command:

make -f targets/($TARGET)/Makefile.($TARGET) js2c

The C file will be generated at ($TARGET)/source folder as jerry_targetjs.h. Then you have to build yotta.

make -f targets/($TARGET)/Makefile.($TARGET) yotta

Or, you can do this manually: You have to enter the ($TARGET) folder.

cd *($TARGET)*

Then you have to select the correct target for the yotta. Target descriptions allow yotta to compile the same code for different target platforms (different desktop operating systems, or different embedded devices). Each target description contains information both about how to run the compiler to compile (or cross-compile), and configuration information describing the hardware or environment that the target represents.

yotta target *<your-target-name>*

You are able to add some optional module to yotta. It is very easy, just type this into the terminal:

yotta install *<module-name>*

Help: The yotta modules list is available here. You can find a module by name, description or keywords.

Then, you have to build the yotta manually with this command:

yotta build

Note:The executable file is generated to ($JERRY_TARGETS)/($TARGET)/build/($YOTTA_TARGET)/source/jerry.bin.

JerryScript flashing to the board

If you want to test the application, you have to flash the binary to the board. If you configured the ST-LINK correctly, just type the following command into the terminal:

st-flash write ($JERRY_TARGETS)/($TARGET)/build/($YOTTA_TARGET)/source/jerry.bin 0x08000000

Or, if you do not want to do this, just pick the shorter way:

make -f targets/($TARGET)/Makefile.($TARGET) flash

At this point, you have to wait until the led near the USB port stop blinking. When it is done reset the board and LED1 will blink in every seconds.

How to blink program works

All .js files in js folder are executed, with main.js in first order. The sysloop() function in main.js is called periodically in every 100msec via the jerry_loop() and the js_loop() functions from JerryScript engine.

minar::Scheduler::postCallback(jerry_loop).period(minar::milliseconds(100))

The sysloop() then calls blink() in blink.js which blinks the LED in every second.

Benchmark tests

Let’s see in action the JerryScript and mBedOS together. Performance, code size and memory benchmark tests.

Performance

If you are up to do some benchmarking, you have so many options, we used ‘minicom’ for this (what you already have installed if you read the ##Minicom article). We use an USB-TTL for the communication, so if you want to reproduce our process, you need to have a similar device. For STM32F4 board we connected the pin PA3 to TXD and the PA2 to RXD with breadboard jumper wire.

In the JerryScript folder ($TARGET)/yotta_target/stm32f4-disco-gcc/target.json file has the information for this. After you have connected your board to the pc enter dmesg | grep STM to the terminal, you can check the usb devices, and there is showed up the STM32 STLink. You need to modify your main.cpp in ($TARGET)/source/main.cpp to print the lines. Add the highlighted lines to main.cpp:

#include "mbed-drivers/mbed.h"
#include "jerry-core/jerry.h"
#include "jerry_run.h"
#include "jerry_targetjs.h"

**Serial pc(USBTX, USBRX); //tx, rx**

static int jerry_init(void) {
  int retcode;
  int src;

  DECLARE_JS_CODES;

  /* run main.js */
 **pc.printf("Run main.js...\r\n");**
  retcode = js_entry(js_codes[0].source, js_codes[0].length);
  if (retcode != 0) {
    printf("js_entry failed code(%d) [%s]\r\n", retcode, js_codes[0].name);
    js_exit();
    return -1;
  }
  /* run rest of the js files */
  **pc.printf("Run rest of the .js files...\r\n");**
  for (src=1; js_codes[src].source; src++) {
    retcode = js_eval(js_codes[src].source, js_codes[src].length);
    if (retcode != 0) {
      printf("js_eval failed code(%d) [%s]\r\n", retcode, js_codes[src].name);
      js_exit();
      return -2;
    }
  } // end
  return 0;
 }

static void jerry_loop(void) {
  static uint32_t _jcount = 0;
  js_loop(_jcount++);
}

void app_start(int, char**){
  int i;
    if (jerry_init() == 0) {
      for(i=0; i<=10; i++){
        jerry_loop();
        js_exit();
        **pc.printf("READY.. \r\n");**
      }
  }
}

The result of these changes is to measure the time between the “Run rest of the .js files…” and “READY...“. Build the program with yotta and flash to the board with st-link. Now, turn on the minicom. Type ‘sudo minicom -s’ to the terminal. Configure serial port as follows:

    +-----------------------------------------------------------------------+
    | A -    Serial Device      : /dev/ttyUSB0                              |
    | B - Lockfile Location     : /tmp/                                     |
    | C -   Callin Program      :                                           |
    | D -  Callout Program      :                                           |
    | E -    Bps/Par/Bits       : 9600 8N1                                  |
    | F - Hardware Flow Control : No                                        |
    | G - Software Flow Control : No                                        |
    +-----------------------------------------------------------------------+

You can leave other options as they are and quit from the options. So, you can do the following in minicom:

  • push N key (‘Timestamp Toggle’) - To enable performance measuring we want to know when our application prints debug information on the screen. how fast is our program select.
  • push N - Repeat it for once more, to change the granularity of the measurement to millisecond.
  • push U - For the good readability enable this. In the function menu the you can find it under the ‘Add Carriage Ret’ option.
  • restar the board - Restart the hardware with the reset button. Now, you can see the timestamps which can be used to measure intervals.

So, you can use the timestamps to calculate the running time difference between the first pc.printf() timestamp and second pc.printf() timestamp.

Size

To get the size of the binary files use a simple ‘size jerry’ command in terminal. The ‘jerry’ file next to the generated binary file in ($TARGET)/build/($YOTTA_TARGET)/source/. You will get the size statistic. e.g.:

   text    data     bss     dec     hex filename
 254136     408  203960  458504   6ff08 jerry

Memory

There are two options to measure and track the memory in our project. The first one is trace the mbed OS memory allocation, reallocation and free command results, and the second one is the JerryScript memory statistics. So, let’s see them in order:

mbed OS memory trace

It is possible to turn on mbed OS builtin memory trace module. The ualloc module can be used for this, but you have to do some additional changes to enable. Let’s see how we did!

Navigate to the yotta_targets folder. It assume the current folder is the JerryScript root folder.

cd ($TARGET)/yotta_targets/($YOTTA_TARGET)

Edit target.json:

gedit target.json

You have to add the following lines into the config block. These lines will be turn on the memory trace in the ualloc module. This is a temporary solution, the ARM team really want to find a better way for this.

"debug": {
   "options": {
      "memory-trace": true
  }
},

If you want to flash your program into the board, just follow the next few steps.

cd ($JERRY)
make -f targets/($TARGET)/Makefile.($TARGET) yotta
make -f targets/($TARGET)/Makefile.($TARGET) flash

When you alloc, realloc or free a memory space, you will get a simple log message, or a simple error message if something is not okay. e.g.:

UAL:L ua c:0x803b1b1 s:4 m:0x2001ab78
UAL:L ua c:0x803b1b1 s:48 m:0x2001b140
UAL:L ua c:0x8039ed5 s:212 m:0x2002ff2c
UAL:L ua c:0x803b1b1 s:20 m:0x2001b178
UAL:L ua c:0x803a06d s:3420 m:0x2002f1d0
UAL:L ua c:0x803b1b5 s:16 m:0x2002c290
UAL:L uf c:0x800bd67 m:0x2002c290

Note: If you do not receive the trace message when you running your program on the board, you have to check the ualloc module, it might be outdated or modified. Please check the ARM team ualloc module repository, and check the current state of this module.

If your module is outdated, you have to update it! Just go to the ($TARGET) folder, and run the following command:

yotta update

Or you can still change the source code of ualloc module manually :).

JerryScript mem-stat

Okay, now let’s see how you can enable the memory statistic in JerryScript. This is a little bit longer than the mbed OS memory trace solution.

First of all, navigate to the target folder. It assumes the current folder is the JerryScript root folder.

cd ($TARGET)

Edit Makefile.($TARGET):

vi Makefile.$(TARGET)

You have to add the following option to the EXT_CFLAGS macro:

-DMEM_STAT

It should look like:

EXT_CFLAGS := -D__TARGET_MBED_STM32F4
EXT_CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4
EXT_CFLAGS += -Wno-error=format=
EXT_CFLAGS += -DMEM_STAT

You have to modify the jerry block too. You will find the jerry block around the 30th line. There is a make command with two arguments and ends with .external suffix. Change the .external suffix to the external-mem_stats.

It should look like:

make -C $(INTERM) $(TYPE).external-mem_stats

Then after the make command, there are three cp commands. You have to modify all of them. These cp command will copy the jerry core libs into our targets libjerry folder. In the first cp command, you have to change the external keyword to the external-mem_stats.

cp `cat $(INTERM)/$(TYPE).external-mem_stats/list` $(OUTPUT)/.

In the second and the third cp command, you have to do almost the same. Add the -mem_stats keyword after the lib$(TYPE).

cp $(OUTPUT)/lib$(TYPE)-mem_stats.jerry-core.a $(COPYTARGET)/libjerrycore.a
cp $(OUTPUT)/lib$(TYPE)-mem_stats.jerry-fdlibm.third_party.lib.a $(COPYTARGET)/libfdlibm.a

When you finish, it should look like:

make -C $(INTERM) $(TYPE).external-mem_stats
cp `cat $(INTERM)/$(TYPE).external-mem_stats/list` $(OUTPUT)/.
cp $(OUTPUT)/lib$(TYPE)-mem_stats.jerry-core.a $(COPYTARGET)/libjerrycore.a
cp $(OUTPUT)/lib$(TYPE)-mem_stats.jerry-fdlibm.third_party.lib.a $(COPYTARGET)/libfdlibm.a

We have done with that! Now, we have to change something in the source files. This is the ($TARGET)/source folder.

cd ($TARGET)/source

Next, open the jerry_run.cpp file with an editor and modify the jerry_init flags in the jerry_init function. So, ...

vi jerry_run.cpp

There is a jerry_flag_t flags = JERRY_FLAG_EMPTY; command. Modify the JERRY_FLAG_EMPTY value to the JERRY_FLAG_MEM_STATS value.

jerry_flag_t flags = JERRY_FLAG_MEM_STATS;

Save and close the jerry_run.cpp file and open the main.cpp with an editor. In this file, you have to add the js_exit() call after the jerry_loop() call, because of the memory statistic does not show up by default. The memory statistic will run after the js engine stop working. We did the followings in the main.cpp:

void app_start(int, char**) {
  pc.printf ("\r\nJerryScript in mbed STM32F429ZI\r\n");
  if (jerry_init() == 0) {
    jerry_loop();
    js_exit();
  }
}

Now, you have to go back to the JerryScript root folder and build jerry again!

cd ($JERRY)
make -f targets/($TARGET)/Makefile.($TARGET) jerry

If the Jerry build finished with no error, run js2c to convert your javascript code into c code, build yotta and flash the binary to your board!

make -f targets/($TARGET)/Makefile.($TARGET) js2c yotta
make -f targets/($TARGET)/Makefile.($TARGET) flash

So, when the js is finished with no error on your board, you will get a memory statistic report in the terminal! e.g.:

Heap stats:
  Heap size = 63488 bytes
  Chunk size = 64 bytes
  Allocated chunks count = 0
  Allocated = 0 bytes
  Waste = 0 bytes
  Peak allocated chunks count = 759
  Peak allocated = 47988 bytes
  Peak waste = 660 bytes

Pools stats:
  Chunk size: 8
  Pools: 0
  Allocated chunks: 0
  Free chunks: 0
  Peak pools: 719
  Peak allocated chunks: 5752

NOTE: If the JerryScript memory statistic does not print any value, you have to go to the definition of the mem-stat printf (you will find this in JerryScript/jerry-core/mem/mem-allocator.cpp and JerryScript/jerry-core/mem/mem-heap.cpp) and you have to modify the printf format, because of the default print format is %zu (maybe this format is not good for you).

Epilogue

We hope you like this guide! At first it may seem tough, but if you do every steps we mentioned it shouldn't be so hard to get involved in JerryScript and mbed OS.

If you have any question or comment, just leave a comment below!

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • No HTML tags allowed
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Fill in the blank