+FAT how to create two partitions on SD card

spikeroot wrote on Friday, August 04, 2017:

I’m having a hard time figuring out how to do this. Here is my code, could you tell me what is wrong with it? ffconfigMAX_PARTITIONS is set to 2, and the 2nd call to FF_Format is only finding 1 partition when it calls FF_PartitionSearch.

static FF_Disk_t Disks[ffconfigMAX_PARTITIONS];

static FF_IOManager_t * CreateIoManager(FF_Disk_t * p_disk)
{
	FF_CreationParameters_t xParameters;
	memset( &xParameters, '\0', sizeof( xParameters ) );
	xParameters.pxDisk = p_disk;
	xParameters.pucCacheMemory = NULL;
	xParameters.ulMemorySize = 1024;
	xParameters.ulSectorSize = 512;
	xParameters.fnWriteBlocks = prvFFWrite;
	xParameters.fnReadBlocks = prvFFRead;
	xParameters.xBlockDeviceIsReentrant = pdFALSE;
	if (!xPlusFATMutex) xPlusFATMutex = xSemaphoreCreateRecursiveMutex();
	ASSERT_AND_RETURN(xPlusFATMutex, NULL);
	xParameters.pvSemaphore = ( void * ) xPlusFATMutex;
	
	FF_Error_t err;
	FF_IOManager_t * p_ioman = FF_CreateIOManger( &xParameters, &err );
	ASSERT_AND_RETURN(p_ioman, NULL);
	if (err != 0) 
	{
		ffconfigFREE(p_ioman);
		return NULL;
	}
	return p_ioman;
}

int FF_SDDiskTwoPartitionFormat(void)
{
	for (size_t i = 0; i  < ffconfigMAX_PARTITIONS; i++)
	{
		memset(&Disks[i], 0, sizeof(Disks[i]));
		Disks[i].ulNumberOfSectors = RTE_Storage_GetBlockCount(RTE_STORAGE_CARD);
		Disks[i].pxIOManager = CreateIoManager(&Disks[i]);
		if (!Disks[i].pxIOManager) return -1;
	
		Disks[i].xStatus.bIsInitialised = pdTRUE;
		Disks[i].xStatus.bPartitionNumber = i;
	}
	
	FF_PartitionParameters_t partitions;
	memset( &partitions, 0x00, sizeof( partitions ) );
	partitions.ulSectorCount = RTE_Storage_GetBlockCount(RTE_STORAGE_CARD);
	partitions.ulHiddenSectors = 0;
	partitions.ulInterSpace = 0;
	partitions.xPrimaryCount = 2; // ????
	partitions.eSizeType = eSizeIsPercent;
	partitions.xSizes[0] = partitions.xSizes[1] = 50;
	
	FF_Error_t partition_err = FF_Partition(&Disks[0], &partitions);
	if (partition_err != FF_ERR_NONE) return -1;
	
	for (size_t i = 0; i < ffconfigMAX_PARTITIONS; i++)
	{
		FF_Error_t format_err = FF_Format(&Disks[i], i, pdFALSE, pdFALSE);
		if (format_err != FF_ERR_NONE) return -1;
	}
	
	return 0;
}


rtel wrote on Monday, August 07, 2017:

Is this a different topic to this thread: https://sourceforge.net/p/freertos/discussion/382005/thread/4874bbe8/ ?

heinbali01 wrote on Monday, August 07, 2017:

The topics are indeed quite similar.
Before answering, I will try-out the above code on an SD-card

heinbali01 wrote on Monday, August 07, 2017:

PS. please check all return codes from the library calls and it may also useful to define FF_PRINTF, in order to see the internal logging of FreeRTOS+FAT.
I’m still playing with it and I’ll report later.

spikeroot wrote on Monday, August 07, 2017:

My code is checking all return values. The second call to FF_Format is returning 0x86000010.

I also have FF_PRINTF defined, and here is the output:

FF_Format: Secs 124868608 Rsvd 32 Hidden 0 Root 0 Data 124868576
FF_Format: SecCluster 64 DatSec 124838016 DataClus 1950594 ulClusterBeginLBA 30592
FF_Format: Clearing entire FAT (2 x 15240 sectors):
FF_Format: Clearing done
FF_Format: Clearing root directory at 00007780: 64 sectors
FF_Part: no partitions, try as PBR
FF_Part: no partitions, try as PBR
FF_Part: no partitions, try as PBR
prvDetermineFatType: firstWord 0000FFF8

