Hello community,
I am seeking assistance with integrating littlefs with the LPCxpresso55S16. I have encountered several difficulties due to the lack of documentation regarding the flash memory characteristics of the LPCXpresso55S16.
I have created the following functions and attempted to assign them to the lfs_config struct for initialization. However, I suspect that the other struct members I defined might be incorrect.
Currently, when executing the lfs_mount function, it calls the lfs_rawmount, and I receive LFS_ERR_CORRUPT during the execution of lfs_dir_fetchmatch. Upon investigation, I believe this error is related to corruption in the directory pair, as the pair[0] and pair[1] values of the dir variable are both 0 before executing this function.
Could someone assist me in mounting littlefs on the LPCXpresso55S16?
Here is the code:
********Created function *********
flash_config_t flashInstance;
void InitilizeFlashInstance(flash_config_t* flashInstance){
// Set all the flashInstance parameters to 0
static uint32_t status;
// Starting intializing the flashInstance
status = FLASH_Init(flashInstance);
if (status == kStatus_Success)
{
PRINTF("Flash init successfull!!. Halting...\r\n");
}
}
int ReadDataFromFlash(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size)
{
// initialize the status :
status_t result;
// Calculate the start address based on block and offset
uint32_t startAddress = (block * c->block_size) + off;
/* Check if the flash page is blank before reading to avoid hardfault. */
result = FLASH_VerifyErase(&flashInstance, startAddress, c->block_size);
if (result == kStatus_Success)
{
PRINTF("verified erasable block");
}
// Call FLASH_Read function to read data from flash
result = FLASH_Read(&flashInstance, startAddress, (uint8_t *)buffer, size);
if (result == kStatus_Success) {
return LFS_ERR_OK; // Return 0 on success
} else {
return LFS_ERR_CORRUPT; // Return -1 on failure (or handle error as per your application's logic)
}
}
int ProgDataToFlash(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size)
{
uint32_t failedAddress, failedData;
// initialize the status :
status_t result;
// Calculate the start address based on block and offset
uint32_t startAddress = (block * c->block_size) + off;
// Call FLASH_Read function to read data from flash
result = FLASH_Program(&flashInstance, startAddress, (uint8_t *)buffer, size);
if (result == kStatus_Success) {
/* Verify if the given flash region is successfully programmed with given data */
result = FLASH_VerifyProgram(&flashInstance, startAddress, sizeof(buffer), (const uint8_t *)buffer, &failedAddress,
&failedData);
if (result == kStatus_Success)
{
return LFS_ERR_OK;
}
else
{
return LFS_ERR_CORRUPT;
}
}//Return 0 on success
return LFS_ERR_CORRUPT;
}
int EraseDataFromFlash(const struct lfs_config *c, lfs_block_t block)
{
// Calculate the start address based on block
uint32_t startAddress = block * c->block_size ;
status_t result;
result = FLASH_Erase(&flashInstance, startAddress, c->block_size, kFLASH_ApiEraseKey);
if (result == kStatus_Success)
{
result = FLASH_VerifyErase(&flashInstance, startAddress, c->block_size);
if (result == kStatus_Success)
{
PRINTF("FLASH Verify erase successful!\n");
}
return LFS_ERR_OK;
}
else
{
return LFS_ERR_CORRUPT;
}
}
int SyncFlash(const struct lfs_config *c){
return LFS_ERR_OK;
};
int LockFlash(const struct lfs_config *c){
return LFS_ERR_OK;
};
int UnlockFlash(const struct lfs_config *c){
return LFS_ERR_OK;
};
*************** lfs_config initialization *******
// variables used by the filesystem
lfs_t lfs;
lfs_file_t file;
// configuration of the filesystem is provided by this struct
const struct lfs_config cfg = {
// block device operations
.read = ReadDataFromFlash,
.prog = ProgDataToFlash,
.erase = EraseDataFromFlash,
.sync = SyncFlash,
.lock = LockFlash,
.unlock = UnlockFlash,
// block device configuration
.read_size = 16,
.prog_size = 16,
.block_size = 4096,
.block_count = 64,
.cache_size = 16,
.lookahead_size = 16,
.block_cycles = 500,
};
************** Main program ********
int main(void) {
/* Init board hardware. */
/* set BOD VBAT level to 1.65V */
POWER_SetBodVbatLevel(kPOWER_BodVbatLevel1650mv, kPOWER_BodHystLevel50mv, false);
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
/* enable clock for GPIO*/
CLOCK_EnableClock(kCLOCK_Gpio0);
CLOCK_EnableClock(kCLOCK_Gpio1);
BOARD_InitBootPins();
BOARD_BootClockFROHF96M();
BOARD_InitDebugConsole();
flash_config_t flashInstance;
InitilizeFlashInstance(&flashInstance);
// mount the filesystem
int err =lfs_mount(&lfs, &cfg);
}
Something worth mentioning is that I have created the functions based on the IAP API to program the flash of the LPCXpresso55S16. These functions are used in the integration with littlefs to handle reading, writing, erasing, and synchronizing data in the flash memory.
Please let me know if you need any further information.
Ahmed.