C40 read/write arbitrary bytes

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

C40 read/write arbitrary bytes

508 Views
chenyuhang
Contributor I

Hi nxp techsupport,

I'm now using S32K344's C40 interfaces to fit the littlefs filesystem, but it seems has some problems with C40 driver(Could it be that the C40 interface can only write data of a specified length? I haven't found a solution yet ). It cannot fit C40 drivers. I would like to ask if there is an interface available for reading and writing arbitrary bytes? Or whether there are higher-level function encapsulations that can be called? 

Thank you for your reply!

 

Best regards.

Yuhang Chen

0 Kudos
Reply
5 Replies

480 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi @chenyuhang,

This is what the C40 HW requires (S32K3xx RM rev.11)

danielmartynek_1-1762948969272.png

The C40_Ip driver (C40_Ip_MainInterfaceWrite()) has these checks:

danielmartynek_0-1762948666477.png

 

Regards,

Daniel

Any support, information, and technology (“Materials”) provided by NXP are provided AS IS, without any warranty express or implied, and NXP disclaims all direct and indirect liability and damages in connection with the Material to the maximum extent permitted by the applicable law. 
NXP accepts no liability for any assistance with applications or product design. Materials may only be used in connection with NXP products. Any feedback provided to NXP regarding the Materials may be used by NXP without restriction.

 

0 Kudos
Reply

457 Views
chenyuhang
Contributor I

Hi Daniel,

Thanks for your reply.

I found the C40_Ip_MainInterfaceWritePreCheck() API in C40_Ip.c, and I know write or read c40 has these limits. At present, there are still problems when we transplant littlefs's read/write/erase API to the s32k344. So I would like to ask if there is an API (maybe HAL API) that read or write to any length that can be called ? This will help us transplant littlefs more quickly. If you want to see our transplantation project, I can provide it to you. Thank you so much.

Best Regards,

Chenyuhang

0 Kudos
Reply

433 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi @chenyuhang,

The C40_IP driver is the lowest-level driver we have.

What data length do you intend to write?

  • It cannot be shorter than 8 bytes, as this is a hardware limitation

There is no restriction for reading from flash—use C40_Ip_Read() for that.

What issue are you experiencing with the erase operation?

  • Sector erase is the only option - block Erase does not have the cycling endurance.

danielmartynek_1-1763040581380.png

 

Regards,

Daniel

 

0 Kudos
Reply

406 Views
chenyuhang
Contributor I

Hi Daniel,

As far as i know, c40's 1 page has 32 bytes, It can write up to 128 bytes at most, and read 32 bytes at most. For example, i want to write 200 bytes(maybe more, any bytes more than write once) to fit the LittleFS‘s write API, because filesystem needs to write more than 128 bytes. Here is the code I wrote for adapting the c40 API to LittleFS (refer to <lfs_port.c>). In this code, I want to use the seconde half of DFlash as my filesystem.

<lfs_port.c>

#include "lfs_port.h"
#include "C40_Ip.h"
#include "C40_Ip_Cfg.h"

// Define buffers with aligned attribute to ensure alignment
__attribute__((aligned(8))) static uint8_t m_lfs_read_buf[LFS_READ_SIZE];
__attribute__((aligned(8))) static uint8_t m_lfs_prog_buf[LFS_PROG_SIZE];
__attribute__((aligned(8))) static uint8_t m_lfs_lookahead_buf[LFS_LOOKAHEAD_SIZE];

// Data buffer for intermediate read/write operations (extra space added for alignment and ECC)
__attribute__((aligned(8))) static uint8_t m_lfs_buf[SECTOR_SIZE + 16];

// Define global lfs objects
lfs_t lfs;
lfs_file_t file;

/*
 * @brief Read data from a specific area within a block
 * @Param [in] lfs_config format parameters
 * @Param [in] block Logical block index, starting from 0
 * @Param [in] off Offset within block, must be divisible by read_size
 * @Param [out] Output buffer for read data
 * @Param [in] size Number of bytes to read, must be divisible by read_size, lfs ensures no cross-block reads
 * @retval 0 Success, < 0 Error code
 */

int lfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) {
    C40_Ip_StatusType C40Status;
    uint32_t addr;
    uint8_t *p_src, *p_dst;

    // Validate parameters
    if (block >= c->block_count) {
        logInfo("Read error: Invalid block number %d\n", block);
        return LFS_ERR_IO;
    }

    if (off + size > c->block_size) {
        logInfo("Read error: Out of block bounds\n");
        return LFS_ERR_IO;
    }

    if (buffer == NULL) {
        logInfo("Read error: NULL buffer\n");
        return LFS_ERR_IO;
    }

    // Calculate block start address
    addr = FILESYSTEM_START_ADDRESS + block * c->block_size;

    logInfo("Reading from block %d, offset %d, size %d bytes\n", block, off, size);

    // First read entire sector to intermediate buffer to ensure proper alignment handling
    C40Status = C40_Ip_Read(addr, c->block_size, m_lfs_buf);

    if (C40_IP_STATUS_SUCCESS != C40Status) {
        logInfo("Read operation failed with status %d\n", C40Status);
        return LFS_ERR_IO;
    }

    // Copy required portion from buffer to target buffer
    p_src=(uint8_t*)m_lfs_buf + off;
    p_dst = (uint8_t*)buffer;
    memcpy(p_dst, p_src, size);

    logInfo("Read completed successfully\n");
    return LFS_ERR_OK;
}

/*
 * @brief Write data to a specific area within a block. The area must be erased first, can return LFS_ERR_CORRUPT if block is corrupted
 * @Param [in] lfs_config format parameters
 * @Param [in] block Logical block index, starting from 0
 * @Param [in] off Offset within block, must be divisible by prog_size
 * @Param [in] Buffer containing data to write
 * @Param [in] size Number of bytes to write, must be divisible by read_size, lfs ensures no cross-block writes
 * @retval 0 Success, < 0 Error code
 */
