2024-05-14 01:12 AM - edited 2024-05-14 01:30 AM
Microcontroller : STM32L476RG,
External flash : AT45DB041E (4Mbit, 256 bytes of page, 2048 bytes of block),
SPI2 communication protocol, using HAL.
I am not able to use the LittleFS library in order to read a file that is written into the flash or any way I cannot even mount the flash. Every time I am getting the same error : (LFS_ERR_CORRUPT and after format it returns LFS_ERR_NOSPC, which is No space left on device). I don't know what it the problem I have configured some function based on the datasheet of the external flash in order to read, write and erase. I have imported the 4 basic files for littlefs into STM32CubeIDE and I don't know how to configure the cfg properly. My approach is this:
/***** LittleFS functions *****/
int block_device_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size)
{
/*Find the physical address*/
uint32_t address = (block * c->block_size) + off + FLASH_BASE;
/*Perform an array read*/
// at45db_read_buffer(address, 0, size, buffer);
buffer_read(1, address, (uint8_t *)buffer);
return 0;
}
int block_device_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size)
{
/*Find the physical address*/
uint8_t address = (block * c->block_size) + off + FLASH_BASE;
/*Transmit data to flash memory through buffer 1*/
at45db_load_data_into_buffer(1, address, size, (uint8_t *) buffer);
return 0;
}
int block_device_erase(const struct lfs_config *c, lfs_block_t block)
{
/*Find the physical address*/
uint32_t physical_address = (block * c->block_size) + FLASH_BASE;
/*Erase the block*/
uint16_t res = at45db_block_erase(physical_address);
if (res == 1) {
/*Success*/
return LFS_ERR_OK;
} else {
/*False*/
return 1;
}
}
int block_device_sync(const struct lfs_config *c)
{
return 0;
}
lfs_t lfs;
lfs_file_t file;
uint8_t lfs_read_buf[256];
uint8_t lfs_prog_buf[256];
uint8_t lfs_lookahead_buf[32]; //256/8
uint8_t lfs_file_buf[256];
const struct lfs_config cfg = {
.read = block_device_read,
.prog = block_device_prog,
.erase = block_device_erase,
.sync = block_device_sync,
// block device configuration
.read_size = 256,
.prog_size = 256,
.block_size = 2048,
.block_count = 256,
.lookahead_size = 16384,
.cache_size = 2048,
.block_cycles = 500
.read_buffer = lfs_read_buf,
.prog_buffer = lfs_prog_buf,
.lookahead_buffer = lfs_lookahead_buf,
};
/*Mount the external flash memory*/
short err = lfs_mount(&lfs, &cfg);
/**
* Reformat if we can't mount the file system.
* This should only happen on the first boot.
* */
if (err) {
err = lfs_format(&lfs, &cfg);
err = lfs_mount(&lfs, &cfg);
}
The function for reading/writing/erasing are correct, since I test with some dummy data to see if I can write the external flash, read it and erase it as well. All works fine. What is wrong here? The think is that I can't use FatFS because the file that is written into the external flash is based on LittleFS.
Question:
Is this the proper way to tell the LFS to mount the external flash? Or it is trying to mount the internal flash and it sees wrong configurations and it crashes?
Solved! Go to Solution.
2024-05-31 04:58 AM
Hello @ngrigoriadis ,
Could you please provide your configuration parameters of the SPI (baud rate, clock polarity, clock phase, etc.)?
Additionally, the value in your code of the lookahead_size parameter is unusually large, the lookahead buffer is used to track which blocks are free in a compact manner, and it typically doesn't need to be as large as the block size. A value that is a multiple of 8 and can cover several blocks is usually sufficient. If you have 256 blocks, a lookahead size of 256 or 512 bytes might be more appropriate.
Also for cache_size parameter, it sets the size of the read/write caches; if the cache size is too large and there isn't enough RAM, it could potentially cause memory allocation failures in your system, which could lead to undefined behavior. If the cache size is too small, it could lead to poor performance due to more frequent reads/writes to the flash. You can consider reducing the cache_size to a smaller multiple of 256 that still fits your performance needs and memory constraints, try setting the cache_size to 1024 bytes or even 512 bytes.
Please initialize and format the file system after reconfiguring LittleFS, should there be any new concerns, please do not hesitate to update me.
2024-05-31 04:58 AM
Hello @ngrigoriadis ,
Could you please provide your configuration parameters of the SPI (baud rate, clock polarity, clock phase, etc.)?
Additionally, the value in your code of the lookahead_size parameter is unusually large, the lookahead buffer is used to track which blocks are free in a compact manner, and it typically doesn't need to be as large as the block size. A value that is a multiple of 8 and can cover several blocks is usually sufficient. If you have 256 blocks, a lookahead size of 256 or 512 bytes might be more appropriate.
Also for cache_size parameter, it sets the size of the read/write caches; if the cache size is too large and there isn't enough RAM, it could potentially cause memory allocation failures in your system, which could lead to undefined behavior. If the cache size is too small, it could lead to poor performance due to more frequent reads/writes to the flash. You can consider reducing the cache_size to a smaller multiple of 256 that still fits your performance needs and memory constraints, try setting the cache_size to 1024 bytes or even 512 bytes.
Please initialize and format the file system after reconfiguring LittleFS, should there be any new concerns, please do not hesitate to update me.
2024-06-03 02:52 AM
@SHs Hello, you were right I redefined some parameters in the cfg structure and I have change the logic of the functions that I have implemented for block write and read and now my program works as expected!
Thank you for your time to reply in my post suggesting a solution I appreciate it.