Arduino FatFS
RamIO.h
1 #pragma once
2 
3 #include <stdlib.h>
4 #include <cstring>
5 #include <vector>
6 #include "IO.h"
7 
8 namespace fatfs {
9 
15 class RamIO : public IO {
16  public:
17  // valid sector sizes are 512, 1024, 2048 and 4096
18  RamIO(int sectorCount, int sectorSize = FF_MAX_SS) {
19  sector_size = sectorSize;
20  sector_count = sectorCount;
21  }
22 
23  ~RamIO() {
24  for (int j = 0; j <= sector_count; j++) {
25  free(sectors[j]);
26  }
27  delete[]work_buffer;
28  }
29 
30  // custom logic on mount: we need to format the drive
31  FRESULT mount(FatFs& fs) override;
32 
33  DSTATUS disk_initialize(BYTE pdrv) override {
34  if (pdrv != 0) return STA_NODISK;
35  // allocate sectors
36  if (sectors.size() == 0) {
37  for (int j = 0; j <= sector_count; j++) {
38  uint8_t* ptr = nullptr;
39 #ifdef ESP32
40  ptr = (uint8_t*)ps_malloc(sector_count * sector_size);
41 #endif
42  if (ptr == nullptr) ptr = (uint8_t*)malloc(sector_size);
43  memset(ptr, 0, sector_size);
44  sectors.push_back(ptr);
45  }
46  }
47  status = STA_CLEAR;
48  return status;
49  }
50 
51  DSTATUS disk_status(BYTE pdrv) override {
52  if (pdrv != 0) return STA_NODISK;
53  return status;
54  }
55 
56  DRESULT disk_read(BYTE pdrv, BYTE* buffer, LBA_t sectorNo, UINT sectorCount) override {
57  if (pdrv != 0) return RES_NOTRDY;
58  if (status == STA_NOINIT) return RES_NOTRDY;
59  if (sectors.size() == 0 || sectorNo + sectorCount > sector_count) RES_ERROR;
60  for (int j = sectorNo; j < sectorNo + sectorCount; j++) {
61  int idx = j - sectorNo;
62  uint8_t* source = sectors[j];
63  memcpy(buffer + (idx * sector_size), source , sector_size);
64  }
65  return RES_OK;
66  }
67 
68  DRESULT disk_write(BYTE pdrv, const BYTE* buffer, LBA_t sectorNo,
69  UINT sectorCount) override {
70  if (pdrv != 0) return RES_NOTRDY;
71  if (status == STA_NOINIT) return RES_NOTRDY;
72  if (sectors.size() == 0 || sectorNo + sectorCount > sector_count) RES_ERROR;
73  for (int j = sectorNo; j < sectorNo + sectorCount; j++) {
74  int idx = j - sectorNo;
75  uint8_t* target = sectors[j];
76  memcpy(target, buffer + (idx * sector_size), sector_size);
77  }
78  return RES_OK;
79  }
80 
81  DRESULT disk_ioctl(BYTE pdrv, ioctl_cmd_t cmd, void* buffer) override {
82  DRESULT res;
83  if (pdrv) return RES_PARERR; /* Check parameter */
84  switch (cmd) {
85  case CTRL_SYNC: /* Wait for end of internal write process of the drive */
86  res = RES_OK;
87  break;
88 
89  case GET_SECTOR_COUNT: { /* Get drive capacity in unit of sector (DWORD)
90  */
91  DWORD result = sector_count;
92  memcpy(buffer, &result, (sizeof(result)));
93  res = RES_OK;
94  } break;
95 
96  case GET_BLOCK_SIZE: { /* Get erase block size in unit of sector (DWORD)
97  */
98  DWORD result = 1;
99  memcpy(buffer, &result, (sizeof(result)));
100  res = RES_OK;
101  } break;
102 
103  case CTRL_TRIM: { /* Erase a block of sectors (used when _USE_ERASE == 1)
104  */
105  DWORD range[2];
106  // determine range
107  memcpy(&range, buffer, sizeof(range));
108  // clear memory
109  for (int j = range[0]; j <= range[1]; j++) {
110  memset(sectors[j], 0, sector_size);
111  }
112  res = RES_OK; /* FatFs does not check result of this command */
113  } break;
114 
115  default:
116  res = RES_PARERR;
117  break;
118  }
119  return res;
120  }
121 
122  protected:
123  std::vector<uint8_t*> sectors;
124  DSTATUS status = STA_NOINIT;
125  int sector_size = 512;
126  size_t sector_count = 0;
127  uint8_t *work_buffer = nullptr;
128 };
129 
130 } // namespace fatfs
API for FatFS See http://elm-chan.org/fsw/ff/00index_e.html.
Definition: ff.h:34
FatFS interface definition.
Definition: IO.h:74
The data is stored in RAM. In a ESP32 when PSRAM has been activated we store it is PSRAM.
Definition: RamIO.h:15
FRESULT mount(FatFs &fs) override
mount the file system
Definition: RamIO.cpp:7