Introduction to LEVELX

Applicable for STM32MP13x lines


1 Introduction[edit]

Azure® RTOS LevelX is a library offering wear-levelling and bad-block management features for Flash memories. LevelX is not intended to provide FileSytem APIs, but only low-level APIs to read, write, and erase sectors in Flash memories. Combined with FileX, it allows seamless use of NAND and NOR Flash memories as media storage devices.

LevelX Overview


LevelX is designed in a modular way that facilitates the support of any Flash memory. In fact, LevelX requires a low-level driver interacting with the Flash memory to support the basic raw API, read blocks, write blocks, erase blocks, and check errors. These raw APIs are then logically combined to offer more user-friendly high-level APIs. The main features offered by LevelX are:

  • Data read/write
  • Flash erase
  • Flash defragmentation
  • Wear levelling
  • Error checks

Further details are available in LevelX official documentation [1]

2 STM32Cube MPU Integration[edit]

LevelX mainly targets the following memory types:

  • NOR Flash memories (SPI/Quad-SPI/Octo-SPI), making use of wear-levelling and bad-block management features.
  • NAND Flash memories, also making use of wear-levelling and bad-block management features.
  • SRAMs: covering any MPU internal volatile memory (such as DTCM and AXI SRAM). This is useful specifically for fast prototyping and testing.


2.1 Known limitations[edit]

  • No known limitations so far. More details are in LevelX official documentation[1]

3 How to use[edit]

LevelX must be used alongside with FileX.
Refer to the FileX page for more details.

LevelX requires low-level interfaces to support the above-mentioned hardware devices:

  • lx_stm32_*_driver.c: LevelX driver patterns that are ready to use by the application. They are delivered as part of the LevelX source code. The drivers may differ between STM32 Series depending on the supported features.
LevelX LowLayer

The LevelX driver Octo-SPI header file below is an example:

#ifndef LX_STM32_OSPI_DRIVER_H
#define LX_STM32_OSPI_DRIVER_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "lx_api.h"
#include "stm32NNxx_hal.h"
/* #include "mx25lm51245g.h" */

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */

/* USER CODE END ET */

/* Exported constants --------------------------------------------------------*/

/* the OctoSPI instance, default value set to 0 */
#define LX_STM32_OSPI_INSTANCE                           0
#define LX_STM32_OSPI_DEFAULT_TIMEOUT                    10 * TX_TIMER_TICKS_PER_SECOND
#define LX_STM32_DEFAULT_SECTOR_SIZE                     LX_STM32_OSPI_SECTOR_SIZE

/* when set to 1 LevelX is initializing the OctoSPI memory,
 * otherwise it is the up to the application to perform it.
 */
#define LX_STM32_OSPI_INIT                               1

#if (LX_STM32_OSPI_INIT == 1)

/* allow the driver to fully erase the OctoSPI chip. This should be used carefully.
 * the call is blocking and takes a while. by default it is set to 0.
 */
#define LX_STM32_OSPI_ERASE                              0
#endif

/* USER CODE BEGIN EC */

/* USER CODE END EC */

/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */

#define LX_STM32_OSPI_CURRENT_TIME                              tx_time_get

#define LX_STM32_OSPI_POST_INIT()

#define LX_STM32_OSPI_PRE_READ_TRANSFER(__status__)

#define LX_STM32_OSPI_READ_CPLT_NOTIFY(__status__)

#define LX_STM32_OSPI_POST_READ_TRANSFER(__status__)

#define LX_STM32_OSPI_READ_TRANSFER_ERROR(__status__)

#define LX_STM32_OSPI_PRE_WRITE_TRANSFER(__status__)

#define LX_STM32_OSPI_WRITE_CPLT_NOTIFY(__status__)

#define LX_STM32_OSPI_POST_WRITE_TRANSFER(__status__)

#define LX_STM32_OSPI_WRITE_TRANSFER_ERROR(__status__)

/* USER CODE END EM */

/* Exported functions prototypes ---------------------------------------------*/
INT lx_stm32_ospi_lowlevel_init(UINT instance);
INT lx_stm32_ospi_lowlevel_deinit(UINT instance);

INT lx_stm32_ospi_get_status(UINT instance);
INT lx_stm32_ospi_get_info(UINT instance, ULONG *block_size, ULONG *total_blocks);

INT lx_stm32_ospi_read(UINT instance, ULONG *address, ULONG *buffer, ULONG words);
INT lx_stm32_ospi_write(UINT instance, ULONG *address, ULONG *buffer, ULONG words);

INT lx_stm32_ospi_erase(UINT instance, ULONG block, ULONG erase_count, UINT full_chip_erase);
INT lx_stm32_ospi_is_block_erased(UINT instance, ULONG block);

UINT lx_ospi_driver_system_error(UINT error_code);

UINT lx_stm32_ospi_initialize(LX_NOR_FLASH *nor_flash);
/* USER CODE BEGIN EFP */

/* USER CODE END EFP */

/* Private defines -----------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* The following defines should be set according to the OctoSPI component used */
#define LX_STM32_OSPI_SECTOR_SIZE                 MX25LM51245G_BLOCK_SIZE
#define LX_STM32_OSPI_FLASH_SIZE                  MX25LM51245G_FLASH_SIZE
#define LX_STM32_OSPI_PAGE_SIZE                   MX25LM51245G_PAGE_SIZE
#define LX_STM32_OSPI_BULK_ERASE_MAX_TIME         MX25LM51245G_CHIP_ERASE_MAX_TIME
#define LX_STM32_OSPI_SECTOR_ERASE_MAX_TIME       MX25LM51245G_SECTOR_ERASE_MAX_TIME
#define LX_STM32_OSPI_WRITE_REG_MAX_TIME          MX25LM51245G_WRITE_REG_MAX_TIME
#define LX_STM32_OSPI_DUMMY_CYCLES_READ_OCTAL     MX25LM51245G_DUMMY_CYCLES_READ_OCTAL_66M
#define LX_STM32_OSPI_DUMMY_CYCLES_CR_CFG         MX25LM51245G_CR2_DC_66M
#define LX_STM32_OSPI_CR2_REG3_ADDR               MX25LM51245G_CR2_REG3_ADDR
#define LX_STM32_QSPI_CR2_REG1_ADDR               MX25LM51245G_CR2_REG1_ADDR
#define LX_STM32_OSPI_SR_WEL                      MX25LM51245G_SR_WEL
#define LX_STM32_OSPI_SR_WIP                      MX25LM51245G_SR_WIP
#define LX_STM32_OSPI_CR2_SOPI                    MX25LM51245G_CR2_SOPI
#define LX_STM32_OSPI_CR2_DOPI                    MX25LM51245G_CR2_DOPI

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

#ifdef __cplusplus
}
#endif
#endif /* LX_STM32_OSPI_DRIVER_H */


4 References[edit]