FreeRTOS+FAT Debugging New SD Card Media Driver: data fading away?!

I am working on a new +FAT port. This is a media driver for SD Card over SPI.

At first I tested it with something similar to the FATFileSystem example at https://os.mbed.com/docs/mbed-os/v5.15/apis/fatfilesystem.html. That seemed to work well. Next, I tried FreeRTOSv10.2.1_191129\FreeRTOS-Labs\Demo\Common\FreeRTOS_Plus_FAT_Demos\CreateAndVerifyExampleFiles.c, and I am going crazy trying to debug this. It gets through prvCreateDemoFilesUsing_ff_fwrite OK, but, when it gets to prvVerifyDemoFileUsing_ff_fread, the files are gone!

Creating file /fs/root001.txt in /fs
Creating file /fs/root002.txt in /fs
Creating file /fs/root003.txt in /fs
Creating file /fs/root004.txt in /fs
Creating file /fs/root005.txt in /fs
Reading file root001.txt from /fs
FF_fopen(root001.txt): No such file or directory (-2)
assertion "pxFile" failed: file "CreateAndVerifyExampleFiles.c", line 236, function: prvVerifyDemoFileUsing_ff_fread

Sure enough, if I yank the card and put it into the slot on my PC, I don’t see the root???.txt files.

I added some more printf()s to the FATFileSystem example, and I added a directory listing in the middle:

ls();
err = ff_chdir("fs");
if (err < 0) {
	FF_PRINTF("chdir error: %s (%d)\n", strerror(stdioGET_ERRNO()),
			-stdioGET_ERRNO());
}
ls();

Sure enough, the numbers.txt file is there:

FF_Mount:
FF_FS_Add:
Reading FAT and calculating Free Space
Partition Nr          0
Type                 12 (FAT32)
VolLabel       'NO NAME    '
TotalSectors   15515648
SecsPerCluster       64
Size            7753728 KB
FreeSize        7753536 KB ( 100 perc free )
Opening "/fs/numbers.txt"... Fail :(
No file found, creating a new file... OK
Writing numbers (10/10)... OK
Seeking file... OK

Incrementing numbers (0/10)...
Incrementing numbers (1/10)...
Incrementing numbers (2/10)...
Incrementing numbers (3/10)...
Incrementing numbers (4/10)...
Incrementing numbers (5/10)...
Incrementing numbers (6/10)...
Incrementing numbers (7/10)...
Incrementing numbers (8/10)...
Incrementing numbers (10/10)... OK
Closing "/fs/numbers.txt"... OK
Directory Listing:
fs [directory] [size=1024]
. [directory] [size=1024]
Directory Listing:
System Volume Information [directory] [size=0]
numbers.txt [writable file] [size=60]
.. [directory] [size=1024]
. [directory] [size=1024]
Opening "/fs/numbers.txt"... OK
numbers:
    5
    6
    7
    8
    9
    10
    11
    12
    13

Closing "/fs/numbers.txt"... OK

When I pull the card and mount it in Windows, sometimes I see numbers.txt, and sometimes I don’t. Similary, at the start of the test, sometimes the old file is found, but usually I get:

Opening "/fs/numbers.txt"... Fail :(
No file found, creating a new file... OK

What could be happening here? Am I missing some step needed to commit changes to the card? Is my hardware no good? (I did try a couple different microSD cards). What should I be looking at next?

CreateAndVerifyExampleFiles.c (16.0 KB)
x.c (5.9 KB)

Hello carlk3, I recommend to test your driver first with a simple self-made test.
The best way to do this is to use the interface in ff_stdio.h.
Create a file, write to it, and close it. Then open, read and close it. Then try it on a PC. Something like that.

I am not sure what /fs stands for in the example. It it the pseudo directory on which the SD-card is mounted?

What parameter did you pass to FF_SDDiskInit()? Was it "/" of "/fs"?

You wrote the driver your self. Q : does it keep sectors in cache? It should not do, because FreeRTOS+TCP already uses cache memory when necessary.

PS. when a file was written to, the caches will be flushed as soon as ff_close() is called.

Hi Hein,

I recommend to test your driver first with a simple self-made test.
The best way to do this is to use the interface in ff_stdio.h .
Create a file, write to it, and close it. Then open, read and close it. Then try it on a PC. Something like that.

That is what I’m trying to do in the snippet I attached as “x.c”. For very simple tests, it seems to work. But, somehow, later activity seems to wipe out files created earlier.

Now, I’m thinking of stealing porting this “Low level disk I/O module function checker” code http://elm-chan.org/fsw/ff/res/app4.c to test my media driver at a lower level.

I am not sure what /fs stands for in the example. It it the pseudo directory on which the SD-card is mounted?

/fs is supposed to be the, umm, “mount point”:

/* Where the RAM disk is mounted. */
#define mainSD_DISK_NAME			"/fs"
// ...

		/*
		 * Add a file system
		 * The path must be absolute, e.g. start with a slash
		 * The second argument is the FF_Disk_t structure that is handling the driver
		 */
		int iReturn = FF_FS_Add(mainSD_DISK_NAME, pxDisk);
    	FF_PRINTF("FF_FS_Add: %s\n", (const char *) FF_GetErrMessage(xError));
		configASSERT(iReturn);
	}

What parameter did you pass to FF_SDDiskInit() ? Was it "/" of "/fs" ?

I took the FF_Mount and FF_FS_Add out of FF_SDDiskInit, so I am not using a parameter there anymore. You can see the calls in the snippet I attached as “x.c”.

Q : does it keep sectors in cache?

Not intentionally! It simply passes everything through to SPI commands.

I am pretty unsure how to configure the +FAT cache. This is what I have now:

	const BaseType_t SECTOR_SIZE = 512;
	const uint32_t xIOManagerCacheSize = 2 * SECTOR_SIZE;
// ...

		memset(&xParameters, 0, sizeof xParameters);
		xParameters.pucCacheMemory = NULL;
		xParameters.ulMemorySize = xIOManagerCacheSize;
		xParameters.ulSectorSize = SECTOR_SIZE;
		xParameters.fnWriteBlocks = FFWrite;
// ...
		pxDisk->pxIOManager = FF_CreateIOManger(&xParameters, &xError);

Thanks for your help!

       Carl

FreeRTOSFATConfig.h (14.0 KB)
ff_sddisk.c (68.4 KB)

#define mainSD_DISK_NAME "/fs"

I think it is less confusing when you define this as "/", and create a physical directory "/fs".

const uint32_t xIOManagerCacheSize = 2 * SECTOR_SIZE;

That is very small. Not sure if it gives problems somewhere.

Yes it would be a good idea to test the low-level SPI read and write functions.

#define mainSD_DISK_NAME "/fs"

I think it is less confusing when you define this as "/" , and create a physical directory "/fs" .

Well, I am confusing :slight_smile: I’m still unclear on this whole subject. I plan to eventually have 3 SD cards mounted in the system. I presume I’ll have to do something like this?

FF_FS_Add("/sd0", pxDisk0);
FF_FS_Add("/sd1", pxDisk1);
FF_FS_Add("/sd2", pxDisk2);

const uint32_t xIOManagerCacheSize = 2 * SECTOR_SIZE;

That is very small. Not sure if it gives problems somewhere.

OK, I will try 16 * SECTOR_SIZE and see how that works. I was thinking it would only affect performance (which is important, but I’m still trying to debug all this).

Yes it would be a good idea to test the low-level SPI read and write functions.

I have now done that, and it was very informative. I found two logic errors in my driver. Dumb mistakes. To quote Michael Bolton in Office Space: “Okay! I must have put a decimal point in the wrong place or something. Sh*t! I always do that. I always mess up some mundane detail.”

Update: I now have FreeRTOS+FAT+CLI running on PSoC® 6 BLE Pioneer Kit (CY8CKIT-062-BLE) with an Adafruit Data Logger Shield.

app4 - IO module function checker.c (12.5 KB)