cancel
Showing results for 
Search instead for 
Did you mean: 

FileX NAND Flash performance problem

Pawol
Associate

I using the stm32L4+MT29F2G01 and the latest Filex library from ST 2.0.0 (6.2.0 AzureRTOS). 

After the format, the performance is satisfactory for me (250ms write 2048B), but after saving a few files of about 1MB each, the efficiency drops sharply, the 2048B data writing takes up to 5 seconds.
When I want to delete a 1 MB file, it takes more than 30 seconds.

I using standart configuration with fault_tolerant.
fx_user.h:

 

#define FX_ENABLE_FAULT_TOLERANT
#define FX_FAULT_TOLERANT
#define FX_FAULT_TOLERANT_DATA

 

 

 

ALIGN_32BYTES(UCHAR media_memory[2048]);
ULONG fault_tolerant_memory[3072 / sizeof(ULONG)];

void fx_app_thread_entry(ULONG thread_input)
{
	  status =  fx_media_format(&nand_flash_disk,
								fx_stm32_levelx_nand_driver,         /* Driver entry */
								(VOID *)CUSTOM_DRIVER_ID,          /* NAND disk memory pointer */
								media_memory,                        /* Media buffer pointer */
								sizeof(media_memory),                /* Media buffer size */
								"NAND_FLASH_DISK",                   /* Volume Name */
								1,         /* Number of FATs */
								32,      /* Directory Entries */
								0,         /* Hidden sectors */
								131008,          /* Total sectors */
								2048,            /* Sector size */
								1,    /* Sectors per cluster */
								1,                  /* Heads */
								1);     /* Sectors per track */

	  /* Check if the format status */
	  if (status != FX_SUCCESS)
	  {
		Error_Handler();
	  }
  status =  fx_media_open(&nand_flash_disk, "FX_LX_NAND_DISK", fx_stm32_levelx_nand_driver, (VOID *)CUSTOM_DRIVER_ID, media_memory, sizeof(media_memory));
  if (status != FX_SUCCESS)
  {
    Error_Handler();
  }
  status = fx_fault_tolerant_enable(&nand_flash_disk, fault_tolerant_memory, sizeof(fault_tolerant_memory));
  if (status != FX_SUCCESS)
  {
    Error_Handler();
  }
...
}

 

I think the problem may start to occur when the filesystem tries to recover obsolet pages. 
I tried to run lx_nand_flash_partial_defragment(&flash_instance, 1) but it took about 5 seconds.

Simply test (create a file and delete):

 

	FX_FILE file_ptr;
	status = fx_file_create(&nand_flash_disk, "test.txt");
	status = fx_file_open(&nand_flash_disk, &file_ptr, "test.txt", FX_OPEN_FOR_WRITE);
	status = fx_file_write(&file_ptr, test_memory, 2048);
	status = fx_file_close(&file_ptr);
	status = delete_file(&nand_flash_disk, "test.txt");

 

test generated 19 obsolete pages:
lx_nand_flash_obsolete_pages 19

 

