stream-like access added
This commit is contained in:
		
							parent
							
								
									de52ac5d35
								
							
						
					
					
						commit
						8b8dcbe170
					
				
							
								
								
									
										179
									
								
								fs/fat32/fat32.c
									
									
									
									
									
								
							
							
						
						
									
										179
									
								
								fs/fat32/fat32.c
									
									
									
									
									
								
							@ -236,11 +236,12 @@ static inline uint32_t fat32_get_first_cluster(const Fat32_FileEntry *entry) {
 | 
				
			|||||||
 * The function locates a file based on its full path.
 | 
					 * The function locates a file based on its full path.
 | 
				
			||||||
 * @param ctrl pointer to a FAT32 control block
 | 
					 * @param ctrl pointer to a FAT32 control block
 | 
				
			||||||
 * @param path full path of the file to be located
 | 
					 * @param path full path of the file to be located
 | 
				
			||||||
 | 
					 * @param file_entry_ba if not NULL, then the function returns here the file entry's byte address (on the mass storage); untouched if file not found
 | 
				
			||||||
 * @return pointer to the file entry. Caution! This pointer is only valid until no further
 | 
					 * @return pointer to the file entry. Caution! This pointer is only valid until no further
 | 
				
			||||||
 * call is made to fat32_* functions, since all functions involve the same buffer.
 | 
					 * call is made to fat32_* functions, since all functions involve the same buffer.
 | 
				
			||||||
 * Functions invalidating buffer content are marked with (I).
 | 
					 * Functions invalidating buffer content are marked with (I).
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
const Fat32_FileEntry *fat32_locate_file(const Fat32_CtrlBlock *ctrl, const char *path) {
 | 
					const Fat32_FileEntry *fat32_locate_file(const Fat32_CtrlBlock *ctrl, const char *path, uint32_t *file_entry_ba) {
 | 
				
			||||||
    FETCH_MSTG;
 | 
					    FETCH_MSTG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // start search in the root directory
 | 
					    // start search in the root directory
 | 
				
			||||||
@ -256,7 +257,7 @@ const Fat32_FileEntry *fat32_locate_file(const Fat32_CtrlBlock *ctrl, const char
 | 
				
			|||||||
    char entry_name[FAT32_MAX_BASENAME_LENGTH + 1]; // entry name
 | 
					    char entry_name[FAT32_MAX_BASENAME_LENGTH + 1]; // entry name
 | 
				
			||||||
    Fat32_FileEntry *entry = NULL; // entry iterator
 | 
					    Fat32_FileEntry *entry = NULL; // entry iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while ((!file_found) && (!no_such_file)) {
 | 
					    while ((!file_found) && (!no_such_file)) { // traversing tree levels
 | 
				
			||||||
        // extract first basename
 | 
					        // extract first basename
 | 
				
			||||||
        uint16_t basename_len = fat32_extract_next_basename_length(path_iter); // get basename length
 | 
					        uint16_t basename_len = fat32_extract_next_basename_length(path_iter); // get basename length
 | 
				
			||||||
        uint16_t copy_len = MIN(basename_len, FAT32_MAX_BASENAME_LENGTH);
 | 
					        uint16_t copy_len = MIN(basename_len, FAT32_MAX_BASENAME_LENGTH);
 | 
				
			||||||
@ -271,7 +272,7 @@ const Fat32_FileEntry *fat32_locate_file(const Fat32_CtrlBlock *ctrl, const char
 | 
				
			|||||||
        // acquire pointer to the beginning of the file entry table
 | 
					        // acquire pointer to the beginning of the file entry table
 | 
				
			||||||
        entry = (Fat32_FileEntry *) buffer;
 | 
					        entry = (Fat32_FileEntry *) buffer;
 | 
				
			||||||
        bool basename_entry_found = false;
 | 
					        bool basename_entry_found = false;
 | 
				
			||||||
        while ((entry->short_fname[0] != 0x00) && (!basename_entry_found)) {
 | 
					        while ((entry->short_fname[0] != 0x00) && (!basename_entry_found)) { // traversing siblings
 | 
				
			||||||
            if (entry->short_fname[0] != FAT32_UNUSED_FILE_ENTRY) {
 | 
					            if (entry->short_fname[0] != FAT32_UNUSED_FILE_ENTRY) {
 | 
				
			||||||
                fat32_get_file_entry(&entry, entry_name);
 | 
					                fat32_get_file_entry(&entry, entry_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -304,6 +305,9 @@ const Fat32_FileEntry *fat32_locate_file(const Fat32_CtrlBlock *ctrl, const char
 | 
				
			|||||||
        if (basename_entry_found) {
 | 
					        if (basename_entry_found) {
 | 
				
			||||||
            if (path_iter[0] == '\0') { // ...and it's the end of the path
 | 
					            if (path_iter[0] == '\0') { // ...and it's the end of the path
 | 
				
			||||||
                file_found = true; // ...then the file is found
 | 
					                file_found = true; // ...then the file is found
 | 
				
			||||||
 | 
					                if (file_entry_ba != NULL) { // if file entry writeback address if provided
 | 
				
			||||||
 | 
					                    *file_entry_ba = sector * ctrl->bytes_per_sector + (((uint8_t *) entry) - buffer);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            } else { // ...if it's not the end of the path, then load the cluster corresponding to the entry
 | 
					            } else { // ...if it's not the end of the path, then load the cluster corresponding to the entry
 | 
				
			||||||
                // determine sector number
 | 
					                // determine sector number
 | 
				
			||||||
                uint32_t next_cluster = fat32_get_first_cluster(entry);
 | 
					                uint32_t next_cluster = fat32_get_first_cluster(entry);
 | 
				
			||||||
@ -312,6 +316,8 @@ const Fat32_FileEntry *fat32_locate_file(const Fat32_CtrlBlock *ctrl, const char
 | 
				
			|||||||
                // load sectors
 | 
					                // load sectors
 | 
				
			||||||
                READ_MSTG_TO_FIRST_BUFFER(next_sector);
 | 
					                READ_MSTG_TO_FIRST_BUFFER(next_sector);
 | 
				
			||||||
                READ_MSTG_TO_SECOND_BUFFER(next_sector + 1);
 | 
					                READ_MSTG_TO_SECOND_BUFFER(next_sector + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                sector = next_sector; // advance sector
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else { // if not found...
 | 
					        } else { // if not found...
 | 
				
			||||||
            no_such_file = true; // ...then the file could not be located
 | 
					            no_such_file = true; // ...then the file could not be located
 | 
				
			||||||
@ -362,6 +368,30 @@ int fat32_list_dir(const Fat32_CtrlBlock *ctrl, const char *dir) {
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Get the sequence number of the sector holding the byte pointed by address.
 | 
				
			||||||
 | 
					 * @param ctrl pointer to FAT32 control block
 | 
				
			||||||
 | 
					 * @param address byte address
 | 
				
			||||||
 | 
					 * @return sequence number of the requested sector
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline uint32_t fat32_get_sector_by_byte_address(const Fat32_CtrlBlock *ctrl, uint32_t ba) {
 | 
				
			||||||
 | 
					    return ba / ctrl->bytes_per_sector;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Get file entry based on its byte address. (I)
 | 
				
			||||||
 | 
					 * @param ctrl pointer to FAT32 control block
 | 
				
			||||||
 | 
					 * @param ba byte address of the file entry
 | 
				
			||||||
 | 
					 * @return pointer to file entry
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline const Fat32_FileEntry * fat32_get_file_entry_by_byte_address(const Fat32_CtrlBlock * ctrl, uint32_t ba) {
 | 
				
			||||||
 | 
					    uint32_t sector = fat32_get_sector_by_byte_address(ctrl, ba);
 | 
				
			||||||
 | 
					    uint32_t offset = ba % ctrl->bytes_per_sector;
 | 
				
			||||||
 | 
					    FETCH_MSTG;
 | 
				
			||||||
 | 
					    READ_MSTG_TO_FIRST_BUFFER(sector);
 | 
				
			||||||
 | 
					    return (Fat32_FileEntry *)(buffer + offset);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Get the sector's sequence number corresponding to the specific cluster identified by its sequence number.
 | 
					 * Get the sector's sequence number corresponding to the specific cluster identified by its sequence number.
 | 
				
			||||||
 * @param ctrl pointer to FAT32 control block
 | 
					 * @param ctrl pointer to FAT32 control block
 | 
				
			||||||
@ -373,7 +403,7 @@ static inline uint32_t fat32_get_fat_entry_sector_by_cluster_index(const Fat32_C
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Gets the sequence number of the next chained cluster. (I)
 | 
					 * Get the sequence number of the next chained cluster. (I)
 | 
				
			||||||
 * @param ctrl pointer to FAT32 control block
 | 
					 * @param ctrl pointer to FAT32 control block
 | 
				
			||||||
 * @param cluster sequence number of a cluster
 | 
					 * @param cluster sequence number of a cluster
 | 
				
			||||||
 * @return sequence number of the cluster following the passed one in the chain
 | 
					 * @return sequence number of the cluster following the passed one in the chain
 | 
				
			||||||
@ -388,7 +418,7 @@ static inline uint32_t fat32_get_next_chained_cluster(const Fat32_CtrlBlock *ctr
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Get sequence number of the cluster storing a specific byte position (pos) if the file's first cluster is given.
 | 
					 * Get sequence number of the cluster storing a specific byte position (pos) if the file's first cluster is given. (I)
 | 
				
			||||||
 * @param ctrl pointer to FAT32 control block
 | 
					 * @param ctrl pointer to FAT32 control block
 | 
				
			||||||
 * @param first_cluster sequence number of the first cluster of the file
 | 
					 * @param first_cluster sequence number of the first cluster of the file
 | 
				
			||||||
 * @param pos byte position
 | 
					 * @param pos byte position
 | 
				
			||||||
@ -426,7 +456,8 @@ static inline uint32_t fat32_get_bytes_per_cluster(const Fat32_CtrlBlock *ctrl)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Read a file using "random access".
 | 
					 * Read a file using "random access". (I)
 | 
				
			||||||
 | 
					 * This function holds a load of redundant code, but this is with intent.
 | 
				
			||||||
 * @param ctrl pointer to FAT32 control block
 | 
					 * @param ctrl pointer to FAT32 control block
 | 
				
			||||||
 * @param entry pointer to the corresponding file entry
 | 
					 * @param entry pointer to the corresponding file entry
 | 
				
			||||||
 * @param pos read start position
 | 
					 * @param pos read start position
 | 
				
			||||||
@ -434,7 +465,7 @@ static inline uint32_t fat32_get_bytes_per_cluster(const Fat32_CtrlBlock *ctrl)
 | 
				
			|||||||
 * @param p pointer to output buffer
 | 
					 * @param p pointer to output buffer
 | 
				
			||||||
 * @return the number of bytes read
 | 
					 * @return the number of bytes read
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
uint32_t fat32_read_file(const Fat32_CtrlBlock *ctrl, const Fat32_FileEntry *entry, uint32_t pos, uint32_t len, uint8_t *p) {
 | 
					uint32_t fat32_read_file_random_access(const Fat32_CtrlBlock *ctrl, const Fat32_FileEntry *entry, uint32_t pos, uint32_t len, uint8_t *p) {
 | 
				
			||||||
    // check position validity and check that the entry corresponds to a file, not to a directory or volume
 | 
					    // check position validity and check that the entry corresponds to a file, not to a directory or volume
 | 
				
			||||||
    uint8_t attr = entry->attributes;
 | 
					    uint8_t attr = entry->attributes;
 | 
				
			||||||
    if ((pos >= entry->size) || (attr & FAT32_FATT_DIRECTORY) || (attr & FAT32_FATT_VOLUME)) {
 | 
					    if ((pos >= entry->size) || (attr & FAT32_FATT_DIRECTORY) || (attr & FAT32_FATT_VOLUME)) {
 | 
				
			||||||
@ -490,3 +521,137 @@ uint32_t fat32_read_file(const Fat32_CtrlBlock *ctrl, const Fat32_FileEntry *ent
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return read_len;
 | 
					    return read_len;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int fat32_open_file(const Fat32_CtrlBlock *ctrl, const char *path, Fat32_FileHelper *file_helper) {
 | 
				
			||||||
 | 
					    uint32_t file_entry_ba;
 | 
				
			||||||
 | 
					    const Fat32_FileEntry *entry = fat32_locate_file(ctrl, path, &file_entry_ba);
 | 
				
			||||||
 | 
					    uint32_t first_cluster = fat32_get_first_cluster(entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // store data usable for identifying file on the storage
 | 
				
			||||||
 | 
					    file_helper->ctrl = ctrl;
 | 
				
			||||||
 | 
					    file_helper->entry_ba = file_entry_ba;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // store file information
 | 
				
			||||||
 | 
					    file_helper->size = entry->size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // seek to zero
 | 
				
			||||||
 | 
					    file_helper->last_pos.pos = 0;
 | 
				
			||||||
 | 
					    file_helper->last_pos.sector_begin_pos = 0;
 | 
				
			||||||
 | 
					    file_helper->last_pos.cluster = first_cluster;
 | 
				
			||||||
 | 
					    file_helper->last_pos.sector = fat32_get_first_sector_of_cluster(ctrl, first_cluster);
 | 
				
			||||||
 | 
					    file_helper->last_pos.sector_of_cluster = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Seek file stream, set reader to pos.
 | 
				
			||||||
 | 
					 * @param ctrl pointer to FAT32 control block
 | 
				
			||||||
 | 
					 * @param pos stream position
 | 
				
			||||||
 | 
					 * @param file_helper pointer to file helper, which gets updated
 | 
				
			||||||
 | 
					 * @return 0 on success
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint32_t fat32_seek_stream(const Fat32_CtrlBlock *ctrl, uint32_t pos, Fat32_FileHelper *file_helper) {
 | 
				
			||||||
 | 
					    // check that we are not attempting to seek out of the file
 | 
				
			||||||
 | 
					    if (pos >= file_helper->size) {
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // actual seeking
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Fat32_SeekHint *seek_hint = &file_helper->last_pos; // fetch seek hint
 | 
				
			||||||
 | 
					    if (pos > file_helper->last_pos.pos) { // if seeking forward, then seeking can be accelerated using the seek hints
 | 
				
			||||||
 | 
					        uint32_t delta = pos - file_helper->last_pos.pos;
 | 
				
			||||||
 | 
					        uint32_t bytes_to_sector_end = ctrl->bytes_per_sector - (file_helper->last_pos.pos % ctrl->bytes_per_sector); // determine byte count to sector end
 | 
				
			||||||
 | 
					        if (delta < bytes_to_sector_end) { // if seeking does not cross sector boundary
 | 
				
			||||||
 | 
					            seek_hint->pos = pos; // just change position
 | 
				
			||||||
 | 
					        } else { // ...if crosses sector boundary
 | 
				
			||||||
 | 
					            uint32_t sector_boundaries_crossed = 1 + (delta - bytes_to_sector_end) / ctrl->bytes_per_sector; // 1: boundary crossed; further boundaries crossed based on delta
 | 
				
			||||||
 | 
					            uint32_t delta_sector_from_clusters_first_sector = seek_hint->sector_of_cluster + sector_boundaries_crossed;
 | 
				
			||||||
 | 
					            uint32_t cluster_boundaries_crossed = delta_sector_from_clusters_first_sector / ctrl->sectors_per_cluster; // number of cluster boundary crossing
 | 
				
			||||||
 | 
					            if (cluster_boundaries_crossed > 0) { // if we crossed a cluster boundary, then load the next cluster's first sector in chain
 | 
				
			||||||
 | 
					                uint32_t cluster = seek_hint->cluster;
 | 
				
			||||||
 | 
					                for (uint32_t i = 0; i < cluster_boundaries_crossed; i++) { // do the cluster crossings
 | 
				
			||||||
 | 
					                    cluster = fat32_get_next_chained_cluster(ctrl, cluster); // get next cluster
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // update position fields
 | 
				
			||||||
 | 
					                seek_hint->cluster = cluster;
 | 
				
			||||||
 | 
					                seek_hint->sector_of_cluster = delta_sector_from_clusters_first_sector % ctrl->sectors_per_cluster;
 | 
				
			||||||
 | 
					                seek_hint->sector += sector_boundaries_crossed;
 | 
				
			||||||
 | 
					                seek_hint->pos = pos;
 | 
				
			||||||
 | 
					                seek_hint->sector_begin_pos += sector_boundaries_crossed * ctrl->bytes_per_sector;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else { // if seeking backwards, then no acceleration is available
 | 
				
			||||||
 | 
					        const Fat32_FileEntry * entry = fat32_get_file_entry_by_byte_address(ctrl, file_helper->entry_ba); // fetch file entry
 | 
				
			||||||
 | 
					        uint32_t first_cluster = fat32_get_first_cluster(entry); // get first cluster of the entry
 | 
				
			||||||
 | 
					        uint32_t cluster = fat32_get_cluster_from_pos(ctrl, first_cluster, pos); // get cluster sequence number of the file using the read position
 | 
				
			||||||
 | 
					        uint32_t first_sector = fat32_get_first_sector_of_cluster(ctrl, cluster); // get the first sector of the cluster
 | 
				
			||||||
 | 
					        uint32_t bytes_per_cluster = fat32_get_bytes_per_cluster(ctrl); // get number of bytes per cluster
 | 
				
			||||||
 | 
					        uint32_t pos_in_cluster = pos % bytes_per_cluster; // transform read position to a relative read position from the cluster beginning
 | 
				
			||||||
 | 
					        uint32_t sector_of_cluster = pos_in_cluster / ctrl->bytes_per_sector; // get the sequence number of sector in the cluster that will be read
 | 
				
			||||||
 | 
					        uint32_t sector = first_sector + sector_of_cluster; // offset the sectors based on relative read position
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // update position fields
 | 
				
			||||||
 | 
					        seek_hint->pos = pos;
 | 
				
			||||||
 | 
					        seek_hint->sector_of_cluster = sector_of_cluster;
 | 
				
			||||||
 | 
					        seek_hint->cluster = cluster;
 | 
				
			||||||
 | 
					        seek_hint->sector = first_sector + sector_of_cluster;
 | 
				
			||||||
 | 
					        seek_hint->sector_begin_pos = pos - (pos % ctrl->bytes_per_sector);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t fat32_read_file_stream(const Fat32_CtrlBlock *ctrl, Fat32_FileHelper *file_helper, uint32_t len, uint8_t *p) {
 | 
				
			||||||
 | 
					    FETCH_MSTG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Fat32_SeekHint * seek_hint = &file_helper->last_pos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint32_t pos_in_sector = seek_hint->pos - seek_hint->sector_begin_pos; // determine position in current sector
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    READ_MSTG_TO_FIRST_BUFFER(seek_hint->sector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // cap length, don't read after the end of the file
 | 
				
			||||||
 | 
					    uint32_t read_len = MIN(len, file_helper->size - seek_hint->pos);
 | 
				
			||||||
 | 
					    uint32_t offset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // reading from a file may involve reading across cluster boundaries
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 1. read the beginning from the first cluster
 | 
				
			||||||
 | 
					    uint32_t first_read_len = MIN(read_len, ctrl->bytes_per_sector - seek_hint->pos);
 | 
				
			||||||
 | 
					    memcpy(p, buffer + pos_in_sector, first_read_len);
 | 
				
			||||||
 | 
					    read_len -= first_read_len; // decrease the total read len with the number of bytes read from the first sector of the file
 | 
				
			||||||
 | 
					    offset += first_read_len; // advance offset
 | 
				
			||||||
 | 
					    seek_hint->pos += first_read_len; // advance seek pos
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 2. read from intermediate sectors and read from the final sector
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // if the remaining read length is non-zero, then maintain buffered sectors
 | 
				
			||||||
 | 
					    while (read_len > 0) {
 | 
				
			||||||
 | 
					        seek_hint->sector_of_cluster++; // increase sector index
 | 
				
			||||||
 | 
					        if (seek_hint->sector_of_cluster >= ctrl->sectors_per_cluster) { // if we crossed a cluster boundary, then load the next cluster's first sector in chain
 | 
				
			||||||
 | 
					            seek_hint->cluster = fat32_get_next_chained_cluster(ctrl, seek_hint->cluster); // get next cluster
 | 
				
			||||||
 | 
					            seek_hint->sector = fat32_get_first_sector_of_cluster(ctrl, seek_hint->cluster);
 | 
				
			||||||
 | 
					            seek_hint->sector_of_cluster = 0; // it's the zeroth sector of the cluster
 | 
				
			||||||
 | 
					            READ_MSTG_TO_FIRST_BUFFER(seek_hint->sector); // load the newly determined cluster's first sector
 | 
				
			||||||
 | 
					        } else { // if we didn't cross a cluster boundary, then...
 | 
				
			||||||
 | 
					            seek_hint->sector++; //...just increase the sector count
 | 
				
			||||||
 | 
					            READ_MSTG_TO_FIRST_BUFFER(seek_hint->sector); // ...and load that sector
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        seek_hint->sector_begin_pos += ctrl->bytes_per_sector; // advance begin position, we have stepped one sector forward
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // copy the whole sector or some portion of the sector counting from the sector's begin
 | 
				
			||||||
 | 
					        uint32_t copy_size = MIN(ctrl->bytes_per_sector, read_len);
 | 
				
			||||||
 | 
					        memcpy(p + offset, buffer, copy_size);
 | 
				
			||||||
 | 
					        read_len -= copy_size;
 | 
				
			||||||
 | 
					        offset += copy_size;
 | 
				
			||||||
 | 
					        seek_hint->pos += copy_size;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return read_len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -95,21 +95,29 @@ typedef struct {
 | 
				
			|||||||
    uint32_t pos; // byte position
 | 
					    uint32_t pos; // byte position
 | 
				
			||||||
    uint32_t cluster; // cluster corresponding to the position
 | 
					    uint32_t cluster; // cluster corresponding to the position
 | 
				
			||||||
    uint32_t sector; // sector of the last read
 | 
					    uint32_t sector; // sector of the last read
 | 
				
			||||||
 | 
					    uint32_t sector_of_cluster; // sequence number of sector in the current cluster
 | 
				
			||||||
    uint32_t sector_begin_pos; // byte position of the sector's begin
 | 
					    uint32_t sector_begin_pos; // byte position of the sector's begin
 | 
				
			||||||
} Fat32_SeekHint;
 | 
					} Fat32_SeekHint;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    Fat32_CtrlBlock * ctrl; // pointer FAT32 control block
 | 
					    const Fat32_CtrlBlock * ctrl; // pointer FAT32 control block
 | 
				
			||||||
    Fat32_SeekHint last_pos; // last read position
 | 
					    Fat32_SeekHint last_pos; // last read position
 | 
				
			||||||
    uint32_t entry_pos; // FileEntry byte position
 | 
					    uint32_t entry_ba; // FileEntry byte address on the mass storage
 | 
				
			||||||
 | 
					    uint32_t size; // file size
 | 
				
			||||||
} Fat32_FileHelper;
 | 
					} Fat32_FileHelper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int fat32_load(Fat32_CtrlBlock *ctrl, uint32_t bpb_s, const MassStorage * mstg);
 | 
					int fat32_load(Fat32_CtrlBlock *ctrl, uint32_t bpb_s, const MassStorage * mstg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int fat32_list_dir(const Fat32_CtrlBlock *ctrl, const char * dir);
 | 
					int fat32_list_dir(const Fat32_CtrlBlock *ctrl, const char * dir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint32_t fat32_read_file(const Fat32_CtrlBlock * ctrl, const Fat32_FileEntry * entry, uint32_t pos, uint32_t len, uint8_t * p);
 | 
					uint32_t fat32_read_file_random_access(const Fat32_CtrlBlock * ctrl, const Fat32_FileEntry * entry, uint32_t pos, uint32_t len, uint8_t * p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Fat32_FileEntry * fat32_locate_file(const Fat32_CtrlBlock *ctrl, const char *path);
 | 
					const Fat32_FileEntry * fat32_locate_file(const Fat32_CtrlBlock *ctrl, const char *path, uint32_t * file_entry_ba);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int fat32_open_file(const Fat32_CtrlBlock *ctrl, const char *path, Fat32_FileHelper *file_helper);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t fat32_seek_stream(const Fat32_CtrlBlock *ctrl, uint32_t pos, Fat32_FileHelper *file_helper);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t fat32_read_file_stream(const Fat32_CtrlBlock *ctrl, Fat32_FileHelper *file_helper, uint32_t len, uint8_t *p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif //EMBPART_FAT32_H
 | 
					#endif //EMBPART_FAT32_H
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user