in ff_format.c [916:1076]
FF_Error_t FF_Partition( FF_Disk_t * pxDisk,
FF_PartitionParameters_t * pParams )
{
FF_Error_t xReturn = FF_ERR_NONE;
struct xPartitionSet xSet;
BaseType_t xNeedExtended; /* When more than 4 partitions are requested, extended partitions are needed. */
uint32_t ulAvailable; /* The number of sectors available. */
BaseType_t xPartitionNumber;
uint32_t ulSummedSizes = 0U; /* Summed sizes as a percentage or as number of sectors. */
uint32_t ulReservedSpace; /**< Space needed for the extended partitions. */
memset( &( xSet ), 0, sizeof( xSet ) );
/* Hidden space between 2 extended partitions */
xSet.ulInterSpace = pParams->ulInterSpace ? pParams->ulInterSpace : 2048;
/* The +FAT IO-manager. */
xSet.pxIOManager = pxDisk->pxIOManager;
/* Clear caching without flushing first. */
FF_IOMAN_InitBufferDescriptors( xSet.pxIOManager );
/* Avoid sanity checks by FF_BlockRead/Write. */
xSet.pxIOManager->xPartition.ulTotalSectors = 0;
/* Get the sum of sizes and number of actual partitions. */
for( xPartitionNumber = 0; xPartitionNumber < ffconfigMAX_PARTITIONS; xPartitionNumber++ )
{
if( pParams->xSizes[ xPartitionNumber ] > 0 )
{
xSet.xPartitionCount++;
ulSummedSizes += pParams->xSizes[ xPartitionNumber ];
}
}
/* xSet.xPartitionCount is at most 'ffconfigMAX_PARTITIONS' */
if( xSet.xPartitionCount == 0 )
{
xSet.xPartitionCount = 1;
/* 'ffconfigMAX_PARTITIONS' must be 1 or more. */
if( pParams->eSizeType == eSizeIsSectors )
{
pParams->xSizes[ 0 ] = pParams->ulSectorCount;
}
else
{
pParams->xSizes[ 0 ] = 100;
}
ulSummedSizes = pParams->xSizes[ 0 ];
}
/* Correct PrimaryCount if necessary. */
if( pParams->xPrimaryCount > ( ( xSet.xPartitionCount > 4 ) ? 3 : xSet.xPartitionCount ) )
{
pParams->xPrimaryCount = ( xSet.xPartitionCount > 4 ) ? 3 : xSet.xPartitionCount;
}
/* Now see if extended is necessary. */
xNeedExtended = ( xSet.xPartitionCount > pParams->xPrimaryCount ) ? pdTRUE : pdFALSE;
if( xNeedExtended != pdFALSE )
{
if( pParams->ulHiddenSectors < 4096 )
{
pParams->ulHiddenSectors = 4096;
}
ulReservedSpace = xSet.ulInterSpace * ( xSet.xPartitionCount - pParams->xPrimaryCount );
}
else
{
/* There must be at least 1 hidden sector. */
if( pParams->ulHiddenSectors < 1 )
{
pParams->ulHiddenSectors = 1;
}
ulReservedSpace = 0;
}
ulAvailable = pParams->ulSectorCount - pParams->ulHiddenSectors - ulReservedSpace;
/* Check validity of Sizes */
switch( pParams->eSizeType )
{
case eSizeIsQuota: /* Assign a quotum (sum of Sizes is free, all disk space will be allocated) */
break;
case eSizeIsPercent: /* Assign a percentage of the available space (sum of Sizes must be <= 100) */
if( ulSummedSizes > 100 )
{
return FF_FORMATPARTITION | FF_ERR_IOMAN_BAD_MEMSIZE;
}
ulSummedSizes = 100;
break;
case eSizeIsSectors: /* Assign fixed number of sectors (512 byte each) */
if( ulSummedSizes > ulAvailable )
{
return FF_FORMATPARTITION | FF_ERR_IOMAN_BAD_MEMSIZE;
}
break;
}
{
uint32_t ulRemaining = ulAvailable;
uint32_t ulLBA = pParams->ulHiddenSectors;
/* Divide the available sectors among the partitions: */
for( xPartitionNumber = 0; xPartitionNumber < xSet.xPartitionCount; xPartitionNumber++ )
{
if( pParams->xSizes[ xPartitionNumber ] > 0 )
{
uint32_t ulSize;
switch( pParams->eSizeType )
{
case eSizeIsQuota: /* Assign a quotum (sum of Sizes is free, all disk space will be allocated) */
case eSizeIsPercent: /* Assign a percentage of the available space (sum of Sizes must be <= 100) */
ulSize = ( uint32_t ) ( ( ( uint64_t ) pParams->xSizes[ xPartitionNumber ] * ulAvailable ) / ulSummedSizes );
break;
case eSizeIsSectors: /* Assign fixed number of sectors (512 byte each) */
default: /* Just for the compiler(s) */
ulSize = pParams->xSizes[ xPartitionNumber ];
break;
}
if( ulSize > ulRemaining )
{
ulSize = ulRemaining;
}
ulRemaining -= ulSize;
xSet.pxPartitions[ xPartitionNumber ].ulSectorCount = ulSize;
xSet.pxPartitions[ xPartitionNumber ].ucActive = 0x80;
xSet.pxPartitions[ xPartitionNumber ].ulStartLBA = ulLBA; /* ulStartLBA might still change for logical partitions */
xSet.pxPartitions[ xPartitionNumber ].ucPartitionID = 0x0B;
ulLBA += ulSize;
}
}
}
if( xNeedExtended == pdFALSE )
{
xReturn = prvPartitionPrimary( &( xSet ) );
}
else
{
xReturn = prvPartitionExtended( &( xSet ), pParams );
}
return xReturn;
}