You are currently viewing the documentation for:
m_fnReadSector
m_fnReadSector reads a single sector from the block device (usually an SD card or flash memory).
ECF_ErrorCode m_fnReadSector(
   struct ECF_BlockDriver *pBlockDriver,
   uint32_t sector,
   uint8_t *pData,
   uint8_t flags
);
Parameters
pBlockDriver
This is a pointer to the struct ECF_BlockDriver that the function is a member of. It can be used by the block driver to access the m_BlockDriverData member or to call the other functions.
sector
This specifies which sector to read.
pData
This points to a uint8_t array that the block driver needs to fill with the read data.
flags
These are flags for the read.
ECF_READSECTOR_512_BYTES_ONLY:
If this flag is set, the block driver only needs to read 512 bytes, regardless of the sector size and the buffer pointed to by pData is only 512 bytes big, regardless of the sector size.
Return value
Return ECFERR_SUCCESS if the read was successful. If the read fails, return one of the EcFAT error codes defined in EcFAT.h. You can also define your own error codes, error no 64 to 127 are reserved for custom block driver errors.
Remarks
EcFAT will call this function when it wants to read a sector from the storage device. The m_fnReadSector function is part of struct ECF_BlockDriver. You need to supply it when writing a block driver. On both single- and multithreaded systems, EcFAT will make certain that it will not call any of the other block driver functions until this call has been completed so you do not need to implement any locking in the block driver unless it is needed for other purposes. Note 1: If you use journaling and/or wear-leveling, you must respect the ECF_READSECTOR_512_BYTES_ONLY flag. If you ignore it and the sector size is larger than 512 bytes, reading an entire sector will write beyond the end of the buffer pointed to by pData and corrupt the system. Note 2: If you support TRIM, m_fnReadSector will almost never be called for a sector that is trimmed. But there are a few rare exceptions so you must return ECFERR_SUCCESS even if you don't have any data to return. Just make sure to memset pData to 0's if that is the case.
Example Code

// Create a global to hold our data. Make it 64 kb
uint8_t ramDriveData[64][1024];

ECF_ErrorCode RAM_GetVolumeInformation(
   struct ECF_BlockDriver *pBlockDriver, 
   uint16_t* pSectorSize, 
   uint32_t* pNumberOfSectors)
{
   *pSectorSize = 1024;
   *pNumberOfSectors = 64;
   
   return ECFERR_SUCCESS;
}

ECF_ErrorCode RAM_ReadSector(struct ECF_BlockDriver *pBlockDriver, uint32_t sector, uint8_t *pData, uint8_t flags)
{
   if(sector >= 64)
      return ECFERR_PARAMETERERROR;
   
   if(flags & ECF_READSECTOR_512_BYTES_ONLY)
      memcpy(pData, ramDriveData[sector], 512);
   else
      memcpy(pData, ramDriveData[sector], 1024);
   
   return ECFERR_SUCCESS;
}

ECF_ErrorCode RAM_WriteSector(struct ECF_BlockDriver *pBlockDriver, uint32_t sector, uint8_t *pData, uint8_t flags)
{
   if(sector >= 64)
      return ECFERR_PARAMETERERROR;
   
   if(flags & ECF_WRITESECTOR_512_BYTES_ONLY)
      memcpy(ramDriveData[sector], pData, 512);
   else
      memcpy(ramDriveData[sector], pData, 1024);
   
   return ECFERR_SUCCESS;
}

int main(void)
{
   ...

   struct ECF_BlockDriver blockDriver;
   
   memset(&blockDriver, 0, sizeof(struct ECF_BlockDriver)); 
   
   blockDriver.m_fnReadSector           = RAM_ReadSector;
   blockDriver.m_fnWriteSector          = RAM_WriteSector;
   blockDriver.m_fnGetVolumeInformation = RAM_GetVolumeInformation;

   // You can now call ECF_Mount() or ECF_Format() with blockDriver
   
   ...
}