fx_fault_tolerant for user data consistency
Closed this issue · 4 comments
Hi. I'm trying to use FileX + LevelX on the AT45DB641E dataflash. I connected AT45 as NAND flash page size 256 + 8 bytes. I want to use the fx_fault_tolerant module to provide the integrity of the file system and to ensure consistency data in the user files.
example:
I'm overwriting the same file.
fx_file_current_file_size is always 600 bytes.
The value returned by the functions is always 0.
I want the data in the file to remain consistent if there is an unexpected loss of power.
My problem is that the free disk space is leaking.
iteration - free space
0 - 6979584
1 - 6975488
2 - 6971392
3 - 6967296
4 - 6963200
5 - 6959104
6 - 6955008
7 - 6950912
8 - 6946816
9 - 6942720
.... //free space leak
N - 6868992
....
My assumption is that there are lost clusters remaining in the FAT.
lx_nand_flash_free_pages decreases.
fx_media_available_clusters decreases.
question 1)
Can I use the fx_fault_tolerant module to ensure the integrity of user data?
question 2)
Can you tell me what I'm doing wrong?
question 3)
Can I increase the value of the internal definition
#define FX_FAULT_TOLERANT_MAXIMUM_LOG_FILE_SIZE 3072
to increase the maximum size of a user transaction?
test function code:
void TransactionTest()
{
DFNANDInstance_t df;
DfNANDGetInstance(0, &df);
df.chipErase();
FSFXLXNANDFlashInit();
uint32_t status;
LX_NAND_FLASH* nand = LXNandGet();
static UCHAR faultTolerantMemory[FX_FAULT_TOLERANT_MAXIMUM_LOG_FILE_SIZE];
static uint8_t fxMemBuf[8 * 1024];
static FX_MEDIA fxDisk;
memset(&fxDisk, 0, sizeof(fxDisk));
memset(fxMemBuf, 0, sizeof(fxMemBuf));
_fx_system_initialize();
uint32_t sectorToFat =
nand->lx_nand_flash_total_pages -
nand->lx_nand_flash_total_blocks - 1 -
nand->lx_nand_flash_pages_per_block * 15; //15 blocks reserved
status = _fx_media_format(&fxDisk,
FSFXNandFlashDriver, // Driver entry
0, // RAM disk memory pointer
fxMemBuf, // Media buffer pointer
sizeof(fxMemBuf), // Media buffer size
"C", // Volume Name
1, // Number of FATs
32, // Directory Entries
8, // Hidden sectors
sectorToFat, // Total sectors
256, // Sector size
16, // Sectors per cluster
1, // Heads
1); // Sectors per track
if (status) flt();
memset(&fxDisk, 0, sizeof(fxDisk));
memset(fxMemBuf, 0, sizeof(fxMemBuf));
memset(faultTolerantMemory, 0, sizeof(faultTolerantMemory));
status = _fx_media_open(&fxDisk, "C", FSFXNandFlashDriver, 0, fxMemBuf, sizeof(fxMemBuf));
if (status) flt();
status = _fx_fault_tolerant_enable(&fxDisk, faultTolerantMemory, sizeof(faultTolerantMemory));
if (status) flt();
static uint8_t data1[300];
static uint8_t data2[300];
memset(data1, 0xAA, sizeof(data1));
memset(data2, 0xBB, sizeof(data2));
while (1) {
ULONG space;
FX_FILE file;
status = _fx_media_space_available(&fxDisk, &space);
if (status) flt();
status = _fx_fault_tolerant_transaction_start(&fxDisk);
if (status) flt();
status = _fx_file_create(&fxDisk, "test.txt");
if (status != FX_ALREADY_CREATED && status != FX_SUCCESS) flt();
status = _fx_file_open(&fxDisk, &file, "test.txt", FX_OPEN_FOR_WRITE);
if (status) flt();
status = _fx_file_seek(&file, 0);
if (status) flt();
status = _fx_file_write(&file, data1, 300);
if (status) flt();
status = _fx_file_write(&file, data2, 300);
if (status) flt();
status = _fx_file_close(&file);
if (status) flt();
status = _fx_fault_tolerant_transaction_end(&fxDisk);
if (status) flt();
status = _lx_nand_flash_defragment(nand);
if (status) flt();
}
}
Hi, all the AzureRTOS APIs starts with tx_/nx_/fx_/... In user application, don't call to tx/nx/fx/... directly. Those could be internal functions. In your example, _fx_fault_tolerant_transaction_start/end are internal functions. The only API needed to enable fault tolerant is fx_fault_tolerant_enable
.
See my answers below.
question 1)
Can I use the fx_fault_tolerant module to ensure the integrity of user data?
[MSFT]: Yes.
question 2)
Can you tell me what I'm doing wrong?
[MSFT]: Internal functions must not be called.
question 3)
Can I increase the value of the internal definition
#define FX_FAULT_TOLERANT_MAXIMUM_LOG_FILE_SIZE 3072
to increase the maximum size of a user transaction?
[MSFT]: No. This size is defined for the maximum log file size. No transaction would create a larger log file than this value.
OK, thanks.
Another question:
Is there an interface in FileX, to provide write transactions that consist of multiple write(...)?
I would like, after restarting, to have either three successful writes or none in the file.
Depending on when the failure occurred.
Of course, this can be implemented through a temporary file and the subsequent renaming of the file.
I just wanted to understand - maybe FileX has a ready-made mechanism?
Thanks.
No, there is no FileX service to protect multiple transactions. Besides a temporary file, another solution is to write all data into a buffer and then write buffer to file system in one fx_file_write
call.
I got it, thanks.