lx_nand_flash_state	ULONG	1313821252	
lx_nand_flash_total_blocks	ULONG	2048	
lx_nand_flash_pages_per_block	ULONG	64	
lx_nand_flash_bytes_per_page	ULONG	2048	
lx_nand_flash_words_per_block	ULONG	32768	
lx_nand_flash_words_per_page	ULONG	512	
lx_nand_flash_total_pages	ULONG	131072	
lx_nand_flash_bad_blocks	ULONG	0	
lx_nand_flash_free_pages	ULONG	128745	
lx_nand_flash_mapped_pages	ULONG	260	
lx_nand_flash_obsolete_pages	ULONG	19	
lx_nand_flash_minimum_erase_count	ULONG	1	
lx_nand_flash_maximum_erase_count	ULONG	1	
lx_nand_flash_free_block_search	ULONG	4	
lx_nand_flash_found_block_search	ULONG	1028	
lx_nand_flash_found_page_search	ULONG	7	
lx_nand_flash_max_mapped_sector	ULONG	260	
lx_nand_flash_page_corrections	ULONG	0	
lx_nand_flash_last_block_correction	ULONG	0	
lx_nand_flash_last_page_correction	ULONG	0	
lx_nand_flash_diagnostic_system_errors	ULONG	0	
lx_nand_flash_diagnostic_system_error	ULONG	0	
lx_nand_flash_diagnostic_sector_write_requests	ULONG	279	
lx_nand_flash_diagnostic_sector_read_requests	ULONG	265	
lx_nand_flash_diagnostic_sector_release_requests	ULONG	0	
lx_nand_flash_diagnostic_page_allocates	ULONG	279	
lx_nand_flash_diagnostic_page_allocate_errors	ULONG	0	
lx_nand_flash_diagnostic_sector_mapping_cache_hits	ULONG	23	
lx_nand_flash_diagnostic_sector_mapping_cache_misses	ULONG	260	
lx_nand_flash_diagnostic_page_extra_bytes_cache_hits	ULONG	0	
lx_nand_flash_diagnostic_page_extra_bytes_cache_misses	ULONG	0	
lx_nand_flash_diagnostic_page_0_cache_hits	ULONG	0	
lx_nand_flash_diagnostic_page_0_cache_misses	ULONG	0	
lx_nand_flash_diagnostic_block_status_cache_hits	ULONG	0	
lx_nand_flash_diagnostic_block_status_cache_misses	ULONG	0	
lx_nand_flash_diagnostic_block_reclaim_attempts	ULONG	0	
lx_nand_flash_diagnostic_block_erases	ULONG	0	
lx_nand_flash_diagnostic_block_status_gets	ULONG	5682	
lx_nand_flash_diagnostic_block_status_sets	ULONG	0	
lx_nand_flash_diagnostic_page_extra_bytes_sets	ULONG	605	
lx_nand_flash_diagnostic_page_writes	ULONG	2331	
lx_nand_flash_diagnostic_page_extra_bytes_gets	ULONG	10862	
lx_nand_flash_diagnostic_page_reads	ULONG	2881	
lx_nand_flash_diagnostic_moved_pages	ULONG	0	
lx_nand_flash_diagnostic_block_erased_verifies	ULONG	0	
lx_nand_flash_diagnostic_page_erased_verifies	ULONG	279	
lx_nand_flash_diagnostic_initial_format	ULONG	1	
lx_nand_flash_diagnostic_erased_block	ULONG	0	
lx_nand_flash_diagnostic_re_erase_block	ULONG	0	
lx_nand_flash_diagnostic_page_being_obsoleted	ULONG	0	
lx_nand_flash_diagnostic_page_obsoleted	ULONG	0	
lx_nand_flash_diagnostic_mapping_invalid	ULONG	0	
lx_nand_flash_diagnostic_mapping_write_interrupted	ULONG	0	
lx_nand_flash_diagnostic_page_not_free	ULONG	0	
lx_nand_flash_diagnostic_page_data_not_free	ULONG	0	

 

Statistics shows that there are an awful lot of reads and writes from memory.
Is this normal in FAT?

 

3 REPLIES 3

>>Is this normal in FAT?

NAND probably shouldn't be using classic FAT file system.

Small interactions are going to generate a lot of reading/writing as the erase block size is exceedingly large. There are blocks for the data, the directory entries, and any block tables, and block management.

Using NAND on small MCU's is NOT advisable, best to use eMMC where a lot of the block management and deblocking is pushed within the memory device itself

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Do a bit of reading about the file allocation table in microsoft's early file systems, otherwise known as FAT. It's a single sector on a rotating oxide disk that is used to keep the meta data about the file system. Each time you do a sync, the FAT sector gets rewritten. That involves an erase and a write. Not a big deal on spinning rust, but on a Micron MT29F32G08 (data sheet sitting in front of me), the erase of a block takes 3 ms, now you have to rewrite the FAT sector as well as any other data in that block.

But wait, the 29F... has an endurance of 3000 cycles, not the millions of a decade ago. So now you have to start doing wear levelling, so your FAT is going to move around a bit, and your file system has to know about wear levelling or your chip isn't going to last very long. My details are foggy, but the FAT sector is sector 0??? Don't wear it out or you'll loose your pointers to your data.

Remember also, these chips were designed for cameras where you have a relatively few writes of relatively large files, as long as you live within those rules, you're fine. 

Pawol
Associate

@Andrei ChichakMT29F2G01ABAGDWB -> Endurance: 100,000 PROGRAM/ERASE cycles, FileX libraries are optimized for the number of memory erases (I think 🤔)  

Azure RTOS LevelX info:
The algorithm that chooses which flash block to reuse is primarily based on the erase count, but not entirely. The block with the lowest erase count might not be chosen if there is another block that has an erase count within an acceptable delta from the minimal erase count and that has a greater number of obsolete mappings. In such cases, the block with the greatest number of obsolete mappings will be erased and reused, thus saving overhead in moving valid mapping entries.

But writing 2048B of data, uses 360 different memory reads (few writes)
and one loop of lx_nand_flash_partial_defragment uses 6000 different memory reads (few writes) and 1 erase block.