Skip to main content
Visitor II
November 29, 2023
Question

littleFS using STM32L4 HAL and EMMC chip

  • November 29, 2023
  • 1 reply
  • 5449 views

Hey!

I'm stumbling around with integrating littleFS using STM32 HAL library and EMMC 4GB chip, and any help would be greatly appreciated.

I modified FATFS EMMC example so that it uses littleFS. I changed nothing in the SDMMC driver, so since it worked with original example I'm expecting it should also work with littleFS.

I'm using STM32L4P5G-DK development kit with EMMC chip: Block size is 512 bytes and number of blocks is 7634944.

The issue here is that I cannot for the life of me get it to work reliably. When I somehow (by tweaking parameters) get it to work and I change one parameter, it fails to format and then even if I reverse the changes the same issue persist.

I would really appreciate if somebody could help me by checking the configuration and functions.

 

Thank you so much!

 

 

int read(const struct lfs_config *c, lfs_block_t block,
 lfs_off_t off, void *buffer, lfs_size_t size)
{
 DWORD start_sector = (block * c->block_size) + off; // start address

 if (MMC_read(0, (uint8_t*)buffer, start_sector, size) != RES_OK) {
 // Handle read error
 return LFS_ERR_IO;
 }

 return LFS_ERR_OK;
}

int prog(const struct lfs_config *c, lfs_block_t block,
 lfs_off_t off, const void *buffer, lfs_size_t size)
{
 // Calculate the start sector based on block and offset
 DWORD start_sector = (block * c->block_size) + off;

 if (MMC_write(0, buffer, start_sector, size) != RES_OK) {
		// Handle write error
		return LFS_ERR_IO;
 }
 return LFS_ERR_OK;}

int erase(const struct lfs_config *c, lfs_block_t block)
{
 // Calculate the start sector address based on block
 DWORD start_sector = block * c->block_size;

 // Calculate the end sector address based on block size
 DWORD end_sector = (block + 1) * c->block_size) - 1;

 // Erase the specified memory area on the MMC card
 if (BSP_MMC_Erase(start_sector, end_sector) != MMC_OK) {
 // Handle erase error
 return LFS_ERR_IO;
 }
 return LFS_ERR_OK;
} 

const struct lfs_config cfg = {
 // block device operations
 .read = read,
 .prog = prog,
 .erase = erase,
 .sync = sync,

 // block device configuration
 .read_size = 512,
 .prog_size = 512,
 .block_size = 512,
 .block_count = 7634944,
 .cache_size = 512,
 .lookahead_size = 512,
 .block_cycles = 100,
};

 

One weird things is that from time to time, lfs.c library had an assert when it said that detected block count (127249) is different from configured one (7634944). And then it was never asserted again.

Also in the littlefs source files, if block_count is set to zero LFS will automatically set it to detected size. (as per comments in the code), and setting it to zero worked for some time, and suddenly it started generating assertions that block_count cannot be 0.

 

Below is beginning of main code that handles initialization and mounting.

 

 DSTATUS status = MMC_initialize(0);
 if(status != RES_OK) {
 	printf("Error MMC_initialize %d\n", status);
 	while(1);
 }
 
 BSP_MMC_CardInfo CardInfo = {9};
 status = BSP_MMC_GetCardInfo(&CardInfo);
 if(status != RES_OK) {
 	printf("Error BSP_MMC_GetCardInfo %d\n", status);
 	while(1);
 }
 
 printf("Card Initialized\n");
 printf("block size: %d, %d\n", CardInfo.LogBlockSize, CardInfo.LogBlockNbr);

 // mount the filesystem
 int err = lfs_mount(&lfs, &cfg);

 // reformat if we can't mount the filesystem
 // this should only happen on the first boot
 if (err || FORCE_FORMAT) {
 	printf("Formating filesystem..\n");
 	err = lfs_format(&lfs, &cfg);
 	if(err < 0) {
 		printf("Error lfs_format %d\n", err);
 		while(1);
 	}
 	err = lfs_mount(&lfs, &cfg);
 	if(err < 0) {
 		printf("Error lfs_mount %d\n", err);
 		while(1);
 	}
 }

 

Whenever I run the program I get this:

 

Card Initialized
block size: 512, 7634944
D:/Projects/stm32/STM32CubeL4/Projects/32L4P5GDISCOVERY/Applications/FatFs/FatFs_eMMC_Standalone/third_party/littlefs/lfs.c:1346:error: Corrupted dir pair at {0x0, 0x1}
Formating filesystem..
Error lfs_format -5

 

 

Thank you!

    This topic has been closed for replies.

    1 reply

    Graduate II
    November 30, 2023

    Step one validate the read functionality for the eMMC blocks thoroughly.

    Step two validate write functionality, that a) it works, and b) you can read the SAME data back you wrote.

    Step three integrate the working block storage layer with a file system.

    eMMC typically has two CSD capacity reporting modes, the more usual one provides some arbitrary capacity, and you need the EXTCSD to get the actual capacity.

    kikibAuthor
    Visitor II
    December 3, 2023

    Hello. Thank you for taking the time to answer.

    I completed first two steps successfully and now I'm working on step three.

    While I can read and write to a file, I worry that I don't have correct configuration, because my timings for 32kb byte array are: 

     

     

    450579 us to write 32768 bytes
    513808 us to read 32768 bytes

     

    Which does not look too good.

    My current parameters are:

     

     .read_size = 512,
     .prog_size = 512,
     .block_size = 512,
     .block_count = 7634944, number of blocks, read from MMC chip
     .cache_size = 512,
     .lookahead_size = 512,
     .block_cycles = 100,

     

     Does any of these parameters stand out?

    Also, I'm wondering, is erase functionality required? I tried removing it and everything still works fine.

     

    Visitor II
    February 22, 2024

    Hi, have you resolved the issue? I am facing the same issue, the same exact error code (-5). My setup is SDIO 4 bit wide with a micro SD card (size 32GB). SDIO and eMMC should have similar handling and my code looks almost like yours. Any luck in solving this problem?