Skip to content

MicroEJ/AbstractionLayer-KERNEL-FLASH

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ARCH

Abstraction Layer Kernel Flash

Overview

MicroEJ Kernel Low Level API implementation to install features into Flash memory.

This module implements the generic logic of LLKERNEL_impl Low Level API to allocate features into Flash memory. However, the functions called to use the Flash operations are specific to the target and must be implemented by the user. See Usage section for more information.

See also the MicroEJ documentation for a description of the LLKERNEL functions.

This implementation has a default configuration file, LLKERNEL_flash_configuration.h. If you want to update a configuration, please edit or create the file veeport_configuration.h. See Usage section for more information.

Note

This implementation does not perform any sort of wear leveling. The user should take into account the number of write/erase cycles supported by the flash memory before deciding whether this allocator is suitable for his use case.

Implementation Details

ROM Allocation

The KF ROM region is a dedicated area in flash that holds the installed Feature code and read-only data. Its location and size are defined in the BSP memory map, typically in the linker script.

LLKERNEL_MAX_NB_DYNAMIC_FEATURES is a C constant that defines the maximum number of Features that can be installed simultaneously. By default, this constant is not hardcoded in the BSP -- it is automatically read at link time from the Kernel's com.microej.runtime.kernel.dynamicfeatures.max property. This ensures the BSP and Kernel always agree on the maximum Feature count.

The KF ROM region is divided into equal-sized slots, with one slot for each Feature permitted by LLKERNEL_MAX_NB_DYNAMIC_FEATURES. Each slot must be large enough to hold the largest Feature expected to be installed. Slot sizes are aligned to LLKERNEL_FLASH_SECTOR_SIZE boundaries.

In this repository, sectors are defined as the Erase Unit Size, the erase unit in the selected memory. Pages are defined as the Write Unit Size in the selected memory. See the diagram below:

Sectors and Pages

The KF ROM region size can be computed as follows:

slot_size   = align_up(largest_fo_rom_size, LLKERNEL_FLASH_SECTOR_SIZE)
kf_rom_size = slot_size x LLKERNEL_MAX_NB_DYNAMIC_FEATURES

Where largest_fo_rom_size is the size of the .rodata + .rodata.microej.resources sections of the biggest .fo file to be installed.

Conversely, given a KF ROM region, the individual slot size can be determined with:

rom_area_size = flash_ctrl_get_kf_end_address() - flash_ctrl_get_kf_start_address()
nb_sectors_per_feature = (rom_area_size / LLKERNEL_FLASH_SECTOR_SIZE) / LLKERNEL_MAX_NB_DYNAMIC_FEATURES
rom_slot_size = LLKERNEL_FLASH_SECTOR_SIZE * nb_sectors_per_feature

Warning

The KF ROM region must not overlap with any other partitions in the target flash memory (kernel firmware, filesystem, bootloader configuration). If you want to increase its size, you might have to reduce the size of the other partitions when the whole flash memory is in use.

RAM Allocation

A small RAM buffer is required per Feature for their runtime data (RW data). The RAM allocation algorithm allocates fixed-size memory slots from the LLKERNEL_RAM_BUFFER_SIZE buffer, aligned on 8-byte boundaries (LLKERNEL_RAM_AREA_ALIGNMENT). This buffer is divided equally among all Feature slots. Each slot is permanently reserved from install to uninstall. A minimum of 128 bytes per slot is recommended.

The size of individual RAM memory slots can be determined with the following formula:

ram_slot_size = ((LLKERNEL_RAM_BUFFER_SIZE / LLKERNEL_MAX_NB_DYNAMIC_FEATURES) & ~(LLKERNEL_RAM_AREA_ALIGNMENT - 1));

Determining Feature Memory Requirements

To determine the amount of ROM and RAM required for a .fo file, use the readelf tool.

See Determining the Amount of Required Memory for details on how to analyze .fo ELF sections.

Feature Header

Each slot in flash has a reserved space to store feature metadata named feature header. The two examples below show how a ROM area is partitioned when using this abstraction layer:

KF ROM area partition

Feature Installation Flow

Here is the installation flow for a given feature:

