2023-07-24 06:22 AM
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?
2023-07-24 09:36 AM
>>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
2023-07-24 11:34 AM
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.
2023-07-25 05:09 AM - edited 2023-07-25 05:10 AM
@Andrei ChichakMT29F2G01ABAGDWB -> Endurance: 100,000 PROGRAM/ERASE cycles, FileX libraries are optimized for the number of memory erases (I think :thinking_face:)
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.
2024-08-27 11:22 PM
Hello,
I am working on a project using an STM32F469 microcontroller, and I'm trying to interface a W25N01GV NAND flash memory over QSPI. I’m currently facing issues during the format phase while using FileX with LevelX NAND driver.
following is the configuration used while formatting:
/* Format the NAND flash as FAT */ 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 */ 65536, /* Total sectors */ 2048, /* Sector size */ 1, /* Sectors per cluster */ 1, /* Heads */ 1); /* Sectors per track */
1) The QSPI initialization seems to work fine, and I can read the flash ID: EFAA21 successfully.
2) When attempting to format the NAND flash using fx_media_format, the process fails with errors indicating that no new pages can be allocated (LX_NO_SECTORS and LX_SECTOR_NOT_FOUND).
The software components I have selected in Azure RTOS are as shown in the image:
I also doubt if my implementation of W25NXX_Read_Spare_Area and W25NXX_Write_Spare_Area under lx_nand_driver_extra_bytes_get/ lx_nand_driver_extra_bytes_set.
Please help me in solving this issue. There are no examples available with SPI/QSPI NAND Flash. I have attached my custom driver and W25N C implementation files for reference.
I really appreciate any help you can provide.