⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sma_fat16.c

📁 sharp的arm920t 7A400的评估板附带光盘Sharp KEVLH7A400 v0.3b Welcome to the SHARP KEV7A400 Evaluation board
💻 C
📖 第 1 页 / 共 4 页
字号:
            HDN_SECS_SZ);
        fat16_moveto (&data [LG_SECS_OFS], &fg->large_sectors,
            LG_SECS_SZ);
        fat16_moveto (&data [DV_NUM_OFS], &fg->drive_number, DV_NUM_SZ);
        fat16_moveto (&data [RSV_OFS], &fg->reserved, RSV_SZ);
        fat16_moveto (&data [BT_SIG_OFS], &fg->ext_boot_sig, BT_SIG_SZ);
        fat16_moveto (&data [SERNUM_OFS], &fg->serial_number, SERNUM_SZ);
        fat16_moveto (&data [LABEL_OFS], &fg->label, LABEL_SZ);
        fat16_moveto (&data [FSNAME_OFS], &fg->fs_name, FSNAME_SZ);

        // Compute the first sector in the partition (fatgeom)
        fat_data->cfat.first_boot_sector =
            fat_data->part [partnum].mbr_sec_offset;

        // Compute reserved sectors
        fat_data->cfat.boot_sectors = fat_data->pat_hdr.res_sectors;

        // Compute sectors used for a single FAT
        fat_data->cfat.fat_sectors = fat_data->pat_hdr.sectors_fat;

        // Compute location of first and last FAT(1) sectors
        fat_data->cfat.first_fat1_sector =
            fat_data->cfat.first_boot_sector +
            fat_data->cfat.boot_sectors;
        fat_data->cfat.last_fat1_sector =
            fat_data->cfat.first_fat1_sector +
            fat_data->cfat.fat_sectors - 1;

        // Compute location of first and last FAT(2) sectors. This may
        // not exist in all implementations
        fat_data->cfat.first_fat2_sector =
            fat_data->cfat.last_fat1_sector + 1;
        fat_data->cfat.last_fat2_sector =
            fat_data->cfat.first_fat2_sector +
            fat_data->cfat.fat_sectors - 1;

        // Compute location of the root directory and # of root sectors
        fat_data->cfat.first_root_sector = 
            fat_data->cfat.first_fat1_sector +
            (fat_data->cfat.fat_sectors *
            fat_data->pat_hdr.fat_copies);
        fat_data->cfat.root_sectors = (fat_data->pat_hdr.root_entries *
            sizeof (root_entry_type) / fat_data->pat_hdr.bytes_sector);

        // Compute total number of sectors
        fat_data->cfat.total_sectors = fat_data->pat_hdr.small_sectors;
        if (fat_data->cfat.total_sectors == 0)
        {
            fat_data->cfat.total_sectors =
                fat_data->pat_hdr.large_sectors;
        }

        // Compute location of the first data sector
        fat_data->cfat.first_data_sector =
            fat_data->cfat.first_root_sector +
            fat_data->cfat.root_sectors;

        // Compute total number of data sectors
        fat_data->cfat.data_sectors = fat_data->cfat.total_sectors -
            fat_data->cfat.root_sectors - (fat_data->cfat.fat_sectors *
            (UNS_32) fat_data->pat_hdr.fat_copies) -
            fat_data->cfat.boot_sectors;

        // Compute the number of data clusters available
        fat_data->cfat.clusters = fat_data->cfat.data_sectors /
            fat_data->pat_hdr.sectors_cluster;

        // Compute the total size of the device partition
        fat_data->cfat.total_size = fat_data->cfat.total_sectors *
            fat_data->pat_hdr.bytes_sector;

        // Save computed cluster size (in bytes)
        fat_data->cfat.cluster_size =
            (UNS_16) fat_data->pat_hdr.sectors_cluster *
            (UNS_16) fat_data->pat_hdr.bytes_sector;

        // Compute the required size of the file cluster table
        table_size = (UNS_32) (fat_data->cfat.fat_sectors *
            (UNS_32) fat_data->pat_hdr.bytes_sector);
        fat_data->clusters = (UNS_16 *) malloc (table_size);

        // Read cluster data into file cluster table
        fat16_read_sectors (fat_data, fat_data->clusters,
            fat_data->cfat.first_fat1_sector,
            fat_data->cfat.fat_sectors);

        // Save new active partition number
        fat_data->act_part = (INT_8) partnum;

        // Valid operation
        valid = 1;
    }

    return valid;
}