int lfs_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) {
    C40_Ip_StatusType C40Status;
    uint32_t addr;
    uint32_t write_offset = 0;
    const uint32_t MAX_WRITE_CHUNK = 128; // Set a reasonable chunk size limit
    uint8_t *verify_buf = NULL;

    // Validate parameters
    if (block >= c->block_count) {
        logInfo("Program error: Invalid block number %d\n", block);
        return LFS_ERR_IO;
    }

    if (off + size > c->block_size) {
        logInfo("Program error: Out of block bounds\n");
        return LFS_ERR_IO;
    }

    if (buffer == NULL) {
        logInfo("Program error: NULL buffer\n");
        return LFS_ERR_IO;
    }

    // Calculate write address
    addr = FILESYSTEM_START_ADDRESS + block * c->block_size + off;

    // Check address and size alignment requirements (C40 requires 8-byte alignment)
    if ((addr % 8) != 0) {
        logInfo("Program error: Address not aligned to 8 bytes (0x%08X)\n", addr);
        return LFS_ERR_IO;
    }

    if ((size % 8) != 0) {
        logInfo("Program error: Size not aligned to 8 bytes (%d)\n", size);
        return LFS_ERR_IO;
    }

    logInfo("Writing to address 0x%08X, size %d bytes\n", addr, size);

    // Write data in chunks to support writing more than 32 bytes of data
    while (write_offset < size) {
        // Calculate current chunk size
        uint32_t chunk_size = (size - write_offset) > MAX_WRITE_CHUNK ? MAX_WRITE_CHUNK : (size - write_offset);
        uint32_t current_addr = addr + write_offset;
        const uint8_t *current_buffer = (uint8_t*)buffer + write_offset;

        // Ensure chunk_size is a multiple of 8
        chunk_size = (chunk_size + 7) & ~7;

        logInfo("Writing chunk at offset %d, size %d bytes\n", write_offset, chunk_size);

        // Copy data to intermediate buffer
        memset(m_lfs_buf, 0xFF, chunk_size); // Fill with 0xFF first (Flash default state)
        memcpy(m_lfs_buf, current_buffer, chunk_size);

        // Call C40_Ip interface to write data
        C40Status = C40_Ip_MainInterfaceWrite(current_addr, chunk_size, m_lfs_buf, DFLASH_ID);
        if (C40_IP_STATUS_SUCCESS != C40Status) {
            logInfo("Write command failed with status %d\n", C40Status);
            return LFS_ERR_IO;
        }

        // Wait for write operation to complete
        do {
            C40Status = C40_Ip_MainInterfaceWriteStatus();
            if (C40_IP_STATUS_ERROR == C40Status) {
                logInfo("Write operation error\n");
                return LFS_ERR_IO;
            } else if (C40_IP_STATUS_ERROR_TIMEOUT == C40Status) {
                logInfo("Write operation timeout\n");
                return LFS_ERR_IO;
            }
            // Small delay to avoid excessive CPU usage
            for (volatile int i = 0; i < 100; i++);
        } while (C40_IP_STATUS_BUSY == C40Status);

        write_offset += chunk_size;
    }

    // Verify written data (read back and compare)
    verify_buf = (uint8_t*)malloc(size);
    if (verify_buf != NULL) {
        C40Status = C40_Ip_Read(addr, size, verify_buf);
        if (C40_IP_STATUS_SUCCESS == C40Status) {
            if (memcmp(verify_buf, buffer, size) != 0) {
                logInfo("Write verification failed\n");
                free(verify_buf);
                return LFS_ERR_CORRUPT;
            } else {
                logInfo("Write verification successful\n");
            }
        }
        free(verify_buf);
    } else {
        logInfo("Warning: Memory allocation for verification failed\n");
    }

    logInfo("Write completed successfully\n");

    return LFS_ERR_OK;
}

/*
 * @brief Erase specified block. Blocks must be erased before writing, erased block state is undefined
 * @Param [in] lfs_config format parameters
 * @Param [in] block Logical block index to erase, starting from 0
 * @retval 0 Success, < 0 Error code
 */
int lfs_erase(const struct lfs_config *c, lfs_block_t block) {
    C40_Ip_StatusType C40Status;
    C40_Ip_VirtualSectorsType erase_sector;

    // Calculate physical sector number, assuming block 0 corresponds to start of physical sectors
    // Since using half of DFLASH, need to ensure block is within valid range
    if (block >= c->block_count) {
        logInfo("Erase error: Invalid block number %d\n", block);
        return LFS_ERR_IO;
    }

    // Calculate physical sector number, assuming mapping starts from FILESYSTEM_START_ADDRESS
    erase_sector = ((FILESYSTEM_START_ADDRESS - DFLASH_START_ADDRESS) / SECTOR_SIZE) + block;

    logInfo("Erasing block %d (sector %d)...\n", block, erase_sector);

    // First check if sector is locked, if so try to unlock
    C40Status = C40_Ip_GetLock(erase_sector);
    if (C40_IP_STATUS_SECTOR_PROTECTED == C40Status) {
        logInfo("Sector %d is protected, trying to unlock...\n", erase_sector);
        C40Status = C40_Ip_ClearLock(erase_sector, DFLASH_ID);
        if (C40_IP_STATUS_SUCCESS != C40Status) {
            logInfo("Failed to unlock sector %d\n", erase_sector);
            return LFS_ERR_IO;
        }
    } else if (C40_IP_STATUS_ERROR == C40Status) {
        logInfo("Invalid sector %d\n", erase_sector);
        return LFS_ERR_IO;
    }

    // Call C40_Ip interface to erase sector
    C40Status = C40_Ip_MainInterfaceSectorErase(erase_sector, DFLASH_ID);
    if (C40_IP_STATUS_SUCCESS != C40Status) {
        logInfo("Erase command failed with status %d\n", C40Status);
        return LFS_ERR_IO;
    }

    // Wait for erase operation to complete
    do {
        C40Status = C40_Ip_MainInterfaceSectorEraseStatus();
        if (C40_IP_STATUS_ERROR == C40Status) {
            logInfo("Erase operation error\n");
            return LFS_ERR_IO;
        } else if (C40_IP_STATUS_ERROR_TIMEOUT == C40Status) {
            logInfo("Erase operation timeout\n");
            return LFS_ERR_IO;
        }
        // Small delay to avoid excessive CPU usage
        for (volatile int i = 0; i < 100; i++);
    } while (C40_IP_STATUS_BUSY == C40Status);

    logInfo("Block %d erased successfully\n", block);
    return LFS_ERR_OK;
}