LLKERNEL_IMPL_allocateFeature:

  • A fixed size ROM memory slot is allocated.
  • A fixed size RAM memory slot is allocated.
  • All Flash sectors constituting a ROM memory slot for a given feature are erased.
  • A 32 bytes header is then written into the first sector of the ROM memory slot allocated for a feature. It contains metadata about the feature associated with the slot (RAM address, RAM size, ROM address, ROM size) as well as a uint32 encoded status flag used to detect whether the slot is used or free (see the magic number LLKERNEL_FEATURE_USED_MAGIC_NUMBER).

LLKERNEL_IMPL_copyToROM:

  • The feature data is copied into a page buffer (its size is configurable with LLKERNEL_FLASH_PAGE_SIZE) before getting flushed into Flash when a new page is reached.

LLKERNEL_IMPL_flushCopyToROM:

  • The remaining data buffered in the page buffer is flushed into Flash.

LLKERNEL_IMPL_freeFeature:

  • The first Flash sector of the ROM memory slot is erased.

See the diagram below of an example of sandboxed application (feature) install in flash:

App install in flash

See the diagram below of an example of sandboxed application (feature) update in flash:

App update in flash

Here is a list of useful MicroEJ documentation pages for the feature installation:

Usage

  1. These sources can be included in the VEE Port with the method you prefer, by using this repository as a submodule or by doing a copy of the sources in the VEE Port repository.

  2. Implement the functions listed in the file flash_controller.h by following the functions documentation.

  3. The configuration file LLKERNEL_flash_configuration.h stores default values of the abstraction layer configuration. If you want to update a configuration please edit or create the file veeport_configuration.h and set the desired value. This setting overwrites the content of LLKERNEL_flash_configuration.h. If your VEE Port does not print logs using printf, the trace redirection macro LLKERNEL_TRACE can be updated in veeport_configuration.h.

Requirements

N/A

Validation

This Abstraction Layer implementation can be validated in the target Board Support Package using the llkernel tests of the AbstractionLayer-Tests project.

Here is a non exhaustive list of tested environments:

  • Hardware / Compiler
    • STM32U5G9J-DK2 / IAR Embedded Workbench 9.50.1
    • NRF54L15-DK / arm-zephyr-eabi-gcc-12.2.0.exe (Zephyr SDK 0.17.0) 12.2.0
  • Passed the llkernel C tests version 1.2.0

MISRA Compliance

This Abstraction Layer implementation is MISRA-compliant (MISRA C:2012) with some noted exception. It has been verified with Cppcheck v2.13. Here is the list of deviations from MISRA standard:

Deviation Category Justification
Rule 2.5 Required Macro defined for optional log usage.
Rule 5.5 Required Macro with same name generated in intern/LLKERNEL_impl.h.
Rule 8.4 Required A compatible declaration is defined in headers provided by the VEE Port.
Rule 8.7 Advisory API function that can be used in another file.
Rule 10.3 Required False positive, this is a 8 bits pointer that stores a 32 bits address.
Rule 11.3 Required Cast used by many C framework to factorize code.
Rule 11.4 Advisory Used when coding BSP C source code (drivers, etc.)
Rule 11.5 Advisory Used for code genericity/abstraction.
Rule 17.7 Required Unused non-void returned type, the use of returned values of debug traces is not necessary.
Rule 18.4 Advisory Points after the + operation.
Rule 21.6 Required Used for debug log usage.

Dependencies

  • MicroEJ Architecture 8.1 or higher.

Source

N/A

Restrictions

None.

Migration Guide

From version 1.x to 2.0.0

  • The following macros have been removed: , LLKERNEL_FLASH_BASE, LLKERNEL_FLASH_SIZE, redefine them locally if you used them in the implementation of flash_controller.h functions.
  • Replace the use of LLKERNEL_KF_START and LLKERNEL_KF_END by the functions flash_ctrl_get_kf_start_address and flash_ctrl_get_kf_end_address respectively.
  • Several function declarations in flash_controller.h have been removed, such as flash_ctrl_get_page_size and flash_ctrl_get_page_address. Define them locally if used in the implementation of flash_controller.h functions.

Copyright 2025-2026 MicroEJ Corp. All rights reserved. Use of this source code is governed by a BSD-style license that can be found with this software.

About

MicroEJ Kernel Low Level API implementation to install features in an External Flash.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages