Raises file limit from 14 to 62 files.

Enable all four sectors of root directory to contain files.
This commit is contained in:
Henry Gabryjelski 2019-03-13 18:45:44 -07:00
parent 8def8aee53
commit 53a99195bf
2 changed files with 115 additions and 15 deletions

View File

@ -9,6 +9,8 @@
#include "bootloader_settings.h" #include "bootloader_settings.h"
#include "bootloader.h" #include "bootloader.h"
// #define CREATE_MANY_FILES
typedef struct { typedef struct {
uint8_t JumpInstruction[3]; uint8_t JumpInstruction[3];
@ -48,7 +50,6 @@ typedef struct {
uint16_t startCluster; uint16_t startCluster;
uint32_t size; uint32_t size;
} __attribute__((packed)) DirEntry; } __attribute__((packed)) DirEntry;
STATIC_ASSERT(sizeof(DirEntry) == 32); STATIC_ASSERT(sizeof(DirEntry) == 32);
struct TextFile { struct TextFile {
@ -78,9 +79,56 @@ const char indexFile[] = //
"</body>" "</body>"
"</html>\n"; "</html>\n";
#ifdef CREATE_MANY_FILES
const char dataFile00[] = "This is the data for File 00\r\n";
const char dataFile01[] = "This is the data for File 01\r\n";
const char dataFile02[] = "This is the data for File 02\r\n";
const char dataFile03[] = "This is the data for File 03\r\n";
const char dataFile04[] = "This is the data for File 04\r\n";
const char dataFile05[] = "This is the data for File 05\r\n";
const char dataFile06[] = "This is the data for File 06\r\n";
const char dataFile07[] = "This is the data for File 07\r\n";
const char dataFile08[] = "This is the data for File 08\r\n";
const char dataFile09[] = "This is the data for File 09\r\n";
const char dataFile10[] = "This is the data for File 10\r\n";
const char dataFile11[] = "This is the data for File 11\r\n";
const char dataFile12[] = "This is the data for File 12\r\n";
const char dataFile13[] = "This is the data for File 13\r\n";
const char dataFile14[] = "This is the data for File 14\r\n";
const char dataFile15[] = "This is the data for File 15\r\n";
const char dataFile16[] = "This is the data for File 16\r\n";
const char dataFile17[] = "This is the data for File 17\r\n";
const char dataFile18[] = "This is the data for File 18\r\n";
const char dataFile19[] = "This is the data for File 19\r\n";
#endif // CREATE_MANY_FILES
// WARNING -- code presumes only one NULL .content for .UF2 file
// and requires it be the last element of the array
static struct TextFile const info[] = { static struct TextFile const info[] = {
{.name = "INFO_UF2TXT", .content = infoUf2File}, {.name = "INFO_UF2TXT", .content = infoUf2File},
{.name = "INDEX HTM", .content = indexFile}, {.name = "INDEX HTM", .content = indexFile},
#ifdef CREATE_MANY_FILES
{.name = "FILE00 TXT", .content = dataFile00},
{.name = "FILE01 TXT", .content = dataFile01},
{.name = "FILE02 TXT", .content = dataFile02},
{.name = "FILE03 TXT", .content = dataFile03},
{.name = "FILE04 TXT", .content = dataFile04},
{.name = "FILE05 TXT", .content = dataFile05},
{.name = "FILE06 TXT", .content = dataFile06},
{.name = "FILE07 TXT", .content = dataFile07},
{.name = "FILE08 TXT", .content = dataFile08},
{.name = "FILE09 TXT", .content = dataFile09},
{.name = "FILE10 TXT", .content = dataFile10},
{.name = "FILE11 TXT", .content = dataFile11},
{.name = "FILE12 TXT", .content = dataFile12},
{.name = "FILE13 TXT", .content = dataFile13},
{.name = "FILE14 TXT", .content = dataFile14},
{.name = "FILE15 TXT", .content = dataFile15},
{.name = "FILE16 TXT", .content = dataFile16},
{.name = "FILE17 TXT", .content = dataFile17},
{.name = "FILE18 TXT", .content = dataFile18},
{.name = "FILE19 TXT", .content = dataFile19},
#endif
{.name = "CURRENT UF2"}, {.name = "CURRENT UF2"},
}; };
@ -110,8 +158,9 @@ STATIC_ASSERT(ARRAY_SIZE2(indexFile) < 512);
// all directory entries must fit in a single sector // all directory entries must fit in a single sector
// because otherwise current code overflows buffer // because otherwise current code overflows buffer
STATIC_ASSERT(NUM_DIRENTRIES < (512 / sizeof(DirEntry))); #define DIRENTRIES_PER_SECTOR (512/sizeof(DirEntry))
// STATIC_ASSERT(NUM_DIRENTRIES < (512 / sizeof(DirEntry)) * ROOT_DIR_SECTORS);
STATIC_ASSERT(NUM_DIRENTRIES < DIRENTRIES_PER_SECTOR * ROOT_DIR_SECTORS);
static FAT_BootBlock const BootBlock = { static FAT_BootBlock const BootBlock = {
@ -121,7 +170,7 @@ static FAT_BootBlock const BootBlock = {
.SectorsPerCluster = 1, .SectorsPerCluster = 1,
.ReservedSectors = RESERVED_SECTORS, .ReservedSectors = RESERVED_SECTORS,
.FATCopies = 2, .FATCopies = 2,
.RootDirectoryEntries = (ROOT_DIR_SECTORS * 512 / 32), .RootDirectoryEntries = (ROOT_DIR_SECTORS * DIRENTRIES_PER_SECTOR),
.TotalSectors16 = NUM_FAT_BLOCKS - 2, .TotalSectors16 = NUM_FAT_BLOCKS - 2,
.MediaDescriptor = 0xF8, .MediaDescriptor = 0xF8,
.SectorsPerFAT = SECTORS_PER_FAT, .SectorsPerFAT = SECTORS_PER_FAT,
@ -205,8 +254,11 @@ void read_block(uint32_t block_no, uint8_t *data) {
sectionIdx -= SECTORS_PER_FAT; sectionIdx -= SECTORS_PER_FAT;
if (sectionIdx == 0) { if (sectionIdx == 0) {
data[0] = 0xf0; data[0] = 0xf0;
// WARNING -- code presumes only one NULL .content for .UF2 file
// and all non-NULL .content fit in one sector
// and requires it be the last element of the array
for (int i = 1; i < NUM_FILES * 2 + 4; ++i) { for (int i = 1; i < NUM_FILES * 2 + 4; ++i) {
data[i] = 0xff; // WARNING -- code presumes each non-UF2 file content fits in single sector data[i] = 0xff;
} }
} }
for (int i = 0; i < 256; ++i) { for (int i = 0; i < 256; ++i) {
@ -215,20 +267,33 @@ void read_block(uint32_t block_no, uint8_t *data) {
((uint16_t *)(void *)data)[i] = v == UF2_LAST_SECTOR ? 0xffff : v + 1; ((uint16_t *)(void *)data)[i] = v == UF2_LAST_SECTOR ? 0xffff : v + 1;
} }
} else if (block_no < START_CLUSTERS) { } else if (block_no < START_CLUSTERS) {
// Use STATIC_ASSERT() above to ensure only first sector has entries
sectionIdx -= START_ROOTDIR; sectionIdx -= START_ROOTDIR;
if (sectionIdx == 0) {
DirEntry *d = (void *)data; DirEntry *d = (void *)data;
int remainingEntries = DIRENTRIES_PER_SECTOR;
if (sectionIdx == 0) { // volume label first
// volume label is first directory entry
padded_memcpy(d->name, (char const *) BootBlock.VolumeLabel, 11); padded_memcpy(d->name, (char const *) BootBlock.VolumeLabel, 11);
d->attrs = 0x28; d->attrs = 0x28;
for (int i = 0; i < NUM_FILES; ++i) { remainingEntries--;
d++; }
for (int i = DIRENTRIES_PER_SECTOR * sectionIdx;
remainingEntries > 0 && i < NUM_FILES;
i++, d++) {
struct TextFile const * inf = &info[i]; struct TextFile const * inf = &info[i];
// WARNING -- code presumes only one NULL .content for .UF2 file
// and requires it be the last element of the array
d->size = inf->content ? strlen(inf->content) : UF2_SIZE; d->size = inf->content ? strlen(inf->content) : UF2_SIZE;
d->startCluster = i + 2; d->startCluster = i + 2;
padded_memcpy(d->name, inf->name, 11); padded_memcpy(d->name, inf->name, 11);
// DIR_WrtTime and DIR_WrtDate must be supported
d->updateDate = __DOSDATE__;
d->lastAccessDate = __DOSDATE__;
d->createDate = __DOSDATE__;
} }
}
} else { } else {
sectionIdx -= START_CLUSTERS; sectionIdx -= START_CLUSTERS;
if (sectionIdx < NUM_FILES - 1) { if (sectionIdx < NUM_FILES - 1) {

View File

@ -296,3 +296,38 @@ static inline void check_uf2_handover(uint8_t *buffer, uint32_t blocks_remaining
#endif // ARRAYSIZE2_H #endif // ARRAYSIZE2_H
#ifndef COMPILE_DATE_H
#define COMPILE_DATE_H
#define __YEAR_INT__ ((( \
(__DATE__ [ 7u] - '0') * 10u + \
(__DATE__ [ 8u] - '0')) * 10u + \
(__DATE__ [ 9u] - '0')) * 10u + \
(__DATE__ [10u] - '0'))
#define __MONTH_INT__ ( \
(__DATE__ [2u] == 'n' && __DATE__ [1u] == 'a') ? 1u /*Jan*/ \
: (__DATE__ [2u] == 'b' ) ? 2u /*Feb*/ \
: (__DATE__ [2u] == 'r' && __DATE__ [1u] == 'a') ? 3u /*Mar*/ \
: (__DATE__ [2u] == 'r' ) ? 4u /*Apr*/ \
: (__DATE__ [2u] == 'y' ) ? 5u /*May*/ \
: (__DATE__ [2u] == 'n' ) ? 6u /*Jun*/ \
: (__DATE__ [2u] == 'l' ) ? 7u /*Jul*/ \
: (__DATE__ [2u] == 'g' ) ? 8u /*Jul*/ \
: (__DATE__ [2u] == 'p' ) ? 9u /*Jul*/ \
: (__DATE__ [2u] == 't' ) ? 10u /*Jul*/ \
: (__DATE__ [2u] == 'v' ) ? 11u /*Jul*/ \
: 12u /*Dec*/ )
#define __DAY_INT__ ( \
(__DATE__ [4u] == ' ' ? 0u : __DATE__ [4u] - '0') * 10u \
+ (__DATE__ [5u] - '0') )
#define __DOSDATE__ ( \
((__YEAR_INT__ - 1980u) << 9u) | \
( __MONTH_INT__ << 5u) | \
( __DAY_INT__ << 0u) )
#endif // COMPILE_DATE_H