/*
 * @brief Perform sync operation on underlying block device. If block device has no sync operation, can return directly
 * @Param [in] lfs_config format parameters;
 * @retval 0 Success, < 0 Error code
 */
int lfs_sync(const struct lfs_config *c)
{
    return LFS_ERR_OK;
}

#if 1

// configuration of the filesystem is provided by this struct
// Define lfs configuration structure
const struct lfs_config cfg = {
    // Block device operation functions
    .read = lfs_read,
    .prog = lfs_prog,
    .erase = lfs_erase,
    .sync = lfs_sync,

    // Block device parameters
    .read_size = LFS_READ_SIZE,
    .prog_size = LFS_PROG_SIZE,
    .block_size = LFS_BLOCK_SIZE,
    .block_count = 4,
    .cache_size = LFS_CACHE_SIZE,
    .lookahead_size = LFS_LOOKAHEAD_SIZE,
    .block_cycles = 500,

    // Add file_max limit to prevent overflow
    .file_max = 32, // Explicitly limit maximum number of files to avoid LittleFS calculating too large values
    .name_max = 31, // Limit maximum filename length
    .attr_max = 32, // Limit maximum attribute value length

    // Buffer references (ensure variable names match exactly)
    .read_buffer = m_lfs_read_buf,
    .prog_buffer = m_lfs_prog_buf,
    .lookahead_buffer = m_lfs_lookahead_buf,

    // Block device context, can be used to pass additional parameters
    .context = NULL,
};

<lfs_port.h>

#ifndef __LFS_PORT_H__
#define __LFS_PORT_H__

#include "lfs.h"
#include "log.h"

#define DFLASH_ID                   (0U)
#define FILESYSTEM_START_ADDRESS    (0x10010000)
#define DFLASH_START_ADDRESS        (0x10000000)

#define SECTOR_SIZE         (8192)
#define SECTOR_COUNT_MAX    (16)

// Define buffer size constants
#define LFS_READ_SIZE       (C40_IP_PAGE_SIZE)
#define LFS_PROG_SIZE       (C40_IP_PAGE_SIZE * 4)
#define LFS_BLOCK_SIZE      (SECTOR_SIZE)
#define LFS_BLOCK_COUNT     (SECTOR_COUNT_MAX)
#define LFS_CACHE_SIZE      (128)
#define LFS_LOOKAHEAD_SIZE  (32)

#endif

Thank you for your reply.

 

Best regards.

Chenyuhang

0 Kudos
Reply

398 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi @chenyuhang,

I see that your lfs_prog() function already splits writes into chunks using MAX_WRITE_CHUNK = 128. It loops until all data is written, aligning each chunk to 8 bytes (required by C40).

This is correct. 

I really don't see the problem you are describing.

Can you maybe elaborate?

 

Thank you,

Daniel

 

 

