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.
-
SEGGER emFile library v5.22.0
-
Supports FAT 12/16 and FAT 32 file systems
-
COMPONENT
EMFILE_FAT16supports FAT12 and FAT 16 -
COMPONENT
EMFILE_FAT32extends 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
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.
- 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
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.
- Create an empty application using the Project Creator tool in ModusToolbox™ software.
- Add the emfile and retarget-io libraries using the Library Manager.
- To run the example in an RTOS environment, add the FreeRTOS library using the Library Manager. Then add
RTOS_AWAREandFREERTOSto theCOMPONENTSvariable in the Makefile:Note: In the RTOS environment, select Active mode for System Idle Power Mode in the Power personality (System Tab) in the Device Configurator.COMPONENTS += RTOS_AWARE FREERTOS - (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.
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
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
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
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
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 |
Specific steps for NOR flash (SPI flash) driver configuration
- Include the required headers:
#include "mtb_hal_memoryspi.h" #include "cy_sysint.h" #include "cy_smif.h"
- Add global variables:
static mtb_hal_memoryspi_t * memspi_obj_ptr; static cy_stc_smif_context_t memspi_context;
- Add the interrupt handler for NOR flash HW:
void nor_isr(void) { mtb_hal_memoryspi_process_interrupt(memspi_obj_ptr); }
- 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); }
- Add
EMFILE_NOR_FLASHto theCOMPONENTSvariable in the Makefile:COMPONENTS += EMFILE_NOR_FLASH
Specific steps for Memory Card Device (SD/MMC) driver configuration
- Include the required headers:
#include "mtb_hal_sdhc.h" #include "cy_sd_host.h" #include "cy_sysint.h"
- Add global variables:
static mtb_hal_sdhc_t * sdhc_obj_ptr; static cy_stc_sd_host_context_t sdhc_host_context;
- Add the interrupt handler for Memory Card Device HW:
void sd_card_isr(void) { mtb_hal_sdhc_process_interrupt(sdhc_obj_ptr); }
- Add the
Cy_SD_Host_IsCardConnected()function:bool Cy_SD_Host_IsCardConnected(SDHC_Type const *base) { (void) base; return true; }
- 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); }
- Add
EMFILE_SD_CARDto theCOMPONENTSvariable in the Makefile:COMPONENTS += EMFILE_SD_CARD
Common code
- 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) */
- 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)
- 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) */
- 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 */
- 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 (;;) {} }
- 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); } }
- 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 }
- Add the interrupt handler for the user button:
void btn_isr(void) { mtb_hal_gpio_process_interrupt(&button_obj); }
- 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); }
- 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
- 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"); }
- Open a serial terminal. Set the serial port parameters to 8N1 and 115200 baud.
- Build and program the project.
- If the previous steps were correct, logs will appear in the serial terminal.
- 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.
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."
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.
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.
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.
To share the NOR flash between code execution (XIP) and emFile storage:
- Add
ENABLE_XIP_EMFILE_ON_SAME_NOR_FLASHto theDEFINESvariable in the Makefile. - Update the linker script to place
FS_NOR_HW_SPIFI.oandFS_ConfigNOR_BM_SPIFI.oin 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. - Implement the blocking read/write/erase completion functions as shown in
FS_ConfigNOR_BM_SPIFI.c. - 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.
-
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.
| 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 |
- PSoC(TM) Edge E84 MCUs
- RELEASE.md – Detailed release notes for all versions.
This software is provided under the Infineon End User License Agreement.
- LICENSE – Infineon End User License Agreement
© 2021-2026 Infineon Technologies AG, or an affiliate of Infineon Technologies AG. All rights reserved.




