Skip to content

Infineon/emfile

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SEGGER emFile for ModusToolbox

Overview

emFile is a fail-safe filesystem designed for embedded systems by SEGGER Microcontroller GmbH that can be used with different types of storage devices. It is a high-performance library optimized for high speed, versatility, and a minimal memory footprint of both RAM and Flash.

Infineon has licensed emFile from SEGGER and offers it for free to its customers. This middleware library provides emFile in the form of pre-built libraries and supports FAT 12/16/32 file systems.

Important Notice Regarding Long File Names (LFN): If you configure the software to support long file names on FAT file systems, you should determine whether a license from Microsoft is required. Infineon Technologies AG and its suppliers grant no license under Microsoft's intellectual property rights and assume no liability for any use of the software without obtaining any license that may be required.

Features

  • SEGGER emFile library v5.22.0

  • Supports FAT 12/16 and FAT 32 file systems

    • COMPONENT EMFILE_FAT16 supports FAT12 and FAT 16

    • COMPONENT EMFILE_FAT32 extends FAT12/16 and supports functionality FAT 32

  • Supports Long File Name (LFN)

  • Cache support via RAM for optimized performance

  • Supports fail-safety through the Journaling component

  • Supports encryption: DES (56-bit key length)

  • Supports thread safety for use with multi-threaded RTOS environments using the abstraction-rtos library

  • Supports memory card devices such as MMC, SD, SDHC, and eMMC using SD bus mode (card mode)

    • The SD/MMC HW layer uses DMA and waits on a semaphore until data transfer completes when enabled

    • The SD/MMC driver supports up to 2 instances (FS_MMC_NUM_UNITS=2)

  • Supports Single-SPI/Dual-DSPI/Quad-SPI based NOR flash memories

  • Supports wear leveling for use with NOR flash memories

When to Use

Use emFile when your embedded application needs a reliable, high-performance FAT file system on non-volatile storage. Typical use cases include:

  • Data logging - Storing sensor readings or diagnostic data on an SD card or NOR flash for later retrieval.
  • Firmware update storage - Saving firmware images to an external storage medium and applying them at runtime.
  • Configuration file management - Reading and writing application settings stored as files on a FAT-formatted device.
  • File exchange with host systems - Creating or reading files on a storage device that must also be accessible from a PC or other host (for example, over USB mass storage).
  • Multi-threaded (RTOS) applications - When thread-safe file system access is required across multiple concurrent tasks.

emFile is appropriate when FAT 12/16/32 compatibility, wear leveling on NOR flash, or fail-safe operation with journaling support is required.

Prerequisites

  • ModusToolbox™ software v3.6 or later with Project Creator, Library Manager, and Device Configurator
  • Toolchain: GCC ARM (included with ModusToolbox) or ARM Compiler 6
  • Hardware: PSoC(TM) Edge E84 MCU development board
    • SD card example: board with SDHC peripheral and a micro SD card
    • NOR flash example: board with SMIF/QSPI peripheral
  • Serial terminal (for example, PuTTY or Tera Term) configured to 115200 baud, 8N1

How to Use

Quick Start

The Quick Start examples below are provided for PSoC(TM) Edge E84 MCUs. They demonstrate initializing the file system on the target memory, creating and opening a file, and updating its content.

Project Creation

  1. Create an empty application using the Project Creator tool in ModusToolbox™ software.
  2. Add the emfile and retarget-io libraries using the Library Manager.
  3. To run the example in an RTOS environment, add the FreeRTOS library using the Library Manager. Then add RTOS_AWARE and FREERTOS to the COMPONENTS variable in the Makefile:
    COMPONENTS += RTOS_AWARE FREERTOS
    Note: In the RTOS environment, select Active mode for System Idle Power Mode in the Power personality (System Tab) in the Device Configurator.
  4. (NOR flash driver only) To use the same storage for code execution and file system, perform the additional steps described in the XIP Support section below.

HW Configuration in Device Configurator

All HW resources used in this Quick Start must be configured in the Device Configurator:

  • UART for logging
  • One pin to check the button status
  • Memory Card Device HW – SDHC
  • NOR flash HW – SMIF

If a different alias name is selected instead of the expected resource name in the Device Configurator, the code snippets must be updated accordingly.

Resource Expected name
Quad Serial Memory Interface SMIF_EMFILE
SD Host Controller SDHC_EMFILE
Serial Communication Block (for debug UART) DEBUG_UART
Pin CYBSP_USER_BTN

Recommended Memory Card Device configuration

Recommended Memory Card Device configuration

Note: The pin assignments below are board-specific. Select appropriate pins based on your board documentation.

SD Host Controller (SDHC) 1 (SDHC_EMFILE) - Parameters

Category Parameter Value
Overview Configuration Help Open SD Host Documentation
Timing Clock 8 bit Divider 0 clk [USED]
Timing Input Clock Frequency (kHz) 100000.000
General Card Type SD/SDIO
General DMA Type ADMA2
General LED Control Disabled
General Bus Width 4-bit
General Enable Low Voltage Signaling Disabled
Inputs CLK P7[1] digital_inout (CYBSP_SDHC_CLK) [USED]
Inputs CMD P7[0] digital_inout (CYBSP_SDHC_CMD) [USED]
Inputs DAT0 P7[3] digital_inout (CYBSP_SDHC_IO0) [USED]
Inputs DAT1 P7[5] digital_inout (CYBSP_SDHC_IO1) [USED]
Inputs DAT2 P7[6] digital_inout (CYBSP_SDHC_IO2) [USED]
Inputs DAT3 P7[7] digital_inout (CYBSP_SDHC_IO3) [USED]
Inputs Card Detect Unassigned
Inputs Card Mechanical Write Protect Unassigned
Inputs Card if Power Enabled Unassigned
Inputs IO Volt Select Unassigned
Advanced Store Config in Flash Enabled

Recommended SMIF configuration

Recommended SMIF configuration

Note: The pin assignments below are board-specific. Select appropriate pins based on your board documentation.

Quad Serial Memory Interface (QSPI) 0 (SMIF_EMFILE) - Parameters

Category Parameter Value
Clocks Interface Clock Source CLK_HF3 root_clk [USED]
Clocks Use internal DLL Disabled
Clocks Interface Clock Frequency 99 MHz
Clocks RX Capture Mode Normal SPI SDR/DDR
System SMIF IP Version 6
Data Lines SPI Data[0] P1[0] / SMIF0_SPIHB_DATA0 aux (CYBSP_QSPI_D0) [USED]
Data Lines SPI Data[1] P1[1] / SMIF0_SPIHB_DATA1 aux (CYBSP_QSPI_D1) [USED]
Data Lines SPI Data[2] P1[2] / SMIF0_SPIHB_DATA2 aux (CYBSP_QSPI_D2) [USED]
Data Lines SPI Data[3] P1[3] / SMIF0_SPIHB_DATA3 aux (CYBSP_QSPI_D3) [USED]
Data Lines SPI Data[4] Unassigned
Data Lines SPI Data[5] Unassigned
Data Lines SPI Data[6] Unassigned
Data Lines SPI Data[7] Unassigned
Slave Select SPI Slave Select 0 Unassigned
Slave Select SPI Slave Select 1 P2[0] digital_out (CYBSP_QSPI_SS) [USED]
Slave Select SPI Slave Select 2 Unassigned
Slave Select SPI Slave Select 3 Unassigned
DMA Triggers RX Trigger Output Unassigned
DMA Triggers TX Trigger Output Unassigned
Interrupt Memory Mode Alignment Error Disabled
Interrupt RX Data FIFO Underflow Disabled
Interrupt TX Command FIFO Overflow Disabled
Interrupt TX Data FIFO Overflow Disabled
Advanced Store Config in Flash Enabled

Recommended Debug UART configuration

Recommended Debug UART configuration (part 1)

Recommended Debug UART configuration (part 2)

