forked from mfulz_github/qmk_firmware
		
	Update Mass Storage bootloader for Linux compatibility, and to reduce the compiled bootloader size. Linux appears to replace files with a cluster offset on the disk rather than re-using the same disk clusters (unlike Windows) so the file offset needs to be tracked and compensated for.
This commit is contained in:
		
							parent
							
								
									148b434228
								
							
						
					
					
						commit
						83d5c4729e
					
				| @ -255,10 +255,15 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */ | 	/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */ | ||||||
|  | 	while (TotalBlocks--) | ||||||
|  | 	{ | ||||||
| 		if (IsDataRead == DATA_READ) | 		if (IsDataRead == DATA_READ) | ||||||
| 	  VirtualFAT_ReadBlocks(BlockAddress, TotalBlocks); | 		  VirtualFAT_ReadBlock(BlockAddress); | ||||||
| 		else | 		else | ||||||
| 	  VirtualFAT_WriteBlocks(BlockAddress, TotalBlocks); | 		  VirtualFAT_WriteBlock(BlockAddress); | ||||||
|  | 
 | ||||||
|  | 		BlockAddress++; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Update the bytes transferred counter and succeed the command */ | 	/* Update the bytes transferred counter and succeed the command */ | ||||||
| 	MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * SECTOR_SIZE_BYTES); | 	MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * SECTOR_SIZE_BYTES); | ||||||
|  | |||||||
| @ -72,12 +72,13 @@ static const FATBootBlock_t BootBlock = | |||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| /** FAT 8.3 style directory entry, for the virtual FLASH contents file. */ | /** FAT 8.3 style directory entry, for the virtual FLASH contents file. */ | ||||||
| static FATDirectoryEntry_t FirmwareFileEntries[] = | FATDirectoryEntry_t FirmwareFileEntries[] = | ||||||
| 	{ | 	{ | ||||||
| 		/* Root volume label entry; disk label is contained in the Filename and
 | 		/* Root volume label entry; disk label is contained in the Filename and
 | ||||||
| 		 * Extension fields (concatenated) with a special attribute flag - other | 		 * Extension fields (concatenated) with a special attribute flag - other | ||||||
| 		 * fields are ignored. Should be the same as the label in the boot block. | 		 * fields are ignored. Should be the same as the label in the boot block. | ||||||
| 		 */ | 		 */ | ||||||
|  | 		[DISK_FILE_ENTRY_VolumeID] = | ||||||
| 		{ | 		{ | ||||||
| 			.MSDOS_Directory = | 			.MSDOS_Directory = | ||||||
| 				{ | 				{ | ||||||
| @ -94,6 +95,7 @@ static FATDirectoryEntry_t FirmwareFileEntries[] = | |||||||
| 		/* VFAT Long File Name entry for the virtual firmware file; required to
 | 		/* VFAT Long File Name entry for the virtual firmware file; required to
 | ||||||
| 		 * prevent corruption from systems that are unable to detect the device | 		 * prevent corruption from systems that are unable to detect the device | ||||||
| 		 * as being a legacy MSDOS style FAT12 volume. */ | 		 * as being a legacy MSDOS style FAT12 volume. */ | ||||||
|  | 		[DISK_FILE_ENTRY_FirmwareLFN] = | ||||||
| 		{ | 		{ | ||||||
| 			.VFAT_LongFileName = | 			.VFAT_LongFileName = | ||||||
| 				{ | 				{ | ||||||
| @ -121,6 +123,7 @@ static FATDirectoryEntry_t FirmwareFileEntries[] = | |||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
| 		/* MSDOS file entry for the virtual Firmware image. */ | 		/* MSDOS file entry for the virtual Firmware image. */ | ||||||
|  | 		[DISK_FILE_ENTRY_FirmwareMSDOS] = | ||||||
| 		{ | 		{ | ||||||
| 			.MSDOS_File = | 			.MSDOS_File = | ||||||
| 				{ | 				{ | ||||||
| @ -136,6 +139,12 @@ static FATDirectoryEntry_t FirmwareFileEntries[] = | |||||||
| 		}, | 		}, | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
|  | /** Starting block of the virtual firmware file image on disk. On Windows, files
 | ||||||
|  |  *  are (usually?) replaced using the original file's physical sectors. On Linux | ||||||
|  |  *  file replacements are performed with an offset. | ||||||
|  |  */ | ||||||
|  | uint16_t FileStartBlock = DISK_BLOCK_DataStartBlock; | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /** Updates a FAT12 cluster entry in the FAT file table with the specified next
 | /** Updates a FAT12 cluster entry in the FAT file table with the specified next
 | ||||||
|  *  chain index. If the cluster is the last in the file chain, the magic value |  *  chain index. If the cluster is the last in the file chain, the magic value | ||||||
| @ -170,12 +179,72 @@ static void UpdateFAT12ClusterEntry(uint8_t* const FATTable, | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /** Reads or writes a block of data from/to the physical device FLASH using a
 | ||||||
|  |  *  block buffer stored in RAM, if the requested block is within the virtual | ||||||
|  |  *  firmware file's sector ranges in the emulated FAT file system. | ||||||
|  |  * | ||||||
|  |  *  \param[in]      BlockNumber  Physical disk block to read from | ||||||
|  |  *  \param[in,out]  BlockBuffer  Pointer to the start of the block buffer in RAM | ||||||
|  |  *  \param[in]      Read         If \c true, the requested block is read, if | ||||||
|  |  *                               \c false, the requested block is written | ||||||
|  |  */ | ||||||
|  | static void ReadWriteFirmwareFileBlock(const uint16_t BlockNumber, | ||||||
|  |                                        uint8_t* BlockBuffer, | ||||||
|  |                                        const bool Read) | ||||||
|  | { | ||||||
|  | 	/* Range check the write request - abort if requested block is not within the
 | ||||||
|  | 	 * virtual firmware file sector range */ | ||||||
|  | 	if (!((BlockNumber >= FileStartBlock) && (BlockNumber < (FileStartBlock + FILE_SECTORS(FIRMWARE_FILE_SIZE_BYTES))))) | ||||||
|  | 	  return; | ||||||
|  | 
 | ||||||
|  | 	#if (FLASHEND > 0xFFFF) | ||||||
|  | 	uint32_t FlashAddress = (uint32_t)(BlockNumber - FileStartBlock) * SECTOR_SIZE_BYTES; | ||||||
|  | 	#else | ||||||
|  | 	uint16_t FlashAddress = (uint16_t)(BlockNumber - FileStartBlock) * SECTOR_SIZE_BYTES; | ||||||
|  | 	#endif | ||||||
|  | 
 | ||||||
|  | 	if (Read) | ||||||
|  | 	{ | ||||||
|  | 		/* Read out the mapped block of data from the device's FLASH */ | ||||||
|  | 		for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++) | ||||||
|  | 		{ | ||||||
|  | 			#if (FLASHEND > 0xFFFF) | ||||||
|  | 			  BlockBuffer[i] = pgm_read_byte_far(FlashAddress++); | ||||||
|  | 			#else | ||||||
|  | 			  BlockBuffer[i] = pgm_read_byte(FlashAddress++); | ||||||
|  | 			#endif | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		/* Write out the mapped block of data to the device's FLASH */ | ||||||
|  | 		for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i += 2) | ||||||
|  | 		{ | ||||||
|  | 			if ((FlashAddress % SPM_PAGESIZE) == 0) | ||||||
|  | 			{ | ||||||
|  | 				/* Erase the given FLASH page, ready to be programmed */ | ||||||
|  | 				BootloaderAPI_ErasePage(FlashAddress); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			/* Write the next data word to the FLASH page */ | ||||||
|  | 			BootloaderAPI_FillWord(FlashAddress, (BlockBuffer[i + 1] << 8) | BlockBuffer[i]); | ||||||
|  | 			FlashAddress += 2; | ||||||
|  | 
 | ||||||
|  | 			if ((FlashAddress % SPM_PAGESIZE) == 0) | ||||||
|  | 			{ | ||||||
|  | 				/* Write the filled FLASH page to memory */ | ||||||
|  | 				BootloaderAPI_WritePage(FlashAddress - SPM_PAGESIZE); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /** Writes a block of data to the virtual FAT filesystem, from the USB Mass
 | /** Writes a block of data to the virtual FAT filesystem, from the USB Mass
 | ||||||
|  *  Storage interface. |  *  Storage interface. | ||||||
|  * |  * | ||||||
|  *  \param[in]  BlockNumber  Index of the block to write. |  *  \param[in]  BlockNumber  Index of the block to write. | ||||||
|  */ |  */ | ||||||
| static void WriteVirtualBlock(const uint16_t BlockNumber) | void VirtualFAT_WriteBlock(const uint16_t BlockNumber) | ||||||
| { | { | ||||||
| 	uint8_t BlockBuffer[SECTOR_SIZE_BYTES]; | 	uint8_t BlockBuffer[SECTOR_SIZE_BYTES]; | ||||||
| 
 | 
 | ||||||
| @ -183,32 +252,19 @@ static void WriteVirtualBlock(const uint16_t BlockNumber) | |||||||
| 	Endpoint_Read_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL); | 	Endpoint_Read_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL); | ||||||
| 	Endpoint_ClearOUT(); | 	Endpoint_ClearOUT(); | ||||||
| 
 | 
 | ||||||
| 	if ((BlockNumber >= 4) && (BlockNumber < (4 + FILE_SECTORS(FIRMWARE_FILE_SIZE_BYTES)))) | 	if (BlockNumber == DISK_BLOCK_RootFilesBlock) | ||||||
| 	{ | 	{ | ||||||
| 		#if (FLASHEND > 0xFFFF) | 		/* Copy over the updated directory entries */ | ||||||
| 		uint32_t WriteFlashAddress = (uint32_t)(BlockNumber - 4) * SECTOR_SIZE_BYTES; | 		memcpy(FirmwareFileEntries, BlockBuffer, sizeof(FirmwareFileEntries)); | ||||||
| 		#else |  | ||||||
| 		uint16_t WriteFlashAddress = (uint16_t)(BlockNumber - 4) * SECTOR_SIZE_BYTES; |  | ||||||
| 		#endif |  | ||||||
| 
 | 
 | ||||||
| 		for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i += 2) | 		/* Save the new firmware file block offset so the written and read file
 | ||||||
| 		{ | 		 * contents can be correctly mapped to the device's FLASH pages */ | ||||||
| 			if ((WriteFlashAddress % SPM_PAGESIZE) == 0) | 		FileStartBlock = DISK_BLOCK_DataStartBlock + | ||||||
| 			{ | 		                 (FirmwareFileEntries[DISK_FILE_ENTRY_FirmwareMSDOS].MSDOS_File.StartingCluster - 2) * SECTOR_PER_CLUSTER; | ||||||
| 				/* Erase the given FLASH page, ready to be programmed */ |  | ||||||
| 				BootloaderAPI_ErasePage(WriteFlashAddress); |  | ||||||
| 	} | 	} | ||||||
| 
 | 	else | ||||||
| 			/* Write the next data word to the FLASH page */ |  | ||||||
| 			BootloaderAPI_FillWord(WriteFlashAddress, (BlockBuffer[i + 1] << 8) | BlockBuffer[i]); |  | ||||||
| 			WriteFlashAddress += 2; |  | ||||||
| 
 |  | ||||||
| 			if ((WriteFlashAddress % SPM_PAGESIZE) == 0) |  | ||||||
| 	{ | 	{ | ||||||
| 				/* Write the filled FLASH page to memory */ | 		ReadWriteFirmwareFileBlock(BlockNumber, BlockBuffer, false); | ||||||
| 				BootloaderAPI_WritePage(WriteFlashAddress - SPM_PAGESIZE); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -217,23 +273,24 @@ static void WriteVirtualBlock(const uint16_t BlockNumber) | |||||||
|  * |  * | ||||||
|  *  \param[in]  BlockNumber  Index of the block to read. |  *  \param[in]  BlockNumber  Index of the block to read. | ||||||
|  */ |  */ | ||||||
| static void ReadVirtualBlock(const uint16_t BlockNumber) | void VirtualFAT_ReadBlock(const uint16_t BlockNumber) | ||||||
| { | { | ||||||
| 	uint8_t BlockBuffer[SECTOR_SIZE_BYTES]; | 	uint8_t BlockBuffer[SECTOR_SIZE_BYTES]; | ||||||
| 	memset(BlockBuffer, 0x00, sizeof(BlockBuffer)); | 	memset(BlockBuffer, 0x00, sizeof(BlockBuffer)); | ||||||
| 
 | 
 | ||||||
| 	switch (BlockNumber) | 	switch (BlockNumber) | ||||||
| 	{ | 	{ | ||||||
| 		case 0: /* Block 0: Boot block sector */ | 		case DISK_BLOCK_BootBlock: | ||||||
| 			memcpy(BlockBuffer, &BootBlock, sizeof(FATBootBlock_t)); | 			memcpy(BlockBuffer, &BootBlock, sizeof(FATBootBlock_t)); | ||||||
| 
 | 
 | ||||||
| 			/* Add the magic signature to the end of the block */ | 			/* Add the magic signature to the end of the block */ | ||||||
| 			BlockBuffer[SECTOR_SIZE_BYTES - 2] = 0x55; | 			BlockBuffer[SECTOR_SIZE_BYTES - 2] = 0x55; | ||||||
| 			BlockBuffer[SECTOR_SIZE_BYTES - 1] = 0xAA; | 			BlockBuffer[SECTOR_SIZE_BYTES - 1] = 0xAA; | ||||||
|  | 
 | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| 		case 1: /* Block 1: First FAT12 cluster chain copy */ | 		case DISK_BLOCK_FATBlock1: | ||||||
| 		case 2: /* Block 2: Second FAT12 cluster chain copy */ | 		case DISK_BLOCK_FATBlock2: | ||||||
| 			/* Cluster 0: Media type/Reserved */ | 			/* Cluster 0: Media type/Reserved */ | ||||||
| 			UpdateFAT12ClusterEntry(BlockBuffer, 0, 0xF00 | BootBlock.MediaDescriptor); | 			UpdateFAT12ClusterEntry(BlockBuffer, 0, 0xF00 | BootBlock.MediaDescriptor); | ||||||
| 
 | 
 | ||||||
| @ -241,32 +298,27 @@ static void ReadVirtualBlock(const uint16_t BlockNumber) | |||||||
| 			UpdateFAT12ClusterEntry(BlockBuffer, 1, 0xFFF); | 			UpdateFAT12ClusterEntry(BlockBuffer, 1, 0xFFF); | ||||||
| 
 | 
 | ||||||
| 			/* Cluster 2 onwards: Cluster chain of FIRMWARE.BIN */ | 			/* Cluster 2 onwards: Cluster chain of FIRMWARE.BIN */ | ||||||
| 			for (uint16_t i = 0; i < FILE_CLUSTERS(FIRMWARE_FILE_SIZE_BYTES); i++) | 			for (uint16_t i = 0; i <= FILE_CLUSTERS(FIRMWARE_FILE_SIZE_BYTES); i++) | ||||||
| 			  UpdateFAT12ClusterEntry(BlockBuffer, i+2, i+3); | 			{ | ||||||
|  | 				uint16_t CurrentCluster = FirmwareFileEntries[DISK_FILE_ENTRY_FirmwareMSDOS].MSDOS_File.StartingCluster + i; | ||||||
|  | 				uint16_t NextCluster    = CurrentCluster + 1; | ||||||
| 
 | 
 | ||||||
| 				/* Mark last cluster as end of file */ | 				/* Mark last cluster as end of file */ | ||||||
| 			UpdateFAT12ClusterEntry(BlockBuffer, FILE_CLUSTERS(FIRMWARE_FILE_SIZE_BYTES) + 1, 0xFFF); | 				if (i == FILE_CLUSTERS(FIRMWARE_FILE_SIZE_BYTES)) | ||||||
|  | 				  NextCluster = 0xFFF; | ||||||
|  | 
 | ||||||
|  | 				UpdateFAT12ClusterEntry(BlockBuffer, CurrentCluster, NextCluster); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| 		case 3: /* Block 3: Root file entries */ | 		case DISK_BLOCK_RootFilesBlock: | ||||||
| 			memcpy(BlockBuffer, FirmwareFileEntries, sizeof(FirmwareFileEntries)); | 			memcpy(BlockBuffer, FirmwareFileEntries, sizeof(FirmwareFileEntries)); | ||||||
|  | 
 | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| 		default: /* Blocks 4 onwards: Data allocation section */ | 		default: /* Blocks 4 onwards: Data allocation section */ | ||||||
| 			if ((BlockNumber >= 4) && (BlockNumber < (4 + FILE_SECTORS(FIRMWARE_FILE_SIZE_BYTES)))) | 			ReadWriteFirmwareFileBlock(BlockNumber, BlockBuffer, true); | ||||||
| 			{ |  | ||||||
| 				#if (FLASHEND > 0xFFFF) |  | ||||||
| 				uint32_t ReadFlashAddress = (uint32_t)(BlockNumber - 4) * SECTOR_SIZE_BYTES; |  | ||||||
| 
 |  | ||||||
| 				for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++) |  | ||||||
| 				  BlockBuffer[i] = pgm_read_byte_far(ReadFlashAddress++); |  | ||||||
| 				#else |  | ||||||
| 				uint16_t ReadFlashAddress = (uint16_t)(BlockNumber - 4) * SECTOR_SIZE_BYTES; |  | ||||||
| 
 |  | ||||||
| 				for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++) |  | ||||||
| 				  BlockBuffer[i] = pgm_read_byte(ReadFlashAddress++); |  | ||||||
| 				#endif |  | ||||||
| 			} |  | ||||||
| 
 | 
 | ||||||
| 			break; | 			break; | ||||||
| 	} | 	} | ||||||
| @ -275,38 +327,3 @@ static void ReadVirtualBlock(const uint16_t BlockNumber) | |||||||
| 	Endpoint_Write_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL); | 	Endpoint_Write_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL); | ||||||
| 	Endpoint_ClearIN(); | 	Endpoint_ClearIN(); | ||||||
| } | } | ||||||
| 
 |  | ||||||
| /** Writes a number of blocks to the virtual FAT file system, from the host
 |  | ||||||
|  *  PC via the USB Mass Storage interface. |  | ||||||
|  * |  | ||||||
|  *  \param[in] BlockAddress     Data block starting address for the write sequence |  | ||||||
|  *  \param[in] TotalBlocks      Number of blocks of data to write |  | ||||||
|  */ |  | ||||||
| void VirtualFAT_WriteBlocks(const uint16_t BlockAddress, |  | ||||||
|                             uint16_t TotalBlocks) |  | ||||||
| { |  | ||||||
| 	uint16_t CurrentBlock = (uint16_t)BlockAddress; |  | ||||||
| 
 |  | ||||||
| 	/* Emulated FAT is performed per-block, pass each requested block index
 |  | ||||||
| 	 * to the emulated FAT block write function */ |  | ||||||
| 	while (TotalBlocks--) |  | ||||||
| 	  WriteVirtualBlock(CurrentBlock++); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** Reads a number of blocks from the virtual FAT file system, and sends them
 |  | ||||||
|  *  to the host PC via the USB Mass Storage interface. |  | ||||||
|  * |  | ||||||
|  *  \param[in] BlockAddress     Data block starting address for the read sequence |  | ||||||
|  *  \param[in] TotalBlocks      Number of blocks of data to read |  | ||||||
|  */ |  | ||||||
| void VirtualFAT_ReadBlocks(const uint16_t BlockAddress, |  | ||||||
|                            uint16_t TotalBlocks) |  | ||||||
| { |  | ||||||
| 	uint16_t CurrentBlock = (uint16_t)BlockAddress; |  | ||||||
| 
 |  | ||||||
| 	/* Emulated FAT is performed per-block, pass each requested block index
 |  | ||||||
| 	 * to the emulated FAT block read function */ |  | ||||||
| 	while (TotalBlocks--) |  | ||||||
| 	  ReadVirtualBlock(CurrentBlock++); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
|  | |||||||
| @ -121,6 +121,23 @@ | |||||||
| 		#define FAT_ORDINAL_LAST_ENTRY    (1 << 6) | 		#define FAT_ORDINAL_LAST_ENTRY    (1 << 6) | ||||||
| 		//@}
 | 		//@}
 | ||||||
| 
 | 
 | ||||||
|  | 	/* Enums: */ | ||||||
|  | 		enum | ||||||
|  | 		{ | ||||||
|  | 			DISK_FILE_ENTRY_VolumeID      = 0, | ||||||
|  | 			DISK_FILE_ENTRY_FirmwareLFN   = 1, | ||||||
|  | 			DISK_FILE_ENTRY_FirmwareMSDOS = 2, | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		enum | ||||||
|  | 		{ | ||||||
|  | 			DISK_BLOCK_BootBlock        = 0, | ||||||
|  | 			DISK_BLOCK_FATBlock1        = 1, | ||||||
|  | 			DISK_BLOCK_FATBlock2        = 2, | ||||||
|  | 			DISK_BLOCK_RootFilesBlock   = 3, | ||||||
|  | 			DISK_BLOCK_DataStartBlock   = 4, | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
| 	/* Type Definitions: */ | 	/* Type Definitions: */ | ||||||
| 		/** FAT boot block structure definition, used to identify the core
 | 		/** FAT boot block structure definition, used to identify the core
 | ||||||
| 		 *  parameters of a FAT filesystem stored on a disk. | 		 *  parameters of a FAT filesystem stored on a disk. | ||||||
| @ -213,13 +230,13 @@ | |||||||
| 			static void UpdateFAT12ClusterEntry(uint8_t* const FATTable, | 			static void UpdateFAT12ClusterEntry(uint8_t* const FATTable, | ||||||
| 			                                    const uint16_t Index, | 			                                    const uint16_t Index, | ||||||
| 			                                    const uint16_t ChainEntry) AUX_BOOT_SECTION; | 			                                    const uint16_t ChainEntry) AUX_BOOT_SECTION; | ||||||
| 			static void WriteVirtualBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION; | 
 | ||||||
| 			static void ReadVirtualBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION; | 			static void ReadWriteFirmwareFileBlock(const uint16_t BlockNumber, | ||||||
|  | 			                                       uint8_t* BlockBuffer, | ||||||
|  | 			                                       const bool Read) AUX_BOOT_SECTION; | ||||||
| 		#endif | 		#endif | ||||||
| 
 | 
 | ||||||
| 		void VirtualFAT_WriteBlocks(const uint16_t BlockAddress, | 		void VirtualFAT_WriteBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION; | ||||||
| 		                            uint16_t TotalBlocks) AUX_BOOT_SECTION; | 		void VirtualFAT_ReadBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION; | ||||||
| 
 | 
 | ||||||
| 		void VirtualFAT_ReadBlocks(const uint16_t BlockAddress, |  | ||||||
| 		                           uint16_t TotalBlocks) AUX_BOOT_SECTION; |  | ||||||
| #endif | #endif | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dean Camera
						Dean Camera