/***********************************************************************
 *
 * Function: fat16_create_new_file_descriptor
 *
 * Purpose:
 *  Creates a file structure with the device and FAT data.
 *
 * Processing:
 *  Allocates memory for a new file descriptor. Sets the initial file
 *  mode to FINVALID. Links the FAT device structure to the file
 *  descriptor. Sets up and caches the default directory used with the
 *  file descriptor as the root directory with an initial directory
 *  index at the start of the directory table. Allocates space for
 *  data storage during file operations (read/write).
 *
 * Parameters:
 *  fat_data  : Pointer to a FAT device structure
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  A pointer to a new file descriptor or NULL if there was not enough
 *  memory available.
 *
 * Notes:
 *  None
 *
 **********************************************************************/
file_type * fat16_create_new_file_descriptor (fat_device_type *fat_data)
{
    file_type *file_data;
    UNS_32 table_size;

    // Allocate a new file data structure
    file_data = malloc (sizeof (file_type));
    if (file_data != (file_type *) NULL)
    {
        // Mode is initially invalid
        file_data->fmode = FINVALID;

        // Save binded FAT/device structure
        file_data->fat_data = fat_data;

        // Set the default startup directory to 'root'
        file_data->sector_dir = fat_data->cfat.first_root_sector;

        // Create data buffer pointer and clear buffer index
        file_data->data = (UNS_8 *) malloc ((INT_32)
            file_data->fat_data->cfat.cluster_size);

        // Compute required size of the directory listing and
        // allocate a new directory table
        table_size = fat_data->cfat.root_sectors *
            (UNS_32) fat_data->pat_hdr.bytes_sector;
        file_data->dir_data = (root_entry_type *) malloc (
            table_size);

        // Cache in the directory table
        fat16_read_sectors (fat_data, file_data->dir_data,
            file_data->sector_dir, fat_data->cfat.root_sectors);

        // Clear initial directory index
        file_data->dir_index = 0;

        // Initial directory is unchanged
        file_data->dir_commit = 0;
    }

    return file_data;
}

/***********************************************************************
 *
 * Function: fat16_destroy_file_descriptor
 *
 * Purpose:
 *  Destroys a created file descriptor.
 *
 * Processing:
 *  Prior to destroying the file descriptor, a call to fat16_close is
 *  performed to write any data in the write buffer out to the device.
 *  If the directory has been changed in any way, the cached directory
 *  is written back to the device. The structures used in the file
 *  descriptor and the file descriptor itself are then de-allocated.
 *
 * Parameters:
 *  file_data : Pointer to a file descriptor to free.
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  Nothing
 *
 * Notes:
 *  None
 *
 **********************************************************************/
void fat16_destroy_file_descriptor (file_type *file_data)
{
    if (file_data != NULL)
    {
        // Close an open file
        fat16_close_file (file_data);

        // Write the active directory back to the device is it has
        // changed
        if (file_data->dir_commit == 1)
        {
            fat16_write_sectors (file_data->fat_data,
                file_data->dir_data, file_data->sector_dir,
                file_data->fat_data->cfat.root_sectors);
        }

        // Destroy the data and directory
        free (file_data->data);
        free (file_data->dir_data);

        // Destroy the file data structure
        free (file_data);
    }
}

