Skip to content

Commit b0ef35d

Browse files
committed
update storage extension implementation
1 parent 2618e11 commit b0ef35d

File tree

3 files changed

+99
-50
lines changed

3 files changed

+99
-50
lines changed

ports/espressif/supervisor/internal_flash.c

Lines changed: 89 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2525
* THE SOFTWARE.
2626
*/
27+
2728
#include "supervisor/internal_flash.h"
2829

2930
#include <stdint.h>
@@ -32,31 +33,46 @@
3233

3334
#include "extmod/vfs.h"
3435
#include "extmod/vfs_fat.h"
36+
3537
#include "py/mphal.h"
3638
#include "py/obj.h"
3739
#include "py/runtime.h"
38-
#include "lib/oofatfs/ff.h"
3940

4041
#include "esp_ota_ops.h"
4142
#include "esp_partition.h"
4243

44+
#include "supervisor/filesystem.h"
4345
#include "supervisor/flash.h"
4446
#include "supervisor/usb.h"
4547

46-
#if CIRCUITPY_STORAGE_EXTEND
47-
#define PARTITION_NUM (2)
48-
#else
49-
#define PARTITION_NUM (1)
50-
#endif
51-
52-
STATIC const esp_partition_t *_partition[PARTITION_NUM];
48+
#define OP_READ 0
49+
#define OP_WRITE 1
5350

5451
// TODO: Split the caching out of supervisor/shared/external_flash so we can use it.
5552
#define SECTOR_SIZE 4096
5653
STATIC uint8_t _cache[SECTOR_SIZE];
5754
STATIC uint32_t _cache_lba = 0xffffffff;
5855

56+
#if CIRCUITPY_STORAGE_EXTEND
57+
#if FF_MAX_SS == FF_MIN_SS
58+
#define SECSIZE(fs) (FF_MIN_SS)
59+
#else
60+
#define SECSIZE(fs) ((fs)->ssize)
61+
#endif // FF_MAX_SS == FF_MIN_SS
62+
STATIC DWORD fatfs_bytes(void) {
63+
FATFS *fatfs = filesystem_circuitpy();
64+
return (fatfs->csize * SECSIZE(fatfs)) * (fatfs->n_fatent - 2);
65+
}
66+
STATIC bool storage_extended = true;
67+
STATIC const esp_partition_t *_partition[2];
68+
#else
69+
STATIC const esp_partition_t *_partition[1];
70+
#endif // CIRCUITPY_STORAGE_EXTEND
71+
5972
void supervisor_flash_init(void) {
73+
if (_partition[0] != NULL) {
74+
return;
75+
}
6076
_partition[0] = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
6177
ESP_PARTITION_SUBTYPE_DATA_FAT,
6278
NULL);
@@ -71,38 +87,60 @@ uint32_t supervisor_flash_get_block_size(void) {
7187

7288
uint32_t supervisor_flash_get_block_count(void) {
7389
#if CIRCUITPY_STORAGE_EXTEND
74-
return (_partition[0]->size + _partition[1]->size) / FILESYSTEM_BLOCK_SIZE;
90+
return ((storage_extended) ? (_partition[0]->size + _partition[1]->size) : _partition[0]->size) / FILESYSTEM_BLOCK_SIZE;
7591
#else
7692
return _partition[0]->size / FILESYSTEM_BLOCK_SIZE;
7793
#endif
7894
}
7995

8096
void port_internal_flash_flush(void) {
81-
8297
}
8398

84-
mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
85-
uint32_t offset = block * FILESYSTEM_BLOCK_SIZE;
86-
uint32_t read_total = num_blocks * FILESYSTEM_BLOCK_SIZE;
99+
STATIC void single_partition_rw(const esp_partition_t *partition, uint8_t *data,
100+
const uint32_t offset, const uint32_t size_total, const bool op) {
101+
if (op == OP_READ) {
102+
esp_partition_read(partition, offset, data, size_total);
103+
} else {
104+
esp_partition_erase_range(partition, offset, size_total);
105+
esp_partition_write(partition, offset, _cache, size_total);
106+
}
107+
}
87108

88-
#if CIRCUITPY_STORAGE_EXTEND
109+
#if CIRCUITPY_STORAGE_EXTEND
110+
STATIC void multi_partition_rw(uint8_t *data,
111+
const uint32_t offset, const uint32_t size_total, const bool op) {
89112
if (offset > _partition[0]->size) {
90-
// only read from partition 1
91-
esp_partition_read(_partition[1], (offset - _partition[0]->size), dest, read_total);
92-
} else if ((offset + read_total) > _partition[0]->size) {
93-
// first read from partition 0, then partition 1
94-
uint32_t read_0 = _partition[0]->size - offset;
95-
uint32_t read_1 = read_total - read_0;
96-
esp_partition_read(_partition[0], offset, dest, read_0);
97-
esp_partition_read(_partition[1], 0, (dest + read_0), read_1);
98-
} else
99-
#endif
100-
{
101-
// only read from partition 0
102-
esp_partition_read(_partition[0], offset, dest, read_total);
113+
// only r/w partition 1
114+
single_partition_rw(_partition[1], data, (offset - _partition[0]->size), size_total, op);
115+
} else if ((offset + size_total) > _partition[0]->size) {
116+
// first r/w partition 0, then partition 1
117+
uint32_t size_0 = _partition[0]->size - offset;
118+
uint32_t size_1 = size_total - size_0;
119+
if (op == OP_READ) {
120+
esp_partition_read(_partition[0], offset, data, size_0);
121+
esp_partition_read(_partition[1], 0, (data + size_0), size_1);
122+
} else {
123+
esp_partition_erase_range(_partition[0], offset, size_0);
124+
esp_partition_write(_partition[0], offset, _cache, size_0);
125+
esp_partition_erase_range(_partition[1], 0, size_1);
126+
esp_partition_write(_partition[1], 0, (_cache + size_0), size_1);
127+
}
128+
} else {
129+
// only r/w partition 0
130+
single_partition_rw(_partition[0], data, offset, size_total, op);
103131
}
132+
}
133+
#endif
104134

105-
return 0;
135+
mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
136+
const uint32_t offset = block * FILESYSTEM_BLOCK_SIZE;
137+
const uint32_t read_total = num_blocks * FILESYSTEM_BLOCK_SIZE;
138+
#if CIRCUITPY_STORAGE_EXTEND
139+
multi_partition_rw(dest, offset, read_total, OP_READ);
140+
#else
141+
single_partition_rw(_partition[0], dest, offset, read_total, OP_READ);
142+
#endif
143+
return 0; // success
106144
}
107145

