Multi-Sandbox Firmware Creation

This chapter requires a minimum understanding of MicroEJ Module Manager and Module Natures.

Create a new Firmware Project

First create a new module project using the build-firmware-multiapp skeleton.

A new project is generated into the workspace:

../_images/firmware-multiapp-skeleton-project.png

Configure a Platform

Before building the firmware, a target platform must be configured. The easiest way to do it is to copy a platform file into the myfirmware > dropins folder. Such file usually ends with .jpf. For other ways to setup the input platform to build a firmware see Platform Selection.

Build the Firmware and Virtual Device

In the Package Explorer, right-click on the project and select Build Module. The build of the Firmware and Virtual Device may take several minutes. When the build is succeed, the folder myfirmware > target~ > artifacts contains the firmware output artifacts (see Firmware Input and Output Artifacts) :

  • mymodule.out: The Firmware Binary to be programmed on device.
  • mymodule.kpk: The Firmware Package to be imported in a MicroEJ Forge instance.
  • mymodule.vde: The Virtual Device to be imported in MicroEJ Studio.
  • mymodule-workingEnv.zip: This file contains all files produced by the build phasis (intermediate, debug and report files).
../_images/firmware-multiapp-skeleton-artifacts.png

Define a Runtime Environment

A Multi-Sandbox Firmware must define a runtime environment which is the set of classes, methods and fields all applications are allowed to use. In most of the cases the runtime environment is an aggregation of several Kernel APIs.

Note

According to the Kernel and Features specification, no API is open by default to Sandboxed Applications.

Specify Kernel APIs

A Kernel API module is added as a dependency with the configuration kernelapi->default.

<dependency org="com.microej.kernelapi" name="edc" rev="1.0.6" conf="kernelapi->default"/>

The build options runtime.api.name and runtime.api.version must be set unless declaring a dependency to a Runtime API module.

Create a Runtime API Module

A Runtime API module is a module that aggregates a set of Kernel APIs modules.

It is be built with module project build-runtime-api skeleton.

<info organisation="myorg" module="mymodule" status="integration" revision="1.0.0">
   <ea:build organisation="com.is2t.easyant.buildtypes" module="build-runtime-api" revision="2.+">
   <ea:property name="runtime.api.name" value="RUNTIME"/>
   <ea:property name="runtime.api.version" value="1.0"/>
   </ea:build>
</info>

The build option runtime.api.name defines the name of the runtime environment (required). The build option runtime.api.version defines its version. If not set, it takes the declared module version.

For example, the following dependencies declare a runtime environment that aggregates all classes, methods and fields defined by edc,kf,bon,wadapps,components Kernel APIs modules.

<dependencies>
   <dependency org="com.microej.kernelapi" name="edc" rev="1.0.4"/>
   <dependency org="com.microej.kernelapi" name="kf" rev="2.0.1"/>
   <dependency org="com.microej.kernelapi" name="bon" rev="1.0.4"/>
   <dependency org="com.microej.kernelapi" name="wadapps" rev="1.2.2"/>
   <dependency org="com.microej.kernelapi" name="components" rev="1.2.2"/>
</dependencies>

Add System Applications

A MicroEJ Sandboxed Application can be dynamically installed using Kernel.install() or can be directly linked into the Firmware binary at built-time. In this case, it is called a System Application.

The user can specify the System Applications in two different ways:

  • Set the property build-systemapps.dropins.dir to a folder which contains System Applications (.wpk files).

  • Add a new dependency for each System Application with the configuration systemapp->application:

    <dependency org="com.microej.app.wadapps" name="management" rev="2.2.2" conf="systemapp->application"/>
    

All System Applications are also included to the Virtual Device. If a System Application must only be linked to the Firmware, declare the dependency with the configuration systemapp-fw instead of systemapp:

<dependency org="com.microej.app.wadapps" name="management" rev="2.2.2" conf="systemapp-fw->application"/>

Build Firmware using Meta Build

A Meta build project can be useful to automatically build Sandboxed Applications that will be linked as System Application in the Firmware.

The following figure shows the overall build flow (Sandboxed Application build prior to the Firmware build):

Firmware Build Flow using MicroEJ Module Manager

Firmware Build Flow using MicroEJ Module Manager

Build Firmware using MicroEJ Launches

It is still possible to build the Firmware using MicroEJ Launch rather than the regular module build. This speeds-up the build time thanks to MicroEJ Module Manager workspace resolution and Eclipse incremental compilation.

  • Import the Firmware project and all System Application projects in the same workspace,
  • Prepare a MicroEJ Application for the Kernel as a regular Standalone Application,
  • Prepare a MicroEJ Application launch for each System Application using Build Dynamic Feature settings,
  • Prepare a MicroEJ Tool launch for each System Application using the Firmware Linker settings.

