Architectures MCU / Compiler
Principle
The MicroEJ C libraries have been built for a specific processor (a specific MCU architecture) with a specific C compiler. The third-party linker must make sure to link C libraries compatible with the MicroEJ C libraries. This chapter details the compiler version, flags and options used to build MicroEJ C libraries for each processor.
Some processors include an optional floating point unit (FPU). This FPU
is single precision (32 bits) and is compliant with IEEE 754 standard.
It can be disabled when not in use, thus reducing power consumption.
There are two steps to use the FPU in an application. The first step is
to tell the compiler and the linker that the microcontroller has an FPU
available so that they will produce compatible binary code. The second
step is to enable the FPU during execution. This is done by writing to
CPAR in the SystemInit()
function. Even if there is an FPU in the
processor, the linker may still need to use runtime library functions to
deal with advanced operations. A program may also define calculation
functions with floating numbers, either as parameters or return values.
There are several Application Binary Interfaces (ABI) to handle floating
point calculations. Hence, most compilers provide options to select one
of these ABIs. This will affect how parameters are passed between caller
functions and callee functions, and whether the FPU is used or not.
There are three ABIs:
Soft ABI without FPU hardware. Values are passed via integer registers.
Soft ABI with FPU hardware. The FPU is accessed directly for simple operations, but when a function is called, the integer registers are used.
Hard ABI. The FPU is accessed directly for simple operations, and FPU-specific registers are used when a function is called, for both parameters and the return value.
It is important to note that code compiled with a particular ABI might not be compatible with code compiled with another ABI. MicroEJ modules, including the MicroEJ Core Engine, use the hard ABI.
Supported MicroEJ Core Engine Capabilities by Architecture Matrix
The following table lists the supported MicroEJ Core Engine capabilities by MicroEJ Architectures.
MicroEJ Core Engine Architectures |
Capabilities |
|||
MCU |
Compiler |
Mono- Sandbox |
Tiny- Sandbox |
Multi- Sandbox |
ARM Cortex-M0 |
GCC |
YES |
YES |
NO |
ARM Cortex-M4 |
IAR Embedded Workbench for ARM |
YES |
YES |
YES |
ARM Cortex-M4 |
GCC |
YES |
NO |
YES |
ARM Cortex-M4 |
Keil uVision |
YES |
NO |
YES |
ARM Cortex-M7 |
IAR Embedded Workbench for ARM |
YES |
NO |
YES |
ARM Cortex-M7 |
GCC |
YES |
NO |
YES |
ARM Cortex-M7 |
Keil uVision |
YES |
NO |
YES |
ARMv7A |
GCC |
YES |
YES |
YES |
ARMv7VE |
GCC |
YES |
YES |
YES |
ESP32 |
ESP-IDF |
YES |
NO |
YES |
ARM Cortex-M0
Compiler |
Version |
Flags and Options |
Module |
---|---|---|---|
GCC |
4.8 |
|
ARM Cortex-M4
Compiler |
Build Version |
Known Compatible Versions |
Flags and Options |
Module |
---|---|---|---|---|
Keil uVision |
5.18.0.0 |
5.x |
|
|
GCC |
4.8 |
4.x, 5.x, 6.x, 7.x, 8.x, 9.x |
|
|
IAR Embedded Workbench for ARM |
8.32.1.18631 |
8.x, 9.x |
|
Note
Cortex-M4 architectures are compiled using
hardfp
convention call.Cortex-M4 architectures are compatible with Cortex-M33 core with DSP extension.
ARM Cortex-M7
Compiler |
Build Version |
Known Compatible Versions |
Flags and Options |
Module |
---|---|---|---|---|
Keil uVision |
5.18.0.0 |
5.x |
|
|
GCC |
4.8 |
4.x, 5.x, 6.x, 7.x, 8.x, 9.x |
|
|
IAR Embedded Workbench for ARM |
8.32.1.18631 |
8.x, 9.x |
|
ARMv7A (ARMv7-A without integer division extension: Cortex-A5/Cortex-A8/Cortex-A9)
Compiler |
Build Version |
Known Compatible Versions |
Flags and Options |
Module |
---|---|---|---|---|
GCC |
10.3 |
4.x, 5.x, 6.x, 7.x, 8.x, 9.x, 10.x |
|
|
ARMv7VE (ARMv7-A with integer division extension: Cortex-A7/Cortex-A15)
Compiler |
Build Version |
Known Compatible Versions |
Flags and Options |
Module |
---|---|---|---|---|
GCC |
10.3 |
4.x, 5.x, 6.x, 7.x, 8.x, 9.x, 10.x |
|
|
ESP32
Compiler |
Version |
Flags and Options |
Module Name |
Module Version |
---|---|---|---|---|
GCC (ESP-IDF) |
5.2.0 (crosstool-ng-1.22.0-80-g6c4433a) |
|
Any |
|
GCC (ESP-IDF) |
5.2.0 (crosstool-ng-1.22.0-80-g6c4433a) |
|
Up to |
|
GCC (ESP-IDF) |
5.2.0 (crosstool-ng-1.22.0-96-g2852398) |
|
|
|
GCC (ESP-IDF) |
8.2.0 (crosstool-NG esp-2019r2) |
|
|
|
GCC (ESP-IDF) |
5.2.0 (crosstool-ng-1.22.0-97-gc752ad5) |
|
|
|
GCC (ESP-IDF) |
8.4.0 (crosstool-NG esp-2021r1) |
|
|
|
GCC (ESP-IDF) |
8.4.0 (crosstool-NG esp-2021r1) |
|
|
|
GCC (ESP-IDF) |
11.2.0 (crosstool-NG esp-2022r1) |
|
|
IAR Linker Specific Options
This section lists options that must be passed to IAR linker for
correctly linking the MicroEJ object file (microejapp.o
) generated
by the SOAR.
--no_range_reservations
MicroEJ SOAR generates ELF absolute symbols to define some Link-Time Option (0 based values). By default, IAR linker allocates a 1 byte section on the fly, which may cause silent sections placement side effects or a section overlap error when multiple symbols are generated with the same absolute value:
Error[Lp023]: absolute placement (in [0x00000000-0x000000db]) overlaps with absolute symbol […]
The option --no_range_reservations
tells IAR linker to manage an
absolute symbol as described by the ELF specification.
--diag_suppress=Lp029
MicroEJ SOAR generates internal veneers that may be interpreted as illegal code by IAR linker, causing the following error:
Error[Lp029]: instruction validation failure in section "C:\xxx\microejapp.o[.text.__icetea__virtual___1xxx#1126]": nested IT blocks. Code in wrong mode?
The option --diag_suppress=Lp029
tells IAR linker to ignore
instructions validation errors.
GNU LD Specific Options
--start-group --end-group
By default the GNU linker does not search unresolved symbols in previously loaded files and can cause undefined reference errors.
To solve this issue, either change the load order of libraries (put microejapp.o
first) or guard the libraries with the
options --start-group
and --end-group
.
ARM Linker Specific Options
ARM linker (armlink
) is the linker included in ARM Compiler and Keil MDK-ARM development tools.
Fix Unexpected Undefined Symbol
The ARM linker requires to resolve all symbols before detecting some that are not transitively required for linking the Executable. This typically happen when linking ELF object files containing dead code or debug functions that are compiled but not intended to be linked. If such functions refer to unresolved symbols, you may need to define a fake symbol to make the linker happy. You can declare it in your BSP project or directly in your VEE Port as following:
Create a file
link/armlink-weak.lscf
in the dropins directory of your VEE Port configuration project.Edit the file and declare as many symbols as required. See also the MicroEJ Linker chapter for more details on the MicroEJ linker file syntax.
<lscFragment> <defSymbol name="[symbolName]" value="0" rootSymbol="true" weak="true"/> </lscFragment>
The weak symbol(s) will be directly defined in the application object file (microejapp.o
).
Link the SOAR Debug Section
When building an Application, the SOAR generates a dedicated ELF debug section named .debug.soar
in the application object file (microejapp.o
).
This section is used by debug tools such as the Stack Trace Reader or the Heap Dumper.
It is also used by the SOAR itself for building Features on a Kernel.
Unfortunately, the ARM linker does not link this section in the output ELF executable, even with debug mode enabled. If you try to load the raw executable produced by the ARM linker, the tools will fail with a no debug section error. Here is an example with the Stack Trace Reader:
=============== [ MicroEJ Core Engine Trace ] ===============
[INFO] Paste the MicroEJ core engine stack trace here.
1 : PROXY ERROR
[M8] - The file XXX is not a valid image file or has no debug informations (can't read file: XXX (no debug section)).
To be able to use debug tools, the debug section must be manually linked and injected in the Executable. This is done using the SOAR debug infos post-linker tool.
This tool takes two file options:
soar.object.file
: the internal object file produced by the SOAR when building the Application. It can be found in the Launch Output Folder atsoar/[application_main_class].o
.output.executable.file
: the Executable file produced by the ARM linker that includes the linked Application.
Once executed, it produces a new Executable file beside the original one with the .microej
extension suffix
=============== [ SOARDebugInfosPostLinker ] ===============
Successfully generated c:\myExecutable.axf.microej.
SUCCESS
This file now contains the linked .debug.soar
section so that it can be used by the debug tools.