|
@@ -32,6 +32,7 @@
|
|
|
#include "FatLibConfig.h"
|
|
|
#include "../common/SysCall.h"
|
|
|
#include "../common/BlockDevice.h"
|
|
|
+#include "../common/FsCache.h"
|
|
|
#include "../common/FsStructs.h"
|
|
|
|
|
|
/** Type for FAT12 partition */
|
|
@@ -43,12 +44,9 @@ const uint8_t FAT_TYPE_FAT16 = 16;
|
|
|
/** Type for FAT12 partition */
|
|
|
const uint8_t FAT_TYPE_FAT32 = 32;
|
|
|
|
|
|
-//------------------------------------------------------------------------------
|
|
|
-// Forward declaration of FatPartition.
|
|
|
-class FatPartition;
|
|
|
//------------------------------------------------------------------------------
|
|
|
/**
|
|
|
- * \brief Cache for an raw data sector.
|
|
|
+ * \brief Cache type for a sector.
|
|
|
*/
|
|
|
union cache_t {
|
|
|
/** Used to access cached file data sectors. */
|
|
@@ -58,74 +56,7 @@ union cache_t {
|
|
|
/** Used to access cached FAT32 entries. */
|
|
|
uint32_t fat32[128];
|
|
|
/** Used to access cached directory entries. */
|
|
|
- DirFat_t dir[16];
|
|
|
-};
|
|
|
-//==============================================================================
|
|
|
-/**
|
|
|
- * \class FatCache
|
|
|
- * \brief Sector cache.
|
|
|
- */
|
|
|
-class FatCache {
|
|
|
- public:
|
|
|
- /** Cached sector is dirty */
|
|
|
- static const uint8_t CACHE_STATUS_DIRTY = 1;
|
|
|
- /** Cashed sector is FAT entry and must be mirrored in second FAT. */
|
|
|
- static const uint8_t CACHE_STATUS_MIRROR_FAT = 2;
|
|
|
- /** Cache sector status bits */
|
|
|
- static const uint8_t CACHE_STATUS_MASK
|
|
|
- = CACHE_STATUS_DIRTY | CACHE_STATUS_MIRROR_FAT;
|
|
|
- /** Sync existing sector but do not read new sector. */
|
|
|
- static const uint8_t CACHE_OPTION_NO_READ = 4;
|
|
|
- /** Cache sector for read. */
|
|
|
- static const uint8_t CACHE_FOR_READ = 0;
|
|
|
- /** Cache sector for write. */
|
|
|
- static const uint8_t CACHE_FOR_WRITE = CACHE_STATUS_DIRTY;
|
|
|
- /** Reserve cache sector for write - do not read from sector device. */
|
|
|
- static const uint8_t CACHE_RESERVE_FOR_WRITE
|
|
|
- = CACHE_STATUS_DIRTY | CACHE_OPTION_NO_READ;
|
|
|
- /** \return Cache sector address. */
|
|
|
- cache_t* buffer() {
|
|
|
- return &m_buffer;
|
|
|
- }
|
|
|
- /** Set current sector dirty. */
|
|
|
- void dirty() {
|
|
|
- m_status |= CACHE_STATUS_DIRTY;
|
|
|
- }
|
|
|
- /** Initialize the cache.
|
|
|
- * \param[in] vol FatPartition that owns this FatCache.
|
|
|
- */
|
|
|
- void init(FatPartition *vol) {
|
|
|
- m_part = vol;
|
|
|
- invalidate();
|
|
|
- }
|
|
|
- /** Invalidate current cache sector. */
|
|
|
- void invalidate() {
|
|
|
- m_status = 0;
|
|
|
- m_lbn = 0XFFFFFFFF;
|
|
|
- }
|
|
|
- /** \return dirty status */
|
|
|
- bool isDirty() {
|
|
|
- return m_status & CACHE_STATUS_DIRTY;
|
|
|
- }
|
|
|
- /** \return Logical sector number for cached sector. */
|
|
|
- uint32_t sector() {
|
|
|
- return m_lbn;
|
|
|
- }
|
|
|
- /** Read a sector into the cache.
|
|
|
- * \param[in] sector Sector to read.
|
|
|
- * \param[in] option mode for cached sector.
|
|
|
- * \return Address of cached sector. */
|
|
|
- cache_t* read(uint32_t sector, uint8_t option);
|
|
|
- /** Write current sector if dirty.
|
|
|
- * \return true for success or false for failure.
|
|
|
- */
|
|
|
- bool sync();
|
|
|
-
|
|
|
- private:
|
|
|
- uint8_t m_status;
|
|
|
- FatPartition* m_part;
|
|
|
- uint32_t m_lbn;
|
|
|
- cache_t m_buffer;
|
|
|
+ DirFat_t dir[16];
|
|
|
};
|
|
|
//==============================================================================
|
|
|
/**
|
|
@@ -173,12 +104,8 @@ class FatPartition {
|
|
|
/** Clear the cache and returns a pointer to the cache. Not for normal apps.
|
|
|
* \return A pointer to the cache buffer or zero if an error occurs.
|
|
|
*/
|
|
|
- cache_t* cacheClear() {
|
|
|
- if (!cacheSync()) {
|
|
|
- return nullptr;
|
|
|
- }
|
|
|
- m_cache.invalidate();
|
|
|
- return m_cache.buffer();
|
|
|
+ uint8_t* cacheClear() {
|
|
|
+ return m_cache.clear();
|
|
|
}
|
|
|
/** \return The total number of clusters in the volume. */
|
|
|
uint32_t clusterCount() const {
|
|
@@ -251,8 +178,6 @@ class FatPartition {
|
|
|
#endif // DOXYGEN_SHOULD_SKIP_THIS
|
|
|
//----------------------------------------------------------------------------
|
|
|
private:
|
|
|
- /** FatCache allowed access to private members. */
|
|
|
- friend class FatCache;
|
|
|
/** FatFile allowed access to private members. */
|
|
|
friend class FatFile;
|
|
|
//----------------------------------------------------------------------------
|
|
@@ -274,6 +199,18 @@ class FatPartition {
|
|
|
uint32_t m_rootDirStart; // Start sector FAT16, cluster FAT32.
|
|
|
//----------------------------------------------------------------------------
|
|
|
// sector I/O functions.
|
|
|
+ bool cacheSafeRead(uint32_t sector, uint8_t* dst) {
|
|
|
+ return m_cache.cacheSafeRead(sector, dst);
|
|
|
+ }
|
|
|
+ bool cacheSafeRead(uint32_t sector, uint8_t* dst, size_t count) {
|
|
|
+ return m_cache.cacheSafeRead(sector, dst, count);
|
|
|
+ }
|
|
|
+ bool cacheSafeWrite(uint32_t sector, const uint8_t* dst) {
|
|
|
+ return m_cache.cacheSafeWrite(sector, dst);
|
|
|
+ }
|
|
|
+ bool cacheSafeWrite(uint32_t sector, const uint8_t* dst, size_t count) {
|
|
|
+ return m_cache.cacheSafeWrite(sector, dst, count);
|
|
|
+ }
|
|
|
bool readSector(uint32_t sector, uint8_t* dst) {
|
|
|
return m_blockDev->readSector(sector, dst);
|
|
|
}
|
|
@@ -283,14 +220,6 @@ class FatPartition {
|
|
|
bool writeSector(uint32_t sector, const uint8_t* src) {
|
|
|
return m_blockDev->writeSector(sector, src);
|
|
|
}
|
|
|
-#if USE_MULTI_SECTOR_IO
|
|
|
- bool readSectors(uint32_t sector, uint8_t* dst, size_t ns) {
|
|
|
- return m_blockDev->readSectors(sector, dst, ns);
|
|
|
- }
|
|
|
- bool writeSectors(uint32_t sector, const uint8_t* src, size_t ns) {
|
|
|
- return m_blockDev->writeSectors(sector, src, ns);
|
|
|
- }
|
|
|
-#endif // USE_MULTI_SECTOR_IO
|
|
|
#if MAINTAIN_FREE_CLUSTER_COUNT
|
|
|
int32_t m_freeClusterCount; // Count of free clusters in volume.
|
|
|
void setFreeClusterCount(int32_t value) {
|
|
@@ -309,29 +238,28 @@ class FatPartition {
|
|
|
(void)change;
|
|
|
}
|
|
|
#endif // MAINTAIN_FREE_CLUSTER_COUNT
|
|
|
-
|
|
|
// sector caches
|
|
|
- FatCache m_cache;
|
|
|
+ FsCache m_cache;
|
|
|
#if USE_SEPARATE_FAT_CACHE
|
|
|
- FatCache m_fatCache;
|
|
|
+ FsCache m_fatCache;
|
|
|
cache_t* cacheFetchFat(uint32_t sector, uint8_t options) {
|
|
|
- return m_fatCache.read(sector,
|
|
|
- options | FatCache::CACHE_STATUS_MIRROR_FAT);
|
|
|
+ options |= FsCache::CACHE_STATUS_MIRROR_FAT;
|
|
|
+ return reinterpret_cast<cache_t*>(m_fatCache.get(sector, options));
|
|
|
}
|
|
|
bool cacheSync() {
|
|
|
return m_cache.sync() && m_fatCache.sync() && syncDevice();
|
|
|
}
|
|
|
#else // USE_SEPARATE_FAT_CACHE
|
|
|
cache_t* cacheFetchFat(uint32_t sector, uint8_t options) {
|
|
|
- return cacheFetchData(sector,
|
|
|
- options | FatCache::CACHE_STATUS_MIRROR_FAT);
|
|
|
+ options |= FsCache::CACHE_STATUS_MIRROR_FAT;
|
|
|
+ return cacheFetchData(sector, options);
|
|
|
}
|
|
|
bool cacheSync() {
|
|
|
return m_cache.sync() && syncDevice();
|
|
|
}
|
|
|
#endif // USE_SEPARATE_FAT_CACHE
|
|
|
cache_t* cacheFetchData(uint32_t sector, uint8_t options) {
|
|
|
- return m_cache.read(sector, options);
|
|
|
+ return reinterpret_cast<cache_t*>(m_cache.get(sector, options));
|
|
|
}
|
|
|
void cacheInvalidate() {
|
|
|
m_cache.invalidate();
|
|
@@ -340,7 +268,7 @@ class FatPartition {
|
|
|
return m_cache.sync();
|
|
|
}
|
|
|
cache_t* cacheAddress() {
|
|
|
- return m_cache.buffer();
|
|
|
+ return reinterpret_cast<cache_t*>(m_cache.cacheBuffer());
|
|
|
}
|
|
|
uint32_t cacheSectorNumber() {
|
|
|
return m_cache.sector();
|
|
@@ -354,7 +282,9 @@ class FatPartition {
|
|
|
uint8_t sectorOfCluster(uint32_t position) const {
|
|
|
return (position >> 9) & m_clusterSectorMask;
|
|
|
}
|
|
|
- uint32_t clusterStartSector(uint32_t cluster) const;
|
|
|
+ uint32_t clusterStartSector(uint32_t cluster) const {
|
|
|
+ return m_dataStartSector + ((cluster - 2) << m_sectorsPerClusterShift);
|
|
|
+ }
|
|
|
int8_t fatGet(uint32_t cluster, uint32_t* value);
|
|
|
bool fatPut(uint32_t cluster, uint32_t value);
|
|
|
bool fatPutEOC(uint32_t cluster) {
|