Note: The pin assignments below are board-specific. Select appropriate pins based on your board documentation.

Serial Communication Block (SCB) 2 (DEBUG_UART) - Parameters

Category Parameter Value
General Com Mode Standard
General Baud Rate (bps) 115200
General Oversample 8
General Bit Order LSB First
General Data Width 8 bits
General Parity None
General Stop Bits 1 bit
General Enable Digital Filter Disabled
Enable RS-485 TX-Enable Disabled
Flow Control Enable Flow Control Disabled
Flow Control CTS Polarity Active Low
Flow Control RTS Polarity Active Low
Flow Control RTS Activation Level 63
Connections Clock 16 bit Divider 0 clk [USED]
Connections RX P6[5] digital_inout (CYBSP_DEBUG_UART_RX) [USED]
Connections TX P6[7] digital_inout (CYBSP_DEBUG_UART_TX) [USED]
Connections RX Trigger Output Unassigned
Connections TX Trigger Output Unassigned
Trigger Level RX FIFO Level 63
Trigger Level TX FIFO Level 63
Multi Processor Mode Enable Multi Processor Mode Disabled
Multi Processor Mode Address 0
Multi Processor Mode Mask 255
Multi Processor Mode Accept Matching Address in RX FIFO Disabled
Advanced Drop on Frame Error Disabled
Advanced Drop on Parity Error Disabled
Advanced Break Signal Bits 11
Advanced Break Level Low Level Pulse Detection
Advanced Store Config in Flash Enabled
API Mode API Mode High Level

Recommended Button Pin configuration

Recommended Button Pin configuration

Note: The pin assignments below are board-specific. Select appropriate pins based on your board documentation.

P8[3] (CYBSP_SW2, CYBSP_USER_BTN1, CYBSP_USER_BTN) - Parameters

Category Parameter Value
Overview Configuration Help Open GPIO Documentation
General Drive Mode Resistive Pull-Up, Input buffer on
General Initial Drive State High (1)
General Secure attribute Non-secure access (1)
Input Threshold CMOS
Input Interrupt Trigger Type None
Output Slew Rate Fast
Output Extended Drive Strength Disabled
Output Drive Strength 1/2
Internal Connection Digital Output Unassigned
Internal Connection Digital InOut Unassigned
Internal Connection AUX Unassigned
Advanced Store Config in Flash Enabled

Add emFile Logic to main.c

Specific steps for NOR flash (SPI flash) driver configuration

  1. Include the required headers:
    #include "mtb_hal_memoryspi.h"
    #include "cy_sysint.h"
    #include "cy_smif.h"
  2. Add global variables:
    static mtb_hal_memoryspi_t * memspi_obj_ptr;
    static cy_stc_smif_context_t memspi_context;
  3. Add the interrupt handler for NOR flash HW:
    void nor_isr(void)
    {
        mtb_hal_memoryspi_process_interrupt(memspi_obj_ptr);
    }
  4. Add the function for NOR flash HW initialization:
    void FS_NOR_HW_SPIFI_ConfigureHw(mtb_hal_memoryspi_t * memspi_obj)
    {
        cy_rslt_t hal_status;
        cy_en_smif_status_t pdl_smif_status;
        cy_en_sysint_status_t pdl_sysint_status;
    
        memspi_obj_ptr = memspi_obj;
    
        pdl_smif_status = Cy_SMIF_Init(SMIF_EMFILE_HW, SMIF_EMFILE_hal_config.config, 10000UL, &memspi_context);
        if (CY_RSLT_SUCCESS != pdl_smif_status)
        {
            printf("Cy_SMIF_Init returns error status\n\r");
            CY_ASSERT(0U);
        }
    
        hal_status = mtb_hal_memoryspi_setup(memspi_obj_ptr, &SMIF_EMFILE_hal_config, &memspi_context);
        if (CY_RSLT_SUCCESS != hal_status)
        {
            printf("mtb_hal_memoryspi_setup returns error status\n\r");
            CY_ASSERT(0U);
        }
    
        cy_stc_sysint_t nor_isr_config =
        {
            .intrSrc = SMIF_EMFILE_IRQ,
            .intrPriority = 3U
        };
    
        pdl_sysint_status = Cy_SysInt_Init(&nor_isr_config, nor_isr);
        if (CY_SYSINT_SUCCESS != pdl_sysint_status)
        {
            printf("Cy_SysInt_Init returns error status\n\r");
            CY_ASSERT(0U);
        }
    
        NVIC_EnableIRQ((IRQn_Type) nor_isr_config.intrSrc);
    
        Cy_SMIF_SetDataSelect(SMIF_EMFILE_HW, (memspi_obj_ptr->chip_select), CY_SMIF_DATA_SEL0);
        Cy_SMIF_Enable(SMIF_EMFILE_HW, memspi_obj_ptr->context);
    }
  5. Add EMFILE_NOR_FLASH to the COMPONENTS variable in the Makefile:
    COMPONENTS += EMFILE_NOR_FLASH

Specific steps for Memory Card Device (SD/MMC) driver configuration

  1. Include the required headers:
    #include "mtb_hal_sdhc.h"
    #include "cy_sd_host.h"
    #include "cy_sysint.h"
  2. Add global variables:
    static mtb_hal_sdhc_t * sdhc_obj_ptr;
    static cy_stc_sd_host_context_t sdhc_host_context;
  3. Add the interrupt handler for Memory Card Device HW:
    void sd_card_isr(void)
    {
        mtb_hal_sdhc_process_interrupt(sdhc_obj_ptr);
    }
  4. Add the Cy_SD_Host_IsCardConnected() function:
    bool Cy_SD_Host_IsCardConnected(SDHC_Type const *base)
    {
        (void) base;
    
        return true;
    }
  5. Add the function for Memory Card Device HW initialization:
    void FS_MMC_HW_CM_ConfigureHw(mtb_hal_sdhc_t * sdhc_obj)
    {
        cy_rslt_t hal_status;
        cy_en_sd_host_status_t pdl_sdhc_status;
        cy_en_sysint_status_t pdl_sysint_status;
    
        sdhc_obj_ptr = sdhc_obj;
    
        /* The SD Card should be enabled before calling any other SD Card APIs */
        Cy_SD_Host_Enable(SDHC_EMFILE_HW);
    
        pdl_sdhc_status = Cy_SD_Host_Init(SDHC_EMFILE_HW, &SDHC_EMFILE_config, &sdhc_host_context);
        if (CY_SD_HOST_SUCCESS != pdl_sdhc_status)
        {
            printf("Cy_SD_Host_Init returns error status\n\r");
            CY_ASSERT(0U);
        }
    
        pdl_sdhc_status = Cy_SD_Host_InitCard(SDHC_EMFILE_HW, &SDHC_EMFILE_card_cfg, &sdhc_host_context);
        if (CY_SD_HOST_SUCCESS != pdl_sdhc_status)
        {
            printf("Cy_SD_Host_InitCard returns error status\n\r");
            CY_ASSERT(0U);
        }
    
        hal_status = mtb_hal_sdhc_setup(sdhc_obj_ptr, &SDHC_EMFILE_sdhc_hal_config, NULL, &sdhc_host_context);
        if (CY_RSLT_SUCCESS != hal_status)
        {
            printf("mtb_hal_sdhc_setup returns error status\n\r");
            CY_ASSERT(0U);
        }
    
        cy_stc_sysint_t sdhc_isr_config =
        {
            .intrSrc = SDHC_EMFILE_IRQ,
            .intrPriority = 3U
        };
    
        pdl_sysint_status = Cy_SysInt_Init(&sdhc_isr_config, sd_card_isr);
        if (CY_SYSINT_SUCCESS != pdl_sysint_status)
        {
            printf("Cy_SysInt_Init returns error status\n\r");
            CY_ASSERT(0U);
        }
    
        NVIC_EnableIRQ((IRQn_Type) sdhc_isr_config.intrSrc);
    }
  6. Add EMFILE_SD_CARD to the COMPONENTS variable in the Makefile:
    COMPONENTS += EMFILE_SD_CARD