0 Kudos
Reply
%3CLINGO-SUB%20id%3D%22lingo-sub-2203447%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3EC40%20read%2Fwrite%20arbitrary%20bytes%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2203447%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3EHi%20nxp%20techsupport%2C%3C%2FP%3E%3CP%3EI'm%20now%20using%20S32K344's%20C40%20interfaces%20to%20fit%20the%20littlefs%20filesystem%2C%20but%20it%20seems%20has%20some%20problems%20with%20C40%20driver(%3CSPAN%3ECould%20it%20be%20that%20the%20C40%20interface%20can%20only%20write%20data%20of%20a%20specified%20length%3F%26nbsp%3BI%20haven't%20found%20a%20solution%20yet%26nbsp%3B%3C%2FSPAN%3E).%20It%20cannot%20fit%20C40%20drivers.%20%3CSPAN%3EI%20would%20like%20to%20ask%20if%20there%20is%20an%20interface%20available%20for%20reading%20and%20writing%20arbitrary%20bytes%3F%20Or%20whether%20there%20are%20higher-level%20function%20encapsulations%20that%20can%20be%20called%3F%26nbsp%3B%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%3CSPAN%3EThank%20you%20for%20your%20reply!%3C%2FSPAN%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CSPAN%3EBest%20regards.%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%3CSPAN%3EYuhang%20Chen%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2205182%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%20translate%3D%22no%22%3ERe%3A%20C40%20read%2Fwrite%20arbitrary%20bytes%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2205182%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3EHi%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F253659%22%20target%3D%22_blank%22%3E%40chenyuhang%3C%2FA%3E%2C%3C%2FP%3E%0A%3CP%3EI%20see%20that%20your%20lfs_prog()%20function%20already%20splits%20writes%20into%20chunks%20using%20MAX_WRITE_CHUNK%20%3D%20128.%26nbsp%3BIt%20loops%20until%20all%20data%20is%20written%2C%20aligning%20each%20chunk%20to%208%20bytes%20(required%20by%20C40).%3C%2FP%3E%0A%3CP%3EThis%20is%20correct.%26nbsp%3B%3C%2FP%3E%0A%3CP%3EI%20really%20don't%20see%20the%20problem%20you%20are%20describing.%3C%2FP%3E%0A%3CP%3ECan%20you%20maybe%20elaborate%3F%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3EThank%20you%2C%3C%2FP%3E%0A%3CP%3EDaniel%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CBR%20%2F%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2205031%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%20translate%3D%22no%22%3ERe%3A%20C40%20read%2Fwrite%20arbitrary%20bytes%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2205031%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3EHi%20Daniel%2C%3C%2FP%3E%3CP%3EAs%20far%20as%20i%20know%2C%20c40's%201%20page%20has%2032%20bytes%2C%20%3CSPAN%3EIt%20can%20write%20up%20to%20128%20bytes%20at%20most%2C%20and%20read%2032%20bytes%20at%20most.%20For%20example%2C%20i%20want%20to%20write%20200%20bytes(maybe%20more%2C%20any%20bytes%20more%20than%20write%20once)%20to%20fit%20the%20LittleFS%E2%80%98s%20write%20API%2C%20because%20filesystem%20needs%20to%20write%20more%20than%20128%20bytes.%20Here%20is%26nbsp%3Bthe%20code%20I%20wrote%20for%20adapting%20the%20c40%20API%20to%20LittleFS%20(refer%20to%20%3CLFS_PORT.C%3E).%20In%20this%20code%2C%20I%20want%20to%20use%20the%20seconde%20half%20of%20DFlash%20as%20my%20filesystem.%3C%2FLFS_PORT.C%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%3CSPAN%3E%3CLFS_PORT.C%3E%3C%2FLFS_PORT.C%3E%3C%2FSPAN%3E%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-c%22%3E%3CCODE%3E%23include%20%22lfs_port.h%22%0A%23include%20%22C40_Ip.h%22%0A%23include%20%22C40_Ip_Cfg.h%22%0A%0A%2F%2F%20Define%20buffers%20with%20aligned%20attribute%20to%20ensure%20alignment%0A__attribute__((aligned(8)))%20static%20uint8_t%20m_lfs_read_buf%5BLFS_READ_SIZE%5D%3B%0A__attribute__((aligned(8)))%20static%20uint8_t%20m_lfs_prog_buf%5BLFS_PROG_SIZE%5D%3B%0A__attribute__((aligned(8)))%20static%20uint8_t%20m_lfs_lookahead_buf%5BLFS_LOOKAHEAD_SIZE%5D%3B%0A%0A%2F%2F%20Data%20buffer%20for%20intermediate%20read%2Fwrite%20operations%20(extra%20space%20added%20for%20alignment%20and%20ECC)%0A__attribute__((aligned(8)))%20static%20uint8_t%20m_lfs_buf%5BSECTOR_SIZE%20%2B%2016%5D%3B%0A%0A%2F%2F%20Define%20global%20lfs%20objects%0Alfs_t%20lfs%3B%0Alfs_file_t%20file%3B%0A%0A%2F*%0A%20*%20%40brief%20Read%20data%20from%20a%20specific%20area%20within%20a%20block%0A%20*%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20%5Bin%5D%20lfs_config%20format%20parameters%0A%20*%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20%5Bin%5D%20block%20Logical%20block%20index%2C%20starting%20from%200%0A%20*%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20%5Bin%5D%20off%20Offset%20within%20block%2C%20must%20be%20divisible%20by%20read_size%0A%20*%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20%5Bout%5D%20Output%20buffer%20for%20read%20data%0A%20*%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20%5Bin%5D%20size%20Number%20of%20bytes%20to%20read%2C%20must%20be%20divisible%20by%20read_size%2C%20lfs%20ensures%20no%20cross-block%20reads%0A%20*%20%40retval%200%20Success%2C%20%26lt%3B%200%20Error%20code%0A%20*%2F%0A%0Aint%20lfs_read(const%20struct%20lfs_config%20*c%2C%20lfs_block_t%20block%2C%20lfs_off_t%20off%2C%20void%20*buffer%2C%20lfs_size_t%20size)%20%7B%0A%20%20%20%20C40_Ip_StatusType%20C40Status%3B%0A%20%20%20%20uint32_t%20addr%3B%0A%20%20%20%20uint8_t%20*p_src%2C%20*p_dst%3B%0A%0A%20%20%20%20%2F%2F%20Validate%20parameters%0A%20%20%20%20if%20(block%20%26gt%3B%3D%20c-%26gt%3Bblock_count)%20%7B%0A%20%20%20%20%20%20%20%20logInfo(%22Read%20error%3A%20Invalid%20block%20number%20%25d%5Cn%22%2C%20block)%3B%0A%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20(off%20%2B%20size%20%26gt%3B%20c-%26gt%3Bblock_size)%20%7B%0A%20%20%20%20%20%20%20%20logInfo(%22Read%20error%3A%20Out%20of%20block%20bounds%5Cn%22)%3B%0A%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20(buffer%20%3D%3D%20NULL)%20%7B%0A%20%20%20%20%20%20%20%20logInfo(%22Read%20error%3A%20NULL%20buffer%5Cn%22)%3B%0A%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Calculate%20block%20start%20address%0A%20%20%20%20addr%20%3D%20FILESYSTEM_START_ADDRESS%20%2B%20block%20*%20c-%26gt%3Bblock_size%3B%0A%0A%20%20%20%20logInfo(%22Reading%20from%20block%20%25d%2C%20offset%20%25d%2C%20size%20%25d%20bytes%5Cn%22%2C%20block%2C%20off%2C%20size)%3B%0A%0A%20%20%20%20%2F%2F%20First%20read%20entire%20sector%20to%20intermediate%20buffer%20to%20ensure%20proper%20alignment%20handling%0A%20%20%20%20C40Status%20%3D%20C40_Ip_Read(addr%2C%20c-%26gt%3Bblock_size%2C%20m_lfs_buf)%3B%0A%0A%20%20%20%20if%20(C40_IP_STATUS_SUCCESS%20!%3D%20C40Status)%20%7B%0A%20%20%20%20%20%20%20%20logInfo(%22Read%20operation%20failed%20with%20status%20%25d%5Cn%22%2C%20C40Status)%3B%0A%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Copy%20required%20portion%20from%20buffer%20to%20target%20buffer%0A%20%20%20%20p_src%3D(uint8_t*)m_lfs_buf%20%2B%20off%3B%0A%20%20%20%20p_dst%20%3D%20(uint8_t*)buffer%3B%0A%20%20%20%20memcpy(p_dst%2C%20p_src%2C%20size)%3B%0A%0A%20%20%20%20logInfo(%22Read%20completed%20successfully%5Cn%22)%3B%0A%20%20%20%20return%20LFS_ERR_OK%3B%0A%7D%0A%0A%2F*%0A%20*%20%40brief%20Write%20data%20to%20a%20specific%20area%20within%20a%20block.%20The%20area%20must%20be%20erased%20first%2C%20can%20return%20LFS_ERR_CORRUPT%20if%20block%20is%20corrupted%0A%20*%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20%5Bin%5D%20lfs_config%20format%20parameters%0A%20*%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20%5Bin%5D%20block%20Logical%20block%20index%2C%20starting%20from%200%0A%20*%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20%5Bin%5D%20off%20Offset%20within%20block%2C%20must%20be%20divisible%20by%20prog_size%0A%20*%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20%5Bin%5D%20Buffer%20containing%20data%20to%20write%0A%20*%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20%5Bin%5D%20size%20Number%20of%20bytes%20to%20write%2C%20must%20be%20divisible%20by%20read_size%2C%20lfs%20ensures%20no%20cross-block%20writes%0A%20*%20%40retval%200%20Success%2C%20%26lt%3B%200%20Error%20code%0A%20*%2F%0Aint%20lfs_prog(const%20struct%20lfs_config%20*c%2C%20lfs_block_t%20block%2C%20lfs_off_t%20off%2C%20const%20void%20*buffer%2C%20lfs_size_t%20size)%20%7B%0A%20%20%20%20C40_Ip_StatusType%20C40Status%3B%0A%20%20%20%20uint32_t%20addr%3B%0A%20%20%20%20uint32_t%20write_offset%20%3D%200%3B%0A%20%20%20%20const%20uint32_t%20MAX_WRITE_CHUNK%20%3D%20128%3B%20%2F%2F%20Set%20a%20reasonable%20chunk%20size%20limit%0A%20%20%20%20uint8_t%20*verify_buf%20%3D%20NULL%3B%0A%0A%20%20%20%20%2F%2F%20Validate%20parameters%0A%20%20%20%20if%20(block%20%26gt%3B%3D%20c-%26gt%3Bblock_count)%20%7B%0A%20%20%20%20%20%20%20%20logInfo(%22Program%20error%3A%20Invalid%20block%20number%20%25d%5Cn%22%2C%20block)%3B%0A%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20(off%20%2B%20size%20%26gt%3B%20c-%26gt%3Bblock_size)%20%7B%0A%20%20%20%20%20%20%20%20logInfo(%22Program%20error%3A%20Out%20of%20block%20bounds%5Cn%22)%3B%0A%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20(buffer%20%3D%3D%20NULL)%20%7B%0A%20%20%20%20%20%20%20%20logInfo(%22Program%20error%3A%20NULL%20buffer%5Cn%22)%3B%0A%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Calculate%20write%20address%0A%20%20%20%20addr%20%3D%20FILESYSTEM_START_ADDRESS%20%2B%20block%20*%20c-%26gt%3Bblock_size%20%2B%20off%3B%0A%0A%20%20%20%20%2F%2F%20Check%20address%20and%20size%20alignment%20requirements%20(C40%20requires%208-byte%20alignment)%0A%20%20%20%20if%20((addr%20%25%208)%20!%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20logInfo(%22Program%20error%3A%20Address%20not%20aligned%20to%208%20bytes%20(0x%2508X)%5Cn%22%2C%20addr)%3B%0A%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20((size%20%25%208)%20!%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20logInfo(%22Program%20error%3A%20Size%20not%20aligned%20to%208%20bytes%20(%25d)%5Cn%22%2C%20size)%3B%0A%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20logInfo(%22Writing%20to%20address%200x%2508X%2C%20size%20%25d%20bytes%5Cn%22%2C%20addr%2C%20size)%3B%0A%0A%20%20%20%20%2F%2F%20Write%20data%20in%20chunks%20to%20support%20writing%20more%20than%2032%20bytes%20of%20data%0A%20%20%20%20while%20(write_offset%20%26lt%3B%20size)%20%7B%0A%20%20%20%20%20%20%20%20%2F%2F%20Calculate%20current%20chunk%20size%0A%20%20%20%20%20%20%20%20uint32_t%20chunk_size%20%3D%20(size%20-%20write_offset)%20%26gt%3B%20MAX_WRITE_CHUNK%20%3F%20MAX_WRITE_CHUNK%20%3A%20(size%20-%20write_offset)%3B%0A%20%20%20%20%20%20%20%20uint32_t%20current_addr%20%3D%20addr%20%2B%20write_offset%3B%0A%20%20%20%20%20%20%20%20const%20uint8_t%20*current_buffer%20%3D%20(uint8_t*)buffer%20%2B%20write_offset%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Ensure%20chunk_size%20is%20a%20multiple%20of%208%0A%20%20%20%20%20%20%20%20chunk_size%20%3D%20(chunk_size%20%2B%207)%20%26amp%3B%20~7%3B%0A%0A%20%20%20%20%20%20%20%20logInfo(%22Writing%20chunk%20at%20offset%20%25d%2C%20size%20%25d%20bytes%5Cn%22%2C%20write_offset%2C%20chunk_size)%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Copy%20data%20to%20intermediate%20buffer%0A%20%20%20%20%20%20%20%20memset(m_lfs_buf%2C%200xFF%2C%20chunk_size)%3B%20%2F%2F%20Fill%20with%200xFF%20first%20(Flash%20default%20state)%0A%20%20%20%20%20%20%20%20memcpy(m_lfs_buf%2C%20current_buffer%2C%20chunk_size)%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Call%20C40_Ip%20interface%20to%20write%20data%0A%20%20%20%20%20%20%20%20C40Status%20%3D%20C40_Ip_MainInterfaceWrite(current_addr%2C%20chunk_size%2C%20m_lfs_buf%2C%20DFLASH_ID)%3B%0A%20%20%20%20%20%20%20%20if%20(C40_IP_STATUS_SUCCESS%20!%3D%20C40Status)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20logInfo(%22Write%20command%20failed%20with%20status%20%25d%5Cn%22%2C%20C40Status)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Wait%20for%20write%20operation%20to%20complete%0A%20%20%20%20%20%20%20%20do%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20C40Status%20%3D%20C40_Ip_MainInterfaceWriteStatus()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(C40_IP_STATUS_ERROR%20%3D%3D%20C40Status)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20logInfo(%22Write%20operation%20error%5Cn%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(C40_IP_STATUS_ERROR_TIMEOUT%20%3D%3D%20C40Status)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20logInfo(%22Write%20operation%20timeout%5Cn%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Small%20delay%20to%20avoid%20excessive%20CPU%20usage%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(volatile%20int%20i%20%3D%200%3B%20i%20%26lt%3B%20100%3B%20i%2B%2B)%3B%0A%20%20%20%20%20%20%20%20%7D%20while%20(C40_IP_STATUS_BUSY%20%3D%3D%20C40Status)%3B%0A%0A%20%20%20%20%20%20%20%20write_offset%20%2B%3D%20chunk_size%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Verify%20written%20data%20(read%20back%20and%20compare)%0A%20%20%20%20verify_buf%20%3D%20(uint8_t*)malloc(size)%3B%0A%20%20%20%20if%20(verify_buf%20!%3D%20NULL)%20%7B%0A%20%20%20%20%20%20%20%20C40Status%20%3D%20C40_Ip_Read(addr%2C%20size%2C%20verify_buf)%3B%0A%20%20%20%20%20%20%20%20if%20(C40_IP_STATUS_SUCCESS%20%3D%3D%20C40Status)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(memcmp(verify_buf%2C%20buffer%2C%20size)%20!%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20logInfo(%22Write%20verification%20failed%5Cn%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20free(verify_buf)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20LFS_ERR_CORRUPT%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20logInfo(%22Write%20verification%20successful%5Cn%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20free(verify_buf)%3B%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20logInfo(%22Warning%3A%20Memory%20allocation%20for%20verification%20failed%5Cn%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20logInfo(%22Write%20completed%20successfully%5Cn%22)%3B%0A%0A%20%20%20%20return%20LFS_ERR_OK%3B%0A%7D%0A%0A%2F*%0A%20*%20%40brief%20Erase%20specified%20block.%20Blocks%20must%20be%20erased%20before%20writing%2C%20erased%20block%20state%20is%20undefined%0A%20*%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20%5Bin%5D%20lfs_config%20format%20parameters%0A%20*%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20%5Bin%5D%20block%20Logical%20block%20index%20to%20erase%2C%20starting%20from%200%0A%20*%20%40retval%200%20Success%2C%20%26lt%3B%200%20Error%20code%0A%20*%2F%0Aint%20lfs_erase(const%20struct%20lfs_config%20*c%2C%20lfs_block_t%20block)%20%7B%0A%20%20%20%20C40_Ip_StatusType%20C40Status%3B%0A%20%20%20%20C40_Ip_VirtualSectorsType%20erase_sector%3B%0A%0A%20%20%20%20%2F%2F%20Calculate%20physical%20sector%20number%2C%20assuming%20block%200%20corresponds%20to%20start%20of%20physical%20sectors%0A%20%20%20%20%2F%2F%20Since%20using%20half%20of%20DFLASH%2C%20need%20to%20ensure%20block%20is%20within%20valid%20range%0A%20%20%20%20if%20(block%20%26gt%3B%3D%20c-%26gt%3Bblock_count)%20%7B%0A%20%20%20%20%20%20%20%20logInfo(%22Erase%20error%3A%20Invalid%20block%20number%20%25d%5Cn%22%2C%20block)%3B%0A%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Calculate%20physical%20sector%20number%2C%20assuming%20mapping%20starts%20from%20FILESYSTEM_START_ADDRESS%0A%20%20%20%20erase_sector%20%3D%20((FILESYSTEM_START_ADDRESS%20-%20DFLASH_START_ADDRESS)%20%2F%20SECTOR_SIZE)%20%2B%20block%3B%0A%0A%20%20%20%20logInfo(%22Erasing%20block%20%25d%20(sector%20%25d)...%5Cn%22%2C%20block%2C%20erase_sector)%3B%0A%0A%20%20%20%20%2F%2F%20First%20check%20if%20sector%20is%20locked%2C%20if%20so%20try%20to%20unlock%0A%20%20%20%20C40Status%20%3D%20C40_Ip_GetLock(erase_sector)%3B%0A%20%20%20%20if%20(C40_IP_STATUS_SECTOR_PROTECTED%20%3D%3D%20C40Status)%20%7B%0A%20%20%20%20%20%20%20%20logInfo(%22Sector%20%25d%20is%20protected%2C%20trying%20to%20unlock...%5Cn%22%2C%20erase_sector)%3B%0A%20%20%20%20%20%20%20%20C40Status%20%3D%20C40_Ip_ClearLock(erase_sector%2C%20DFLASH_ID)%3B%0A%20%20%20%20%20%20%20%20if%20(C40_IP_STATUS_SUCCESS%20!%3D%20C40Status)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20logInfo(%22Failed%20to%20unlock%20sector%20%25d%5Cn%22%2C%20erase_sector)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%20else%20if%20(C40_IP_STATUS_ERROR%20%3D%3D%20C40Status)%20%7B%0A%20%20%20%20%20%20%20%20logInfo(%22Invalid%20sector%20%25d%5Cn%22%2C%20erase_sector)%3B%0A%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Call%20C40_Ip%20interface%20to%20erase%20sector%0A%20%20%20%20C40Status%20%3D%20C40_Ip_MainInterfaceSectorErase(erase_sector%2C%20DFLASH_ID)%3B%0A%20%20%20%20if%20(C40_IP_STATUS_SUCCESS%20!%3D%20C40Status)%20%7B%0A%20%20%20%20%20%20%20%20logInfo(%22Erase%20command%20failed%20with%20status%20%25d%5Cn%22%2C%20C40Status)%3B%0A%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Wait%20for%20erase%20operation%20to%20complete%0A%20%20%20%20do%20%7B%0A%20%20%20%20%20%20%20%20C40Status%20%3D%20C40_Ip_MainInterfaceSectorEraseStatus()%3B%0A%20%20%20%20%20%20%20%20if%20(C40_IP_STATUS_ERROR%20%3D%3D%20C40Status)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20logInfo(%22Erase%20operation%20error%5Cn%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(C40_IP_STATUS_ERROR_TIMEOUT%20%3D%3D%20C40Status)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20logInfo(%22Erase%20operation%20timeout%5Cn%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20LFS_ERR_IO%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%2F%2F%20Small%20delay%20to%20avoid%20excessive%20CPU%20usage%0A%20%20%20%20%20%20%20%20for%20(volatile%20int%20i%20%3D%200%3B%20i%20%26lt%3B%20100%3B%20i%2B%2B)%3B%0A%20%20%20%20%7D%20while%20(C40_IP_STATUS_BUSY%20%3D%3D%20C40Status)%3B%0A%0A%20%20%20%20logInfo(%22Block%20%25d%20erased%20successfully%5Cn%22%2C%20block)%3B%0A%20%20%20%20return%20LFS_ERR_OK%3B%0A%7D%0A%0A%2F*%0A%20*%20%40brief%20Perform%20sync%20operation%20on%20underlying%20block%20device.%20If%20block%20device%20has%20no%20sync%20operation%2C%20can%20return%20directly%0A%20*%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20%5Bin%5D%20lfs_config%20format%20parameters%3B%0A%20*%20%40retval%200%20Success%2C%20%26lt%3B%200%20Error%20code%0A%20*%2F%0Aint%20lfs_sync(const%20struct%20lfs_config%20*c)%0A%7B%0A%20%20%20%20return%20LFS_ERR_OK%3B%0A%7D%0A%0A%23if%201%0A%0A%2F%2F%20configuration%20of%20the%20filesystem%20is%20provided%20by%20this%20struct%0A%2F%2F%20Define%20lfs%20configuration%20structure%0Aconst%20struct%20lfs_config%20cfg%20%3D%20%7B%0A%20%20%20%20%2F%2F%20Block%20device%20operation%20functions%0A%20%20%20%20.read%20%3D%20lfs_read%2C%0A%20%20%20%20.prog%20%3D%20lfs_prog%2C%0A%20%20%20%20.erase%20%3D%20lfs_erase%2C%0A%20%20%20%20.sync%20%3D%20lfs_sync%2C%0A%0A%20%20%20%20%2F%2F%20Block%20device%20parameters%0A%20%20%20%20.read_size%20%3D%20LFS_READ_SIZE%2C%0A%20%20%20%20.prog_size%20%3D%20LFS_PROG_SIZE%2C%0A%20%20%20%20.block_size%20%3D%20LFS_BLOCK_SIZE%2C%0A%20%20%20%20.block_count%20%3D%204%2C%0A%20%20%20%20.cache_size%20%3D%20LFS_CACHE_SIZE%2C%0A%20%20%20%20.lookahead_size%20%3D%20LFS_LOOKAHEAD_SIZE%2C%0A%20%20%20%20.block_cycles%20%3D%20500%2C%0A%0A%20%20%20%20%2F%2F%20Add%20file_max%20limit%20to%20prevent%20overflow%0A%20%20%20%20.file_max%20%3D%2032%2C%20%2F%2F%20Explicitly%20limit%20maximum%20number%20of%20files%20to%20avoid%20LittleFS%20calculating%20too%20large%20values%0A%20%20%20%20.name_max%20%3D%2031%2C%20%2F%2F%20Limit%20maximum%20filename%20length%0A%20%20%20%20.attr_max%20%3D%2032%2C%20%2F%2F%20Limit%20maximum%20attribute%20value%20length%0A%0A%20%20%20%20%2F%2F%20Buffer%20references%20(ensure%20variable%20names%20match%20exactly)%0A%20%20%20%20.read_buffer%20%3D%20m_lfs_read_buf%2C%0A%20%20%20%20.prog_buffer%20%3D%20m_lfs_prog_buf%2C%0A%20%20%20%20.lookahead_buffer%20%3D%20m_lfs_lookahead_buf%2C%0A%0A%20%20%20%20%2F%2F%20Block%20device%20context%2C%20can%20be%20used%20to%20pass%20additional%20parameters%0A%20%20%20%20.context%20%3D%20NULL%2C%0A%7D%3B%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%3CSPAN%3E%3CLFS_PORT.H%3E%3C%2FLFS_PORT.H%3E%3C%2FSPAN%3E%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-c%22%3E%3CCODE%3E%23ifndef%20__LFS_PORT_H__%0A%23define%20__LFS_PORT_H__%0A%0A%23include%20%22lfs.h%22%0A%23include%20%22log.h%22%0A%0A%23define%20DFLASH_ID%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(0U)%0A%23define%20FILESYSTEM_START_ADDRESS%20%20%20%20(0x10010000)%0A%23define%20DFLASH_START_ADDRESS%20%20%20%20%20%20%20%20(0x10000000)%0A%0A%23define%20SECTOR_SIZE%20%20%20%20%20%20%20%20%20(8192)%0A%23define%20SECTOR_COUNT_MAX%20%20%20%20(16)%0A%0A%2F%2F%20Define%20buffer%20size%20constants%0A%23define%20LFS_READ_SIZE%20%20%20%20%20%20%20(C40_IP_PAGE_SIZE)%0A%23define%20LFS_PROG_SIZE%20%20%20%20%20%20%20(C40_IP_PAGE_SIZE%20*%204)%0A%23define%20LFS_BLOCK_SIZE%20%20%20%20%20%20(SECTOR_SIZE)%0A%23define%20LFS_BLOCK_COUNT%20%20%20%20%20(SECTOR_COUNT_MAX)%0A%23define%20LFS_CACHE_SIZE%20%20%20%20%20%20(128)%0A%23define%20LFS_LOOKAHEAD_SIZE%20%20(32)%0A%0A%23endif%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%3CSPAN%3EThank%20you%20for%20your%20reply.%3C%2FSPAN%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CSPAN%3EBest%20regards.%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%3CSPAN%3EChenyuhang%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2204528%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%20translate%3D%22no%22%3ERe%3A%20C40%20read%2Fwrite%20arbitrary%20bytes%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2204528%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3EHi%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F253659%22%20target%3D%22_blank%22%3E%40chenyuhang%3C%2FA%3E%2C%3C%2FP%3E%0A%3CP%3EThe%20C40_IP%20driver%20is%20the%20lowest-level%20driver%20we%20have.%3C%2FP%3E%0A%3CP%3EWhat%20data%20length%20do%20you%20intend%20to%20write%3F%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3EIt%20cannot%20be%20shorter%20than%208%20bytes%2C%20as%20this%20is%20a%20hardware%20limitation%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3EThere%20is%20no%20restriction%20for%20reading%20from%20flash%E2%80%94use%20C40_Ip_Read()%20for%20that.%3C%2FP%3E%0A%3CP%3EWhat%20issue%20are%20you%20experiencing%20with%20the%20erase%20operation%3F%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3ESector%20erase%20is%20the%20only%20option%20-%20block%20Erase%20does%20not%20have%20the%20cycling%20endurance.%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22danielmartynek_1-1763040581380.png%22%20style%3D%22width%3A%20720px%3B%22%3E%3Cspan%20class%3D%22lia-inline-image-display-wrapper%22%20image-alt%3D%22danielmartynek_1-1763040581380.png%22%20style%3D%22width%3A%20720px%3B%22%3E%3Cimg%20src%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F365549i27115F2A03961215%2Fimage-dimensions%2F720x323%3Fv%3Dv2%22%20width%3D%22720%22%20height%3D%22323%22%20role%3D%22button%22%20title%3D%22danielmartynek_1-1763040581380.png%22%20alt%3D%22danielmartynek_1-1763040581380.png%22%20%2F%3E%3C%2Fspan%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3ERegards%2C%3C%2FP%3E%0A%3CP%3EDaniel%3C%2FP%3E%0A%3CBR%20%2F%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2203997%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%20translate%3D%22no%22%3ERe%3A%20C40%20read%2Fwrite%20arbitrary%20bytes%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2203997%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3EHi%20Daniel%2C%3C%2FP%3E%3CP%3EThanks%20for%20your%20reply.%3C%2FP%3E%3CP%3EI%20found%20the%20%3CSPAN%3EC40_Ip_MainInterfaceWritePreCheck()%20API%20in%20C40_Ip.c%2C%20and%20I%20know%20write%20or%20read%20c40%20has%20these%20limits.%26nbsp%3BAt%20present%2C%20there%20are%20still%20problems%20when%20we%20transplant%20littlefs's%20read%2Fwrite%2Ferase%20API%20to%20the%20s32k344.%20So%26nbsp%3BI%20would%20like%20to%20ask%20if%20there%20is%20an%20API%20(maybe%20HAL%20API)%20that%26nbsp%3Bread%20or%20write%20to%20any%20length%20that%20can%20be%20called%20%3F%20This%20will%20help%20us%20transplant%20littlefs%20more%20quickly.%20If%20you%20want%20to%20see%20our%20transplantation%20project%2C%20I%20can%20provide%20it%20to%20you.%20Thank%20you%20so%20much.%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%3CSPAN%3EBest%20Regards%2C%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%3CSPAN%3EChenyuhang%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2203605%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%20translate%3D%22no%22%3ERe%3A%20C40%20read%2Fwrite%20arbitrary%20bytes%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2203605%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3EHi%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F253659%22%20target%3D%22_blank%22%3E%40chenyuhang%3C%2FA%3E%2C%3C%2FP%3E%0A%3CP%3EThis%20is%20what%20the%20C40%20HW%20requires%20(S32K3xx%20RM%20rev.11)%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22danielmartynek_1-1762948969272.png%22%20style%3D%22width%3A%20780px%3B%22%3E%3Cspan%20class%3D%22lia-inline-image-display-wrapper%22%20image-alt%3D%22danielmartynek_1-1762948969272.png%22%20style%3D%22width%3A%20780px%3B%22%3E%3Cimg%20src%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F365244i2092F71D18EDBBD7%2Fimage-dimensions%2F780x195%3Fv%3Dv2%22%20width%3D%22780%22%20height%3D%22195%22%20role%3D%22button%22%20title%3D%22danielmartynek_1-1762948969272.png%22%20alt%3D%22danielmartynek_1-1762948969272.png%22%20%2F%3E%3C%2Fspan%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3EThe%20C40_Ip%20driver%20(C40_Ip_MainInterfaceWrite())%20has%20these%20checks%3A%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22danielmartynek_0-1762948666477.png%22%20style%3D%22width%3A%20948px%3B%22%3E%3Cspan%20class%3D%22lia-inline-image-display-wrapper%22%20image-alt%3D%22danielmartynek_0-1762948666477.png%22%20style%3D%22width%3A%20948px%3B%22%3E%3Cimg%20src%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F365241i1808182D569D9C02%2Fimage-dimensions%2F948x549%3Fv%3Dv2%22%20width%3D%22948%22%20height%3D%22549%22%20role%3D%22button%22%20title%3D%22danielmartynek_0-1762948666477.png%22%20alt%3D%22danielmartynek_0-1762948666477.png%22%20%2F%3E%3C%2Fspan%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3ERegards%2C%3C%2FP%3E%0A%3CP%3EDaniel%3C%2FP%3E%0A%3CPRE%3EAny%20support%2C%20information%2C%20and%20technology%20(%E2%80%9CMaterials%E2%80%9D)%20provided%20by%20NXP%20are%20provided%20AS%20IS%2C%20without%20any%20warranty%20express%20or%20implied%2C%20and%20NXP%20disclaims%20all%20direct%20and%20indirect%20liability%20and%20damages%20in%20connection%20with%20the%20Material%20to%20the%20maximum%20extent%20permitted%20by%20the%20applicable%20law.%20%3CBR%20%2F%3ENXP%20accepts%20no%20liability%20for%20any%20assistance%20with%20applications%20or%20product%20design.%20Materials%20may%20only%20be%20used%20in%20connection%20with%20NXP%20products.%20Any%20feedback%20provided%20to%20NXP%20regarding%20the%20Materials%20may%20be%20used%20by%20NXP%20without%20restriction.%3C%2FPRE%3E%0A%3CBR%20%2F%3E%3C%2FLINGO-BODY%3E