9. Platform

The MicroEJ platform for MIMXRT595-EVK has been built against the MicroEJ Architecture for Cortex M33 (version 7.16.0) and the UI extension pack (version 13.3.0). This extension pack provides the library MicroUI-3.0, and this library has been designed:

  • to replace a set of basic shapes renderings using a GPU instead of using software algorithms;
  • to be extended by third-party UI libraries.

The MicroEJ platform for MIMXRT595-EVK provides the MicroVG additional extended UI library to target the GCNanoLiteV GPU.

This library allows:

  • drawing paths with either plain color (opaque and transparent) or gradient.
  • applying matrix transformations dynamically to the rendered paths (translation, scale, rotation).
  • drawing images and texts with vector fonts.
digraph structs {
   rankdir=LR
   node [shape=record];
   struct3 [label="Application |{ {Widget|MWT|MicroUI}|MicroVG}| Platform | {Software Algorithms|Hardware (GPU)}"];
}

9.1. MicroUI Drawings

MicroUI provides several basic shapes rendering (pixel-oriented). MicroEJ platform for MIMXRT595-EVK overrides weak implementation (which performs the drawing in software) to use the GPU. The drawings are using the vg_lite APIs (i.e. vg_lite_blit, vg_lite_draw, …). The following functions are hardware accelerated (under the circumstances):

Shapes

  • UI_DRAWING_fillRectangle
  • UI_DRAWING_fillRoundRectangle
  • UI_DRAWING_fillCircle
  • UI_DRAWING_fillEllipse
  • UI_DRAWING_fillCircleArc
  • UI_DRAWING_fillEllipseArc
  • DW_DRAWING_drawThickFadedPoint (fade == 1)
  • DW_DRAWING_drawThickFadedLine (fade == 1)
  • DW_DRAWING_drawThickFadedCircle (fade == 1)
  • DW_DRAWING_drawThickFadedCircleArc (fade == 1)
  • DW_DRAWING_drawThickFadedEllipse (fade == 1)
  • DW_DRAWING_drawThickLine
  • DW_DRAWING_drawThickCircle
  • DW_DRAWING_drawThickEllipse
  • DW_DRAWING_drawThickCircleArc

Images

  • UI_DRAWING_drawImage (image not transparent)
  • DW_DRAWING_drawFlippedImage (full image and not transparent)
  • DW_DRAWING_drawRotatedImageNearestNeighbor (image not transparent)
  • DW_DRAWING_drawRotatedImageBilinear (image not transparent)
  • DW_DRAWING_drawScaledImageNearestNeighbor (image not transparent)
  • DW_DRAWING_drawScaledImageBilinear (image not transparent)

MicroUI manages several RAW formats. A subset of these RAW formats is supported by the VG Lite blit feature:

MicroUI RAW format Bits per pixel blit compatible format
ARGB8888 32 VG_LITE_RGBA8888
RGB888 24  
RGB565 16 VG_LITE_RGB565
ARGB1555 16 VG_LITE_RGBA5551
ARGB4444 16 VG_LITE_RGBA4444
A1 1  
A2 2  
A4 4 VG_LITE_A4
A8 8 VG_LITE_A8
C1 1  
C2 2  
C4 4  
AC11 2  
AC22 4  
AC44 8  
LARGB8888 8  
LRGB888 8  

9.2. MicroVG Library

The MIMXRT595-EVK provides a native and a simulator implementation of the MicroVG foundation library.