The following figure shows the overall build flow:

Firmware Build Flow using MicroEJ Launches

Firmware Build Flow using MicroEJ Launches

Advanced

MicroEJ Firmware module.ivy

The following section describes module description file (module.ivy) generated by the build-firmware-multiapp skeleton.

Ivy info

<info organisation="org" module="module" status="integration"
revision="1.0.0">
    <ea:build organisation="com.is2t.easyant.buildtypes" module="build-firmware-multiapp" revision="2.+"/>
    <ea:property name="application.main.class" value="org.Main" />
    <ea:property name="runtime.api.name" value="RUNTIME" />
    <ea:property name="runtime.api.version" value="0.1.0" />
</info>

The property application.main.class is set to the fully qualified name of the main java class. The firmware generated from the skeleton defines its own runtime environment by using ivy dependencies on several kernel API instead of relying on a runtime environment module. As consequence, the runtime.api.name and runtime.api.version properties are specified in the firmware project itself.

Ivy Configurations

The build-firmware-multiapp build type requires the following configurations, used to specify the different kind of firmware inputs (see Firmware Input and Output Artifacts) as Ivy dependencies.

<configurations defaultconfmapping="default->default;provided->provided">
    <conf name="default" visibility="public"/>
    <conf name="provided" visibility="public"/>
    <conf name="platform" visibility="public"/>
    <conf name="vdruntime" visibility="public"/>
    <conf name="kernelapi" visibility="private"/>
    <conf name="systemapp" visibility="private"/>
    <conf name="systemapp-fw" visibility="private"/>
</configurations>

The following table lists the different configuration mapping usage where a dependency line is declared:

<dependency org="..." name="..." rev="..." conf="[Configuration Mapping]"/>
Configurations Mapping for build-firmware-multiapp Build Type
Configuration Mapping Dependency Kind Usage
provided->provided Foundation Library (JAR) Expected to be provided by the platform. (e.g. ej.api.* module)
default->default Add-On Library (JAR) Embedded in the firmware only, not in the Virtual Device
vdruntime->default Add-On Library (JAR) Embedded in the Virtual Device only, not in the firmware
default->default; vdruntime->default Add-On Library (JAR) Embedded in both the firmware and the Virtual Device
platform->platformDev Platform (JPF) Platform dependency used to build the firmware and the Virtual Device. There are other ways to select the platform (see Platform Selection)
kernelapi->default Runtime Environment (JAR) See Define a Runtime Environment
systemapp->application Application (WPK) Linked into both the firmware and the Virtual Device as System Application. There are other ways to select System Applications (see Add System Applications)
systemapp-fw->application Application (WPK) Linked into the firmware only as System Application.

Example of minimal firmware dependencies.

The following example firmware contains one System App (management), and defines an API that contains all types, methods, and fields from edc,kf,wadapps,components.

<dependencies>
    <dependency org="ej.api" name="edc" rev="1.2.0" conf="provided" />
    <dependency org="ej.api" name="kf" rev="1.4.0" conf="provided" />
    <dependency org="ej.library.wadapps" name="framework" rev="1.11.0" />
    <dependency org="com.microej.library.wadapps.kernel" name="common-impl" rev="3.0.0" />
    <dependency org="com.microej.library.wadapps" name="admin-kf-default" rev="1.2.0" />
    <!-- Runtime API (set of Kernel API files) -->
    <dependency org="com.microej.kernelapi" name="edc" rev="1.0.0" conf="kernelapi->default"/>
    <dependency org="com.microej.kernelapi" name="kf" rev="2.0.0" conf="kernelapi->default"/>
    <dependency org="com.microej.kernelapi" name="wadapps" rev="1.0.0" conf="kernelapi->default"/>
    <dependency org="com.microej.kernelapi" name="components" rev="1.0.0" conf="kernelapi->default"/>
    <!-- System Applications -->
    <dependency org="com.microej.app.wadapps" name="management" rev="2.2.2" conf="systemapp->application"/>
</dependencies>

Build only a Firmware

Set the property skip.build.virtual.device

<ea:property name="skip.build.virtual.device" value="SET" />

Build only a Virtual Device

Set the property virtual.device.sim.only

<ea:property name="virtual.device.sim.only" value="SET" />

Build only a Virtual Device with a pre-existing Firmware

Copy/Paste the .kpk file into the folder dropins