Common code

  1. Include the required headers:
    #include "cybsp.h"
    #include "cy_retarget_io.h"
    #include "mtb_hal_gpio.h"
    #include "mtb_hal_system.h"
    #include "FS.h"
    #include <string.h>
    #include <inttypes.h>
    
    #if defined(COMPONENT_RTOS_AWARE)
    #include "FreeRTOS.h"
    #include "task.h"
    #endif /* #if defined(COMPONENT_RTOS_AWARE) */
  2. Add the common defines to the project:
    #define NUM_BYTES_TO_READ_FROM_FILE         (256U)
    #define STRING_TO_WRITE                     "This is an emFile filesystem example for ModusToolbox."
    #define FILE_NAME                           "File.txt"
    
    #if defined(COMPONENT_RTOS_AWARE)
    #define EMFILE_TASK_STACK_SIZE              (1000U)
    #endif /* #if defined(COMPONENT_RTOS_AWARE) */
    
    #define DEBOUNCE_DELAY_MS                   (50U)
  3. Add common global variables:
    static char fileData[NUM_BYTES_TO_READ_FROM_FILE];
    static mtb_hal_gpio_t button_obj;
    
    #if defined(COMPONENT_RTOS_AWARE)
    static TaskHandle_t emfile_task_handle;
    #else
    static bool button_press = false;
    #endif /* #if defined(COMPONENT_RTOS_AWARE) */
  4. Add the function prototypes:
    static void user_button_callback(void *handler_arg, mtb_hal_gpio_event_t event);
    static void check_error(char *message, int error);
    static void btn_init(void);
    void retarget_io_init(void);  /* Implemented in separate file */
  5. Add the emFile task function:
    void emfile_task(void* arg)
    {
        U32         varU32;
        U32         numBytesToRead;
        int         error;
        FS_FILE    *filePtr;
        const char *volumeName = "";
    
        (void) arg;
    
        btn_init();
    
    #if defined (COMPONENT_EMFILE_NOR_FLASH)
        printf("Using NOR flash as storage device\n");
    #else
        printf("Using SD card as storage device\n");
    #endif
    
        FS_Init();
    
    #if defined (COMPONENT_EMFILE_NOR_FLASH)
        error = FS_FormatLLIfRequired(volumeName);
        check_error("Error in low-level formatting", error);
    #endif
    
        error = FS_IsHLFormatted(volumeName);
        check_error("Error in checking if volume is high-level formatted", error);
    
        if (error == 0)
        {
            printf("Perform high-level format\n");
            error = FS_Format(volumeName, NULL);
            check_error("Error in high-level formatting", error);
        }
    
        varU32 = FS_GetVolumeSizeKB(volumeName);
        printf("Volume size: %"PRIu32" KB\n\n", varU32);
    
        if (0U == varU32)
        {
            printf("Error in checking the volume size\n");
            CY_ASSERT(0U);
        }
    
        printf("Opening the file for reading...\n");
    
        filePtr = FS_FOpen(FILE_NAME, "r");
    
        if (filePtr != NULL)
        {
            numBytesToRead = sizeof(fileData) - 1U;
            varU32 = FS_GetFileSize(filePtr);
    
            if (varU32 < numBytesToRead)
            {
                numBytesToRead = varU32;
            }
    
            printf("Reading %"PRIu32" bytes from the file. ", numBytesToRead);
            varU32 = FS_Read(filePtr, fileData, numBytesToRead);
    
            if (varU32 != numBytesToRead)
            {
                error = FS_FError(filePtr);
                check_error("Error in reading from the file", error);
            }
    
            fileData[numBytesToRead] = '\0';
            printf("File Content:\n\"%s\"\n", fileData);
    
            error = FS_FClose(filePtr);
            check_error("Error in closing the file", error);
    
            printf("\nOpening the file for overwriting...\n");
        }
        else
        {
            printf("Unable to read. File not found.\n");
            printf("\nOpening the file for writing...\n");
        }
    
        filePtr = FS_FOpen(FILE_NAME, "w");
    
        if (filePtr != NULL)
        {
            varU32 = FS_Write(filePtr, STRING_TO_WRITE, strlen(STRING_TO_WRITE));
    
            if (varU32 != strlen(STRING_TO_WRITE))
            {
                error = FS_FError(filePtr);
                check_error("Error in writing to the file", error);
            }
    
            printf("File is written with the following message:\n");
            printf("\"%s\"\n\n", STRING_TO_WRITE);
    
            error = FS_FClose(filePtr);
            check_error("Error in closing the file", error);
    
            mtb_hal_gpio_enable_event(&button_obj, MTB_HAL_GPIO_IRQ_FALL, true);
            printf("\nPress the user button to delete the file or press reset to run the example again.\n\n");
    
            while (true)
            {
    #if defined (COMPONENT_RTOS_AWARE)
                if (1UL == ulTaskNotifyTake(pdTRUE, portMAX_DELAY))
                {
    #else
                if (button_press)
                {
                    button_press = false;
    #endif
                    cy_rslt_t result;
                    result = mtb_hal_system_delay_ms(DEBOUNCE_DELAY_MS);
                    CY_ASSERT(CY_RSLT_SUCCESS == result);
                    (void) result;
    
                    if (!mtb_hal_gpio_read(&button_obj)) { break; }
                }
            }
    
            printf("Deleting the file... \n");
    
            error = FS_Remove(FILE_NAME);
            check_error("Error in deleting the file", error);
    
            FS_Unmount(volumeName);
    
            printf("Filesystem operations completed successfully!\n");
            printf("Press reset to run the example again.\n");
        }
        else
        {
            printf("Unable to open the file for writing! Exiting...\n");
        }
    
        for (;;) {}
    }
  6. Add the check error function:
    static void check_error(char *message, int error)
    {
        if (error < 0)
        {
            printf("\n================================================================================\n");
            printf("\nFAIL: %s\n", message);
            printf("Error Value: %d\n", error);
            printf("emFile-defined Error Message: %s", FS_ErrorNo2Text(error));
            printf("\n================================================================================\n");
    
            while (true);
        }
    }
  7. Add the callback function for the user button:
    static void user_button_callback(void *handler_arg, mtb_hal_gpio_event_t event)
    {
        (void) handler_arg;
        (void) event;
    
    #if defined(COMPONENT_RTOS_AWARE)
        BaseType_t higher_priority_task_woken = pdFALSE;
        vTaskNotifyGiveFromISR(emfile_task_handle, &higher_priority_task_woken);
        portYIELD_FROM_ISR(higher_priority_task_woken);
    #else
        button_press = true;
    #endif
    }
  8. Add the interrupt handler for the user button:
    void btn_isr(void)
    {
        mtb_hal_gpio_process_interrupt(&button_obj);
    }
  9. Add the function for user button initialization:
    static void btn_init(void)
    {
        cy_en_sysint_status_t pdl_sysint_status;
    
        mtb_hal_gpio_setup(&button_obj, CYBSP_USER_BTN_PORT_NUM, CYBSP_USER_BTN_PIN);
        mtb_hal_gpio_configure(&button_obj, MTB_HAL_GPIO_DIR_INPUT, MTB_HAL_GPIO_DRIVE_PULLUP);
        mtb_hal_gpio_register_callback(&button_obj, user_button_callback, NULL);
    
        cy_stc_sysint_t btn_isr_config =
        {
            .intrSrc = CYBSP_USER_BTN_IRQ,
            .intrPriority = 3U
        };
    
        pdl_sysint_status = Cy_SysInt_Init(&btn_isr_config, btn_isr);
        if (CY_SYSINT_SUCCESS != pdl_sysint_status)
        {
            printf("Cy_SysInt_Init returns error status\n\r");
        }
    
        NVIC_EnableIRQ((IRQn_Type) btn_isr_config.intrSrc);
    }
  10. Update main():
    retarget_io_init();
    
    printf("************* emFile FAT Filesystem ************* \n\n");
    
    #if defined (COMPONENT_RTOS_AWARE)
    xTaskCreate(emfile_task, "emFile Task", EMFILE_TASK_STACK_SIZE,
                NULL, (configMAX_PRIORITIES - 1), &emfile_task_handle);
    vTaskStartScheduler();
    #else
    emfile_task(NULL);
    #endif

retarget-io configuration

  1. Add the retarget-io configuration function:
    void retarget_io_init(void)
    {
        cy_rslt_t result;
    
        static cy_stc_scb_uart_context_t DEBUG_UART_context;
        static mtb_hal_uart_t            DEBUG_UART_hal_obj;
    
        result = (cy_rslt_t)Cy_SCB_UART_Init(DEBUG_UART_HW, &DEBUG_UART_config, &DEBUG_UART_context);
        if (result != CY_RSLT_SUCCESS) { CY_ASSERT(0); }
    
        Cy_SCB_UART_Enable(DEBUG_UART_HW);
    
        result = mtb_hal_uart_setup(&DEBUG_UART_hal_obj, &DEBUG_UART_hal_config, &DEBUG_UART_context, NULL);
        if (result != CY_RSLT_SUCCESS) { CY_ASSERT(0); }
    
        result = cy_retarget_io_init(&DEBUG_UART_hal_obj);
        if (result != CY_RSLT_SUCCESS) { CY_ASSERT(0); }
    
        /* \x1b[2J\x1b[;H - ANSI ESC sequence for clear screen */
        printf("\x1b[2J\x1b[;H");
        printf("Retarget-io is configured\n\r");
    }

Project Execution

  1. Open a serial terminal. Set the serial port parameters to 8N1 and 115200 baud.
  2. Build and program the project.
  3. If the previous steps were correct, logs will appear in the serial terminal.
  4. The example initializes the emFile file system on the target memory device, creates a file, and writes data to it. Click the user button to delete the file.
Expected Serial Output

First run (no file present on the storage device):

Retarget-io is configured
************* emFile FAT Filesystem *************

Using SD card as storage device
Volume size: XXXX KB

Opening the file for reading...
Unable to read. File not found.

Opening the file for writing...
File is written with the following message:
"This is an emFile filesystem example for ModusToolbox."

Press the user button to delete the file or press reset to run the example again.

After pressing the user button:

Deleting the file...
Filesystem operations completed successfully!
Press reset to run the example again.

Subsequent runs (file present from previous run):

Reading XX bytes from the file. File Content:
"This is an emFile filesystem example for ModusToolbox."

Opening the file for overwriting...
File is written with the following message:
"This is an emFile filesystem example for ModusToolbox."

Select the FAT Library Variant

Add one of the following values to the COMPONENTS variable in the Makefile based on your FAT requirements:

COMPONENT FAT support
EMFILE_FAT16 FAT 12 and FAT 16
EMFILE_FAT32 FAT 12, FAT 16, and FAT 32

The correct pre-built library is selected automatically based on the CORE, VFP_SELECT, and TOOLCHAIN Makefile variables.

Configuring the HW Layer for the NOR Flash Block Map Driver (NOR_BM)

Configure the HW layer for the Block Map NOR driver in FS_X_AddDevices() before adding the driver using FS_AddDevice(). Use the configuration template from export/config/COMPONENT_EMFILE_NOR_FLASH/FS_ConfigNOR_BM_SPIFI.c as a starting point. Add EMFILE_NOR_FLASH to the COMPONENTS variable to include the template file in the build.

The template provides a weak FS_NOR_HW_SPIFI_ConfigureHw() function that must be implemented in the user application with the actual SMIF peripheral initialization.

Note: The NOR HW layer supports up to four memories using four slave select pins, but all memories must be connected to the same data lines.

Configuring the HW Layer for the SD/MMC Driver

Configure the HW layer for the SD/MMC driver in FS_X_AddDevices() before adding the driver using FS_AddDevice(). Use the configuration template from export/config/COMPONENT_EMFILE_SD_CARD/FS_ConfigMMC_CM_HS.c as a starting point. Add EMFILE_SD_CARD to the COMPONENTS variable to include the template file in the build.

The template provides a weak FS_MMC_HW_CM_ConfigureHw() function that must be implemented in the user application with the actual SDHC peripheral initialization.

XIP Support – Code and emFile on the Same NOR Flash (optional)

To share the NOR flash between code execution (XIP) and emFile storage:

  1. Add ENABLE_XIP_EMFILE_ON_SAME_NOR_FLASH to the DEFINES variable in the Makefile.
  2. Update the linker script to place FS_NOR_HW_SPIFI.o and FS_ConfigNOR_BM_SPIFI.o in a memory region not used by emFile (for example, SRAM). Ensure that SysLib, SMIF, and Memory SPI driver source files are in the same region.
  3. Implement the blocking read/write/erase completion functions as shown in FS_ConfigNOR_BM_SPIFI.c.
  4. Provide SRAM buffers for logic sector data and parameters.

Note: When XIP support is enabled, asynchronous read/write in RTOS environments is not supported. On multi-core systems, other cores that share the same NOR flash for code execution may lose access to the memory during write or erase operations.

Known Issues and Limitations

  • Supported SD bus speed modes are Default speed and High speed. Ultra High Speed (UHS) modes such as SDR 12, SDR25, and SDR50 requiring 1.8-V signaling are not supported. These modes will be supported in the future.

  • emFile always selects the 256 kB erase sector size for S25FS128S. If S25FS128S is configured to use another erase sector size, this parameter can be set by the FS_NOR_SPIFI_SetSectorSize() function inside FS_X_AddDevices(). By default, for S25FS128S, the erase sector size is 64 kB.

  • Octal SPI is not supported for NOR flash storage.

  • emFile does not support working with memories that need configuration in the secure core from the non-secure core for Edge devices.

Troubleshooting

Symptom Likely cause Fix
Build error: emFile library not found COMPONENTS not set Add EMFILE_FAT16 or EMFILE_FAT32 and the storage driver (EMFILE_SD_CARD or EMFILE_NOR_FLASH) to COMPONENTS in the Makefile
FS_Init() hangs or asserts HW peripheral not initialized Ensure FS_MMC_HW_CM_ConfigureHw() or FS_NOR_HW_SPIFI_ConfigureHw() completes successfully before calling FS_Init()
SD card not detected Card missing or SDHC misconfigured Verify SD card is inserted; confirm SDHC pins are assigned in Device Configurator using the SDHC_EMFILE alias
"Error in low-level formatting" NOR flash device not responding Check SMIF pin assignments and clock frequency in Device Configurator; verify EMFILE_NOR_FLASH is in COMPONENTS
No output on serial terminal Wrong port or baud rate Set terminal to 115200 baud, 8N1; confirm DEBUG_UART alias and UART pins in Device Configurator
RTOS build fails Missing FreeRTOS or RTOS_AWARE Add RTOS_AWARE FREERTOS to COMPONENTS and add the FreeRTOS library via Library Manager

Supported Devices

  • PSoC(TM) Edge E84 MCUs

Release Notes

  • RELEASE.md – Detailed release notes for all versions.

More Information

License

This software is provided under the Infineon End User License Agreement.

  • LICENSE – Infineon End User License Agreement

Copyright

© 2021-2026 Infineon Technologies AG, or an affiliate of Infineon Technologies AG. All rights reserved.

About

SEGGER emFile - A FAT16/32 filesystem for embedded systems supporting SPI NOR flash and SD card.

Resources

License

Contributing

Stars

9 stars

Watchers

13 watching

Forks

Packages

 
 
 

Contributors

Languages