The MicroVG library contains native methods which are implemented on board and simulator(See https://docs.microej.com/en/latest/PlatformDeveloperGuide/vgLowLevel.html):

  • VectorGraphicsNatives API:
  • initialize: Initializes the implementation. This is the first native called by the library.
  • PathNatives API:

    • initializePath: Initializes a vector path.
    • appendPathCommand: Appends a command(Move, Line, Curve, Close) with relative or absolute coordinates.
    • reopenPath: Opens a the closed path.
    • mergePath: Merges two paths with the same commands interpolating all points coordinates with a ratio.
  • MatrixNatives API:

    • identity: Creates an identity matrix.
    • copy: Copies a matrix.
    • setTranslate, translate, postTranslate: Translates a matrix.
    • setScale, scale, postScale: Scales a matrix.
    • setRotate, rotate, postRotate: Rotates a matrix.
    • setConcat, concatenate, postConcat: Concatenates two matrixes.

    The translate, scale, rotate and concatenate operations can be applied before of after the targetted matrix. They can also be applied to initialize a matrix remove the other transformations.

  • GradientNatives API:

    • initializeGradient: Initializes a linear gradient.
  • VectorFontNatives API:

    • loadFont: Loads a font.
    • dispose: Disposes the resources associated to the font.
    • stringWidth: Returns the width of a string.
    • stringHeight: Returns the height of a string.
    • getBaselinePosition: Returns the baline position relatively to the top left corner of the text.
    • getHeight: Returns the height of the text.
    • hasComplexLayouter: Determines if the platform as a complex layouter.
  • PainterNatives API:

    • drawPath: Draws a path with a color.
    • drawGradient: Draws a path with a linear gradient.
    • drawString: Draws a string with a color.
    • drawGradientString: Draws a string with a linear gradient.
    • drawStringOnCircle: Draws a string on a circle with a color.
    • drawGradientStringOnCircle: Draws a string on a circle with a linear gradient.

For more detail about the MicroVG foundation library, see MicroVG Library.

Note

Clipping is managed using the MicroUI GraphicsContext setClip API.

9.2.1. Native Implementation

The PainterNatives API of the MicroVG foundation library is implemented over the vg_lite native library which uses the GCNanoLiteV GPU of the MIMXRT595-EVK.

Note

When a clip is applied to a MicroUI GraphicsContext, it will be internally managed using vg_lite scissor APIs.

The VectorFontNatives methods have been implemented in the low-level LLVG_FONT library. It is in charge of the drawing algorithms: for each string’s character to draw, the corresponding glyph is extracted using the FreeType library. A transformation matrix is computed for each glyph to determine the character size and position on the screen based on the glyph metrics. A renderer module for the FreeType engine, called ft_vglite, has been developed to render glyphs with the VG Lite library. The transformation matrix and color information (alpha, gradient) to apply are set to the renderer.

digraph {
  node [shape = box];
  LL [label="LLVG_FONT"];
  FT [label="FreeType"];
  VG [label="ft_vglite"]
  LL -> FT [label="character", fontsize=8];
  LL -> VG [label="transformations,\ncolors", fontsize=8];
  FT -> LL [label="metrics", fontsize=8];
  FT -> VG [label="render", fontsize=8];
}

Note

The ft_vglite renderer is based on the Smooth rasterizer from the FreeType project. It has been modified to use VG Lite to render glyphs with the GPU.

9.2.2. Simulator Implementation

The MIMXRT595-VEE-IAR83 Virtual Device uses the Desktop rendering vector capabilities to render the MicroUI API for SVG, OpenVG, TrueType.

Note

The virtual device runs over Java2D which support vector graphics via Path2D. The default Java2D rendering quality is used, and the following information is ignored:

  • VGLite path bounding box,
  • VGLite drawing quality.

Warning

The following blending algorithms are not supported.

  • VG_LITE_BLEND_SCREEN,
  • VG_LITE_BLEND_MULTIPLY,
  • VG_LITE_BLEND_ADDITIVE.

The implementation in the simulator relies on Java2D API, which natively supports TrueType fonts and gradient colors. The drawString methods follow the same algorithm as the C native implementation and uses the MicroVG Library implementation in the simulator to manage transformations. Antialiasing is enabled on text rendering for drawString.

9.3. Network

9.3.1. Overview

The MicroEJ Platform provides a WiFi network service. It requires the connection of a Silicon Labs WF200 WiFi Expansion Kit (WF200 board) on the MIMXRT595-EVK board.

Once the WF200 board is connected to the MIMXRT595-EVK board, the MicroEJ application can use it.

The application uses the WiFi network service to connect an NTP server and update the watch date and time.

9.3.2. WF200 Board

The WF200 Expansion Kit board is developed by Silicon Labs.

It is connected to the MIMXRT595-EVK on the Non-Standard Arduino I/F connectors J27, J28, J29, J30 with a Nucleo Interposer board(v1.0 or v2.0). The Nucleo Interposer board can be requested from Silicon Labs with the WF200 board.

The NXP i.MX RT595 communicates with the WF200 devices using an SPI interface. The two switches on the WF200 board must be configured this way:

  • Power source select switch: On-Board LDO.
  • Host interface select switch: SPI.
../_images/WF200_board.png

The following table gives the hardware mapping of the signals interconnecting the i.MX RT595 and the WF200.

WF200 pin WF200 Rasp. Pi Conn. Nucleo Interposer V1.0 Nucleo Interposer V2.0 EVK RT595 RT595
SPI_MOSI 19 J6_14 J6_14 J28_4 PIO5_1
SPI_MISO 21 J6_12 J6_12 J28_5 PIO5_2
SPI_SCLK 23 J6_10 J6_10 J28_6 PIO5_3
SPI_CS 24 J6_16 J6_16 J28_3 PIO5_0
SPI_WIRQ 36 J6_18 J6_18 J28_2 PIO4_29
GPIO_WIRQ 31 J6_20 J6_20 J28_1 PIO4_28
GPIO_WUP 32 J4_4 J4_2 J27_7 PIO4_26
RESETn 33 J4_2 J4_1 J27_8 PIO4_27

The BSP automatically detects if a WF200 board is connected to the MIMXRT595-EVK board. If the WF200 board is not available, the FreeRTOS network tasks are not started, and the application behaves as if there was no network support.

If the MicroEJ Application does not use the network library, the MicroEJ Platform network code is not used (not linked in the binary file) even if a WF200 board is connected.

The WF200 connects a WiFi Access Point using credentials provided by the MicroEJ application.

9.3.3. Application

The MicroEJ Application uses a TimeService to define the date and time. The TimeService can be either a NetTimeService or the standard MicroEJ TimeService.

The NetTimeService requests the date and time to an NTP server. The standard MicroEJ Time Service requests the date and time from the MicroEJ Platform.

The NetTimeService induces a larger RAM size, a larger footprint, and extra MCU execution time. The application has been developed to isolate the NetTimeService in a dedicated module. If this module is not used (not included in the com.microej.demo.watch.vg module.ivy file), the RAM size, FLASH size, MCU execution time are reduced.

The default NTP server is ntp.ubuntu.com:123. Any other NTP server can be used.

The WiFi Access Point credentials are hardcoded in the NetTimeService class. They have to be updated before running the MicroEJ Application.

9.3.4. Implementation

By default, the NetTimeService is disabled in the application. The WiFi Access Point credentials still need to be provided.

Default credentials can be used, but a WiFi Access Point must be created as explained in WiFi Default Access Point.

These steps must be followed to configure the NetTimeService in the application:

  1. Ensure that the com.microej.demo.watch.ntp project is imported into MicroEJ SDK.
  2. Ensure that the com.microej.demo.watch.ntp module dependency is included in the com.microej.demo.watch.vg module.ivy file.
  3. Set the Access Point Credentials in the NetTimeService.java file.
  4. Set the NTP server in the NetTimeService.java file.
  5. Run Demo(Emb) launcher in MicroEJ SDK.
  6. Connect and configure the WF200 as explained in section WF200 Board.
  7. Build, link and deploy as usual.

On application startup, the connection to the WiFi Access point is performed, and if it is successful, an NTP request is made to the NTP server. It will update the date and time of the watchface. The watch hands are automatically moved to the new time position.

9.3.5. WiFi Default Access Point

The default WiFi Access Point SSID is RT595_demo, and this is a WPA2 type Access Point that requires the password MicroEJ_Corp.

This WiFi Access Point can be created using the HotSpot/Network sharing capability of an Android/IOS smartphone.

The following steps will create such Access Point:

  1. Open the Settings app.
  2. Select Wireless & Networks section.
  3. Choose Tethering & Portable Hotspot.
  4. Choose the Set Up WiFi Hotspot item to give the hotspot a name or SSID that must be RT595_demo.
  5. Select WPA2 as the security mode.
  6. Set password to MicroEJ_Corp.
  7. Enable the WiFi Hotspot.

Once this Access Point is enabled, the application should be able to connect it and update the time and date from an NTP server.

9.3.6. Simulator

The simulator manages the MicroEJ Net library.

When the application runs on the simulator with the NetTimeService enabled, the WiFi Configuration mock windows pops up.

../_images/wifi_configuration_mock.png

A new WiFi Access Point can be registered and saved. It will be available after a restart of the simulator.

The WiFi Access Point configuration can also be manually modified from the wifi/wificonfig.properties file.

Warning

The simulator WiFi Configuration mock can not be used over a VPN network.

9.3.7. Disable Network

These steps must be followed to disable the NetTimeService in order to reduce the application footprint:

  1. Comment out the com.microej.demo.watch.ntp module in the com.microej.demo.watch.vg module.ivy file.
  2. (Optional) Resize the core.memory.immortal.size to 256 in build/common.properties file then apply that modification in the launchers.
  3. Empty the Configuration -> Wi-Fi -> Wi-Fi configuration file field of the Demo (Sim) launcher.
  4. Run Demo(Emb) launcher in MicroEJ SDK.
  5. Build, link and deploy as usual.

9.3.8. Limitations

Using the NetTimeService brings some limitations to the watch demo:

  • The boot time is increased as the MCU needs to initialize the WF200 device and the Network BSP stack.
  • The Network BSP stack induces regular activity to monitor the different Network application message boxes. It has some effects on power consumption, even with the FlowerLP watchface.
  • The watchfaces framerate could be slightly reduced during NTP requests.

9.4. Mono-Sandbox Firmware

The platform, the BSP, and the main application are designed to build a MicroEJ Multi-Sandbox Firmware (see Kernel Developer Guide). This chapter describes how to build a Mono-Sandbox Firmware instead of a Multi-Sandbox Firmware.

The main advantage is to reduce the RAM footprint. Indeed the Multi-Sandbox Firmware requires some large buffers (see Limitations). Consequently, the required memory banks must remain active, which prevents reducing the power consumption (see Power Management).

Note

The Mono-Sandbox Firmware format prevents installing additional watchfaces during the main application execution (see Compile Additional Watchface).

9.4.1. Mono-Sandbox Platform

A Mono-Sandbox Firmware can be built against a Multi-Sandbox Platform. However, a Multi-Sandbox Platform requires implementing the low-level API of the Multi-Sandbox module (LLKERNEL_impl.h), which becomes useless in the case of Mono-Sandbox Firmware.

  1. Open properties file /mimxrt595_freertos-configuration/module.properties.
  2. Look for the property com.microej.platformbuilder.module.multi.enabled.
  3. Change its value to false.
  4. Rebuild the platform (see Platform Build).

Note

The Mono-Sandbox Platform stubs the Kernel & Features library. A RuntimeException is thrown when a Kernel & Features API is called. However, this is not critical; the application will keep running.

9.4.2. Mono-Sandbox Application

The wearable application and the watchfaces have been designed to be Multi-Sandbox compatible using Kernel & Features library. This chapter does not describe how to remove the Kernel & Features library dependency: the application can run even if Kernel & Features API’s implementation throws some exceptions at runtime.

Run the main application on the simulator of the new platform (see Build the Demo). An exception is thrown on application startup; however, the application keeps running.

=============== [ Initialization Stage ] ===============
=============== [ Converting fonts ] ===============
=============== [ Converting images ] ===============
=============== [ Launching on Simulator ] ===============
Exception in thread "FeatureFinalizer" java.lang.RuntimeException
   at java.lang.Throwable.fillInStackTrace(Throwable.java:82)
   at java.lang.Throwable.<init>(Throwable.java:32)
   at java.lang.Exception.<init>(Exception.java:14)
   at java.lang.RuntimeException.<init>(RuntimeException.java:14)
   at com.is2t.kf.KernelNatives.getNextStoppedFeatureToUpdate(KernelNatives.java:167)
   at com.is2t.kf.FeatureFinalizer.run(FeatureFinalizer.java:38)
   at java.lang.Thread.runWrapper(Thread.java:387)
Waiting for an application to be available
[WF Registry] Adding SportWatchface
[WF Registry] Adding FlowerWatchface
[WF Registry] Adding FlowerLPWatchface
[WF Registry] Starting SportWatchface

To prepare the compatibility with the Mono-Sandbox BSP, the main application must be very slightly modified. It consists to not call the automatic features loader/installer service FeatureLoaderService:

  1. Open Java file com.microej.Demo.

  2. Comment the FeatureLoaderService registration in the kernelServiceRegistry. The import block is automatically updated (the imports com.microej.demo.watch.util.services.FeatureLoaderService and com.microej.service.FeatureLoaderServiceImpl are removed) :

    // [...]
    import com.nxp.rt595.util.PowerManagementHelper;
    import com.microej.demo.watch.util.services.ActivityService;
    import com.microej.demo.watch.util.services.HeartRateService;
    // [...]
    import com.microej.service.DefaultTimeService;
    import com.microej.service.HeartRateServiceImpl;
    // [...]
    
    public static void main(String[] args) {
       // [...]
       kernelServiceRegistry.register(PowerService.class, new PowerServiceImpl());
       kernelServiceRegistry.register(StepsService.class, new StepsServiceImpl());
       kernelServiceRegistry.register(ActivityService.class, new ActivityServiceImpl());
       // kernelServiceRegistry.register(FeatureLoaderService.class, new FeatureLoaderServiceImpl());
       // [...]
    }
    
  3. Open Java file com.nxp.rt595.util.PowerManagementHelper.

  4. Comment the lines with startService(FeatureLoaderService.class); and stopService(FeatureLoaderService.class);. The import block is automatically updated (the import com.microej.demo.watch.util.services.FeatureLoaderService is removed) :

// [...]
import com.microej.demo.watch.util.KernelServiceRegistry;
import com.microej.demo.watch.util.services.ActivityService;
import com.microej.demo.watch.util.services.HeartRateService;
import com.microej.demo.watch.util.services.NotificationService;
// [...]

private static void applyPerfProfile(int profile) {

   // Start/Stop services depending of profile
   switch (profile) {
   case PERF_PROFILE_MAX_PERFS:

      startService(StepsService.class);
      startService(HeartRateService.class);
      startService(PowerService.class);
      startService(NotificationService.class);
      startService(ActivityService.class);
      //startService(FeatureLoaderService.class);
      break;

   case PERF_PROFILE_POWER_SAVING:

      stopService(StepsService.class);
      stopService(HeartRateService.class);
      stopService(PowerService.class);
      stopService(NotificationService.class);
      stopService(ActivityService.class);
      //stopService(FeatureLoaderService.class);
      break;

   default:
      throw new IllegalArgumentException();
   }

   // [...]
}
  1. Build the application as usual.

If these steps are not performed, some errors will occur during the IAR linker step:

Error[Li005]: no definition for "Java_com_microej_kernel_FeatureInputStream_isFeatureAvailable" [referenced from [...]\mimxrt595_freertos-bsp\
projects\microej\platform\lib\microejapp.o]
Error[Li005]: no definition for "Java_com_microej_kernel_FeatureInputStream_init" [referenced from [...]\mimxrt595_freertos-bsp\projects\microej\
platform\lib\microejapp.o]
Error[Li005]: no definition for "Java_com_microej_kernel_FeatureInputStream_readIntoArray" [referenced from [...]\mimxrt595_freertos-bsp\
projects\microej\platform\lib\microejapp.o]
Error[Li005]: no definition for "Java_com_microej_kernel_FeatureInputStream_closeFeature" [referenced from [...]\mimxrt595_freertos-bsp\
projects\microej\platform\lib\microejapp.o]
Error while running Linker

9.4.3. Mono-Sandbox BSP

As described in BSP Architecture, the kf group in the IAR project implements the low-level APIs of Multi-Sandbox Firmware and the automatic features loader/installer FeatureInputStream.

As we can not install additional features, thjis low-level API are useless.

First, disable these uneeded low-level API implementations:

  1. Open IAR project.
  2. Right-click on group source / kf.
  3. Open the Options... window.
  4. Check Exclude from build.
  5. Click on OK.

Multi-Sandbox Firmware’s large buffers are no longer needed. IAR does not allocate these buffers during the linker step because they are not referenced in the BSP. However, the inuse ram partitions are still powered on by default . The lowpower/src/power_manager.c must be updated to improve the low-power consumption.

Some calls to the feature loader bsp API must also be commented out.

  1. Open source file /mimxrt595_freertos-bsp/projects/microej/lowpower/src/power_manager.c.
  2. Comment out all calls to set_ram_partitions_power() with &m_fo_start, &m_fo_end or &m_kf_start, &m_kf_end arguments.
  3. Comment out calls to USART_Feature_Loader_Enable(); and USART_Feature_Loader_Disable();.
  4. Save the power_manager.c file.

Finally, build the BSP as usual and deploy the application on board. The same exception than the simulator is thrown; the application ignores it and keeps running.