heinbali01 wrote on Monday, August 07, 2017:

I’m working on it, about one hour to go :slight_smile:

spikeroot wrote on Monday, August 07, 2017:

Thanks! Appreciate your responsive support on this forum.

heinbali01 wrote on Monday, August 07, 2017:

Hi Michael, the biggest problem with your code was this line:

    partitions.ulHiddenSectors = 0;

As a consequence, the boot sector 0 got overwritten while formatting partition 0.
The meaning of partitions.ulHiddenSectors is: the offset where the BPR ( Partition Boot Record ) shall be stored.

I will add a configASSERT(), to flag this off in future releases.

There were some other issues, like not settings the signature:

    pxDisks[ i ]->ulSignature = sdSIGNATURE;

As multiple partitions are rarely used, the documentation about this feature is maybe not optimal. We’re sorry about this.

Here below you find an attachment called format_partitions.c that I used for testing.

Please tell us how it goes. Thanks, Hein

heinbali01 wrote on Monday, August 07, 2017:

Another thing that I changed was:

-    xParameters.ulMemorySize = 1024;
+    xParameters.ulMemorySize = 3072;	// 1024;

This is the amount of cache memory per I/O handler. Recently there was a question about the “optimal” size of this cache memory. I found that at most 9 sector buffers were being used simultaneously in a busy application:

https://sourceforge.net/p/freertos/discussion/382005/thread/ea301981/?limit=250#3a53

So this would be safer:

    xParameters.ulMemorySize = 9 * 512;

If you have a single task that makes use of FreeRTOS+FAT, the size of the caching memory may be less.

spikeroot wrote on Wednesday, August 09, 2017:

I’ve incorporated your suggestions and am now successfully partitioning my SD card. But now my problem is that Windows won’t read the second partition. I can see it through the disk management console, but I can’t actually access it. Apparently (and I wish I’d known this before) Windows just doesn’t recognize multiple partitions on a removable drive. I found a couple workarounds that involved installing a hacked-together driver to make windows see it as a non-removable drive, but only ended up causing Windows to run its “Repair Windows” utility upon restarting and re-install the old driver.

Do you have any other suggestions for accessing the second partition?

Link to my original question about being able to access all partitions: https://sourceforge.net/p/freertos/discussion/382005/thread/4874bbe8/

heinbali01 wrote on Wednesday, August 09, 2017:

Do you have any other suggestions for accessing the second partition?

Yes I do, use Linux :slight_smile:

I just checked my SD-card under ubuntu. It shows the two partitions created by FreeRTOS+FAT. I see their contents and I can write to them.

Also running the file check program showed success:

root@my_ubuntu:~# fsck.vfat /dev/sdb1
fsck.fat 3.0.28 (2015-05-16)
/dev/sdb1: 6 files, 6/123381 clusters
root@my_ubuntu:~# fsck.vfat /dev/sdb2
fsck.fat 3.0.28 (2015-05-16)
/dev/sdb2: 3 files, 3/123381 clusters

My W10 only sees a single partition.

heinbali01 wrote on Wednesday, August 09, 2017:

My W10 only sees a single partition.

With W10, of course I mean Windows-10.

Also when I try to (re-)format the SD-card it will only see the first partition, i.e. it only sees 50% of the actual disk size.

spikeroot wrote on Wednesday, August 09, 2017:

Linux might be an option if I were the user of my product. Unfortunately, I need to make it work for Windows users.

My original question was whether I’d be able to access all partitions from Windows. Apparently the answer should have been “no.” I understand now that this limitation is inherent in Windows.

Hello - I’m trying to understand how to create multiple partitions on a single RAMdisk for testing purposes (eventually will be using eMMC) - is the “format_partitions.c” file still available somewhere for reference?

The description of the FF_Partition() API seems to suggest that a singular physical media described by a singular FF_Disk_t structure would be divided into a number of partitions as described by the FF_PartitionParameters structure. However, this post leads me to believe that a separate FF_Disk_t structure is needed for each partition, which seems counterintuitive. An example showing how to give a single RAMdisk two partitions would be very helpful. Thanks!