108146
mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) {
@@ -112,12 +150,10 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32
112150
uint32_t block_address = lba + block;
113151
uint32_t sector_offset = block_address / blocks_per_sector * SECTOR_SIZE;
114152
uint8_t block_offset = block_address % blocks_per_sector;
115-
116153
if (_cache_lba != block_address) {
117154
supervisor_flash_read_blocks(_cache, sector_offset / FILESYSTEM_BLOCK_SIZE, blocks_per_sector);
118155
_cache_lba = sector_offset;
119156
}
120-
121157
for (uint8_t b = block_offset; b < blocks_per_sector; b++) {
122158
// Stop copying after the last block.
123159
if (block >= num_blocks) {
@@ -128,31 +164,34 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32
128164
FILESYSTEM_BLOCK_SIZE);
129165
block++;
130166
}
131-
132167
#if CIRCUITPY_STORAGE_EXTEND
133-
if (sector_offset > _partition[0]->size) {
134-
// only write to partition 1
135-
esp_partition_erase_range(_partition[1], sector_offset - _partition[0]->size, SECTOR_SIZE);
136-
esp_partition_write(_partition[1], sector_offset - _partition[0]->size, _cache, SECTOR_SIZE);
137-
} else if ((sector_offset + SECTOR_SIZE) > _partition[0]->size) {
138-
// first write to partition 0, then partition 1
139-
uint32_t write_0 = _partition[0]->size - sector_offset;
140-
uint32_t write_1 = SECTOR_SIZE - write_0;
141-
esp_partition_erase_range(_partition[0], sector_offset, write_0);
142-
esp_partition_write(_partition[0], sector_offset, _cache, write_0);
143-
esp_partition_erase_range(_partition[1], 0, write_1);
144-
esp_partition_write(_partition[1], 0, _cache + write_0, write_1);
145-
} else
168+
multi_partition_rw(_cache, sector_offset, SECTOR_SIZE, OP_WRITE);
169+
#else
170+
single_partition_rw(_partition[0], _cache, sector_offset, SECTOR_SIZE, OP_READ);
146171
#endif
147-
{
148-
// only write to partition 0
149-
esp_partition_erase_range(_partition[0], sector_offset, SECTOR_SIZE);
150-
esp_partition_write(_partition[0], sector_offset, _cache, SECTOR_SIZE);
151-
}
152172
}
153-
154173
return 0; // success
155174
}
156175

157176
void supervisor_flash_release_cache(void) {
158177
}
178+
179+
void supervisor_flash_set_extended(bool extended) {
180+
#if CIRCUITPY_STORAGE_EXTEND
181+
storage_extended = extended;
182+
#endif
183+
}
184+
185+
bool supervisor_flash_get_extended(void) {
186+
#if CIRCUITPY_STORAGE_EXTEND
187+
return storage_extended;
188+
#else
189+
return false;
190+
#endif
191+
}
192+
193+
void supervisor_flash_update_extended(void) {
194+
#if CIRCUITPY_STORAGE_EXTEND
195+
storage_extended = (_partition[0]->size < fatfs_bytes());
196+
#endif
197+
}

supervisor/flash.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,8 @@ void supervisor_flash_init_vfs(struct _fs_user_mount_t *vfs);
5050
void supervisor_flash_flush(void);
5151
void supervisor_flash_release_cache(void);
5252

53+
void supervisor_flash_set_extended(bool extended);
54+
bool supervisor_flash_get_extended(void);
55+
void supervisor_flash_update_extended(void);
56+
5357
#endif // MICROPY_INCLUDED_SUPERVISOR_FLASH_H

supervisor/shared/filesystem.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,22 @@ bool filesystem_init(bool create_allowed, bool force_create) {
143143
} else if (res != FR_OK) {
144144
return false;
145145
}
146+
146147
vfs->str = "/";
147148
vfs->len = 1;
148149
vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
149150
vfs->next = NULL;
151+
150152
MP_STATE_VM(vfs_mount_table) = vfs;
151153

152154
// The current directory is used as the boot up directory.
153155
// It is set to the internal flash filesystem by default.
154156
MP_STATE_PORT(vfs_cur) = vfs;
155157

158+
#if CIRCUITPY_STORAGE_EXTEND
159+
supervisor_flash_update_extended();
160+
#endif
161+
156162
return true;
157163
}
158164

0 commit comments

Comments
 (0)