Ejemplo n.º 1
0
int fatfs_fat_add_cluster_to_chain(struct fatfs *fs, UINT32 start_cluster, UINT32 newEntry)
{
	UINT32 last_cluster = FAT32_LAST_CLUSTER;
	UINT32 next_cluster = start_cluster;

	if (start_cluster == FAT32_LAST_CLUSTER)
		return 0;
	
	// Loop until end of chain
	while ( next_cluster != FAT32_LAST_CLUSTER )
	{
		last_cluster = next_cluster;

		// Find next link
		next_cluster = fatfs_find_next_cluster(fs, next_cluster);
		if (!next_cluster)
			return 0;
	}

	// Add link in for new cluster
	fatfs_fat_set_cluster(fs, last_cluster, newEntry);

	// Mark new cluster as end of chain
	fatfs_fat_set_cluster(fs, newEntry, FAT32_LAST_CLUSTER);

	return 1;
} 
Ejemplo n.º 2
0
//-----------------------------------------------------------------------------
// fatfs_sector_reader: From the provided startcluster and sector offset
// Returns True if success, returns False if not (including if read out of range)
//-----------------------------------------------------------------------------
int fatfs_sector_reader(struct fatfs *fs, uint32 start_cluster, uint32 offset, uint8 *target)
{
    uint32 sector_to_read = 0;
    uint32 cluster_to_read = 0;
    uint32 cluster_chain = 0;
    uint32 i;
    uint32 lba;

    // FAT16 Root directory
    if (fs->fat_type == FAT_TYPE_16 && start_cluster == 0)
    {
        if (offset < fs->rootdir_sectors)
            lba = fs->lba_begin + fs->rootdir_first_sector + offset;
        else
            return 0;
    }
    // FAT16/32 Other
    else
    {
        // Set start of cluster chain to initial value
        cluster_chain = start_cluster;

        // Find parameters
        cluster_to_read = offset / fs->sectors_per_cluster;
        sector_to_read = offset - (cluster_to_read*fs->sectors_per_cluster);

        // Follow chain to find cluster to read
        for (i=0; i<cluster_to_read; i++)
            cluster_chain = fatfs_find_next_cluster(fs, cluster_chain);

        // If end of cluster chain then return false
        if (cluster_chain == FAT32_LAST_CLUSTER)
            return 0;

        // Calculate sector address
        lba = fatfs_lba_of_cluster(fs, cluster_chain)+sector_to_read;
    }

    // User provided target array
    if (target)
        return fs->disk_io.read_media(lba, target, 1);
    // Else read sector if not already loaded
    else if (lba != fs->currentsector.address)
    {
        fs->currentsector.address = lba;
        return fs->disk_io.read_media(fs->currentsector.address, fs->currentsector.sector, 1);
    }
    else
        return 1;
}
Ejemplo n.º 3
0
int fatfs_free_cluster_chain(struct fatfs *fs, UINT32 start_cluster)
{
	UINT32 last_cluster;
	UINT32 next_cluster = start_cluster;
	
	// Loop until end of chain
	while ( (next_cluster != FAT32_LAST_CLUSTER) && (next_cluster != 0x00000000) )
	{
		last_cluster = next_cluster;

		// Find next link
		next_cluster = fatfs_find_next_cluster(fs, next_cluster);

		// Clear last link
		fatfs_fat_set_cluster(fs, last_cluster, 0x00000000);
	}

	return 1;
} 
Ejemplo n.º 4
0
int fatfs_sector_reader(struct fatfs *fs, uint32 start_cluster, uint32 offset, uint8 *target)
{
    uint32 sector_to_read = 0;
    uint32 cluster_to_read = 0;
    uint32 cluster_chain = 0;
    uint32 i;
    uint32 lba;

    
        // Set start of cluster chain to initial value
        cluster_chain = start_cluster;

        // Find parameters
        cluster_to_read = offset / fs->sectors_per_cluster;      
        sector_to_read = offset - (cluster_to_read*fs->sectors_per_cluster);

        // Follow chain to find cluster to read
        for (i=0; i<cluster_to_read; i++)
            cluster_chain = fatfs_find_next_cluster(fs, cluster_chain);

        // If end of cluster chain then return false
        if (cluster_chain == FAT32_LAST_CLUSTER) 
            return 0;

        // Calculate sector address
        lba = fatfs_lba_of_cluster(fs, cluster_chain)+sector_to_read;
    

    // User provided target array
    if (target)
        return media_read_ak(lba, target, 512);
    // Else read sector if not already loaded
    else if (lba != fs->currentsector.address)
    {
        fs->currentsector.address = lba;
        return media_read_ak(fs->currentsector.address, fs->currentsector.sector, 512);
    }
    else
        return 1;
}
static int _write_sector(FL_FILE* file, UINT32 offset, unsigned char *buf)
{
	UINT32 SectorNumber = 0;
	UINT32 ClusterIdx = 0;
	UINT32 Cluster = 0;
	UINT32 LastCluster = FAT32_LAST_CLUSTER;
	UINT32 i;

	// Find values for Cluster index & sector within cluster
	ClusterIdx = offset / _fs.sectors_per_cluster;	  
	SectorNumber = offset - (ClusterIdx * _fs.sectors_per_cluster);

	// Quick lookup for next link in the chain
	if (ClusterIdx == file->last_fat_lookup.ClusterIdx)
		Cluster = file->last_fat_lookup.CurrentCluster;
	// Else walk the chain
	else
	{
		// Starting from last recorded cluster?
		if (ClusterIdx && ClusterIdx == file->last_fat_lookup.ClusterIdx + 1)
		{
			i = file->last_fat_lookup.ClusterIdx;
			Cluster = file->last_fat_lookup.CurrentCluster;
		}
		// Start searching from the beginning..
		else
		{
			// Set start of cluster chain to initial value
			i = 0;
			Cluster = file->startcluster;
		}

		// Follow chain to find cluster to read
		for ( ;i<ClusterIdx; i++)
		{
			UINT32 nextCluster;
			
			// Does the entry exist in the cache?
			if (!fatfs_cache_get_next_cluster(&_fs, file, i, &nextCluster))			
			{
				// Scan file linked list to find next entry
				nextCluster = fatfs_find_next_cluster(&_fs, Cluster);

				// Push entry into cache
				fatfs_cache_set_next_cluster(&_fs, file, i, nextCluster);
			}			

			LastCluster = Cluster;
			Cluster = nextCluster;

			// Dont keep following a dead end
			if (Cluster == FAT32_LAST_CLUSTER)
				break;
		}

		// If we have reached the end of the chain, allocate more!
		if (Cluster == FAT32_LAST_CLUSTER)
		{
			// Add another cluster to the last good cluster chain
			if (!fatfs_add_free_space(&_fs, &LastCluster))
				return 0;

			Cluster = LastCluster;
		}

		// Record current cluster lookup details
		file->last_fat_lookup.CurrentCluster = Cluster;
		file->last_fat_lookup.ClusterIdx = ClusterIdx;
	}

	return fatfs_write_sector(&_fs, Cluster, SectorNumber, buf);
}
//-----------------------------------------------------------------------------
// _read_sector: Read a sector from disk to file
//-----------------------------------------------------------------------------
static int _read_sector(FL_FILE* file, UINT32 offset)
{
	UINT32 Sector = 0;
	UINT32 ClusterIdx = 0;
	UINT32 Cluster = 0;
	UINT32 i;
	UINT32 lba;

	// Find cluster index within file & sector with cluster
	ClusterIdx = offset / _fs.sectors_per_cluster;	  
	Sector = offset - (ClusterIdx * _fs.sectors_per_cluster);

	// Quick lookup for next link in the chain
	if (ClusterIdx == file->last_fat_lookup.ClusterIdx)
		Cluster = file->last_fat_lookup.CurrentCluster;
	// Else walk the chain
	else
	{
		// Starting from last recorded cluster?
		if (ClusterIdx && ClusterIdx == file->last_fat_lookup.ClusterIdx + 1)
		{
			i = file->last_fat_lookup.ClusterIdx;
			Cluster = file->last_fat_lookup.CurrentCluster;
		}
		// Start searching from the beginning..
		else
		{
			// Set start of cluster chain to initial value
			i = 0;
			Cluster = file->startcluster;					
		}

		// Follow chain to find cluster to read
		for ( ;i<ClusterIdx; i++)
		{
			UINT32 nextCluster;
			
			// Does the entry exist in the cache?
			if (!fatfs_cache_get_next_cluster(&_fs, file, i, &nextCluster))			
			{
				// Scan file linked list to find next entry
				nextCluster = fatfs_find_next_cluster(&_fs, Cluster);

				// Push entry into cache
				fatfs_cache_set_next_cluster(&_fs, file, i, nextCluster);
			}			

			Cluster = nextCluster;
		}

		// Record current cluster lookup details (if valid)
		if (Cluster != FAT32_LAST_CLUSTER)
		{
			file->last_fat_lookup.CurrentCluster = Cluster;
			file->last_fat_lookup.ClusterIdx = ClusterIdx;
		}
	}

	// If end of cluster chain then return false
	if (Cluster == FAT32_LAST_CLUSTER) 
		return 0;

	// Calculate sector address
	lba = fatfs_lba_of_cluster(&_fs, Cluster) + Sector;

	// Read sector of file
	return fatfs_sector_read(&_fs, lba, file->file_data.sector);
}