Skip to content

IOT_JVM linker-relocator

IOT_JVM will read the previously compiled object files and gather them in a bytecode executable by Duetware.

Running IOT_JVM

IOT_JVM is a command-line tool. However, it is automatically launched either from IoTize Studio or from Ride7:

  • In Iotize Studio, the launch is done from the main menu (Project | Run Java compiler), or by clicking on the 'gear' icon at the top left of the java code editing window.

  • In Ride-7, all you have to do is build the current project.

On the command line, the general syntax is:

IOT_JVM.exe [options list] filename.class

Unlike a 'C' linker, there is no need to specify all .class files. In the same way as when compiling, IOT_JVM will automatically search for the object files of the missing classes.

Options

The list of options is as follows:

Option Parameter Description
-o bcb filename By default, the primary class name will be used and the destination directory will be that of the main object file suffixed by '.bcb'.
-l map filename By default, the primary class name will be used and the destination directory will be that of the main object file suffixed by '.map'.
-p pathname Path added for the search of imported packages
-v none Verbose output
-z none Compress output (-z, -z0, -z1 or -z2). See remark 2.
-m size (kb) Specify the amount (in kilobytes) of memory allocated for the heap
-c size (kb) Specify the amount (in kilobytes) of memory allocated for the code memory (bcb size)
-s size (words) Specify the number of word (32 bit words) allocated for the stack
-? none Print this message

Remark

  1. -c does not specifies the code size, but the minimum code size. Specifying more than the exact code size allows to execute the JAVA within a fixed buffer in RAM when debugging from RIDE7. A large buffer allows to overwrite the current bcb without replacing the buffer, even when the new code size is higher (but still lower than the specified minimum code size). When the new code is larger, it is mandatory to proceed to a complete reconfiguration.

  2. Starting with version 2.57 (versioning for both for the firmware and for IOT_JVM.exe), the concept of compression levels was added:

    -z0 is equivalent to 'no compression',

    -z1 is equivalent to '-z' (typical gain of 50% over z0),

    -z2 adds an additional compression level (typical gain of 12% over z1).

Operation

Reading object files (.class)

The main file is processed. When an external class is missing, the tool will scan the external directories to find that class. It will then process the found file and then continue until there are no more missing classes.

Linking to native classes/methods

IOT_JVM links the calls to the native functions. It means that it must know all the methods available in the JVM. Therefore, you must be sure that the versions of both IOT_JVM and Duetware are compatible.

Generating the BCB

The final file bcb is then built and optimized: the 'constant pools' are replaced by single tables that contain the list of methods, the list of classes, the list of fields, the list of constants,... All of these lists are optimized so that only the information necessary for execution is retained.

Compressor

Principles

A post-linker optimizer was introduced in 2023. The linker itself concatenates the list of (slightly optimized) .class files, but there are many redundancies between these files (typically the declaration of a method that belongs to another class is present twice: in the owning class and in the calling class). The compressor's job is mainly to factor out all the duplicate declarations and constants:

This compression tool usually shrinks the bcb file by a ratio of 2. Starting with version 2.57, the concept of compression levels was added. '-z2' provides an additional compression level (-z2) by recoding some assembly instructions. Because we are limited (for both the code and the data) to 16 bit addresses, the encoding of 32-bit instructions has been shrinked. Moreover, 16-bit references are also replaced by 8-bit references when possible. This is possible because the result of this link is fully static. In Iotize Studio, these 3 levels are indentified by Low (-z0), Standard (-z1) and High (-z2).

Why compress your code?

In its current version, the compression operates on an existing BCB file. This file therefore has an initial size of less than 64KB, and the process cannot reduce a file larger than 64KB to less than 64KB. It is therefore impossible to go from 100KB to 50KB, but it is easy to go from 50KB to 25KB.

However, reducing code size offers several advantages:

  • On small microcontrollers (for example, the STM32WL), the Java code size is limited to 16KB. Compression therefore allows us to start with a file size of around 32KB and end up within the 16KB limit.

  • In most implementations, Java byte code is executed from RAM where it is copied. Since RAM is a resource shared with resource-intensive functions (Wi-Fi, TLS, MQTT, etc.), it's always wise to minimize the space occupied by Java. However, this is minimal when a large amount of internal PSRAM is available.

Errors

Output by IOT_JVM

The most common error in IOT_JVM occurs when a standard method (or class) that is not supported by the JVM is used. There are many methods that have limited use in an embedded environment, and that should not be used (or reimplemented in Java).

Exception at Run-time(JVM)

See the 'Exception section'.

Exceptions that occur at runtime are reported with a code address and stack position. The code address is used to locate (in the list generated for IOT_JVM) the offending statement that threw the unprocessed exception. The cause of this error can then be understood by also using the error code issued.

Back to top