/***********************************************************************
 *
 * Function: fat16_cd
 *
 * Purpose:
 *  Set the active directory.
 *
 * Processing:
 *  Prior to any operations, the current directory index data is saved.
 *  If the first character is a '/', the directory pointer is set to
 *  the root directory. If the dir_commit flag is set, the cached
 *  directory will be written back to the device before the change.
 *
 *  The next name in the path will then be parsed. The active directory
 *  will be searched for the name. If the name is found, the cluster
 *  number to the new directory will be fetched and the new directory
 *  cached in. This process continues for all parsed names. If no errors
 *  occurred, the active directory index is updated to the new index.
 *  If an error occurred, the original directory and index are restored.
 *
 * Parameters:
 *  path      : Path of new directory
 *  file_data : Pointer to a FILE data structure to populate
 *
 * Outputs:
 *  Data in file_data will be updated.
 *
 * Returns:
 *  '1' if the operation was successful, '0' otherwise.
 *
 * Notes:
 *  None
 *
 **********************************************************************/
INT_32 fat16_cd (CHAR *path, file_type *file_data)
{
    CHAR dirname [16];
    INT_32 previous_dir, previous_dir_index, dir_index;
    INT_32 size = 0;
    INT_32 valid = 0;
    INT_32 index = 0;

    // Save previous path and index, in case this operation fails
    previous_dir = file_data->sector_dir;
    previous_dir_index = file_data->dir_index;

    // Reset path to root if first character in the pathname is '/'
    if (path [index] == '/')
    {

        // Before caching in new directory, rewrite the old  directory
        // back to the device if the directory has changed
        if (file_data->dir_commit == 1)
        {
            fat16_write_sectors (file_data->fat_data,
                file_data->dir_data, file_data->sector_dir,
                file_data->fat_data->cfat.root_sectors);
            file_data->dir_commit = 0;
        }

        // Set the default startup directory to 'root'
        file_data->sector_dir =
            file_data->fat_data->cfat.first_root_sector;
        file_data->dir_index = 0;

        // Cache in the new directory table
        fat16_read_sectors (file_data->fat_data,
            file_data->dir_data, file_data->sector_dir,
            file_data->fat_data->cfat.root_sectors);

        index = 1;
        valid = 1;
    }

    // More data in the path name
    if (path [1] != '\0')
    {
        valid = 1;

        // Get the next directory name
        size = fat16_parse_path (&path [index]);
        while (size > 0)
        {
            // A valid name was found, copy name locally with terminator
            fat16_moveto (&path [index], dirname, size);
            dirname [size] = '\0';

            dir_index = fat16_find_file (dirname, file_data);
            if (dir_index == -1)
            {
                // Path/directory was not found, so quit
                valid = 0;
                size = -1;
            }
            // Only switch directories if it actually is a directory
            else if (
                file_data->dir_data [dir_index].attribute == ATTB_DIR)
            {
                // Before caching in new directory, rewrite the old
                // directory back to the device if the directory has
                // changed
                if (file_data->dir_commit == 1)
                {
                    fat16_write_sectors (file_data->fat_data,
                        file_data->dir_data, file_data->sector_dir,
                        file_data->fat_data->cfat.root_sectors);
                    file_data->dir_commit = 0;
                }

                // Good so far, set file directory pointer to new
                // directory table
                file_data->sector_dir =
                    fat16_translate_cluster_to_sector (
                    file_data->fat_data,
                    file_data->dir_data [dir_index].clusternum);
                file_data->dir_index = 0;

               // Cache in the new directory table
               fat16_read_sectors (file_data->fat_data,
                   file_data->dir_data, file_data->sector_dir,
                   file_data->fat_data->cfat.root_sectors);

                // Update index, skip past delimiters
                index = index + size;
                if (path [index] == '/')
                {
                    index++;
                }

                // Check next field
                size = fat16_parse_path (&path [index]);
            }
            else
            {
                // Check next field
                size = fat16_parse_path (&path [index]);
            }
        }
    }

    if ((valid == 0) || (size < 0))
    {
        // Restore previous directory if needed
        if (file_data->sector_dir != previous_dir)
        {
            // Error somewhere, restore previous path and index
            file_data->sector_dir = previous_dir;
            file_data->dir_index = previous_dir_index;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -