Skip to content

Commit bbc2d42

Browse files
committed
Bangle.js2_iflash: If we can't write a JS file to internal flash, attempt to write to external instead
+ Bangle.js2_iflash: require("Storage").getStats() now sums both Storage pools by default
1 parent 7fbc3ec commit bbc2d42

File tree

4 files changed

+55
-14
lines changed

4 files changed

+55
-14
lines changed

ChangeLog

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
nRF52: Ensure that if enabled the HID service gets added to the main advertising packet (#2631)
5050
nRF52: Fix unreliable internal flash writes when writing >2k (big issue for compaction) (fix #2509)
5151
nRF52: Don't break out of flash erase/writes if interrupted (Ctrl-C) - these shouldn't take too long and can corrupt data if interruptable
52+
Bangle.js2_iflash: If we can't write a JS file to internal flash, attempt to write to external instead
53+
Bangle.js2_iflash: require("Storage").getStats() now sums both Storage pools by default
5254

5355
2v25 : ESP32C3: Get analogRead working correctly
5456
Graphics: Adjust image alignment when rotating images to avoid cropping (fix #2535)

src/jsflash.c

+32-7
Original file line numberDiff line numberDiff line change
@@ -647,14 +647,26 @@ bool jsfCompact(bool showMessage) {
647647
return compacted;
648648
}
649649

650+
static bool jsvIsDriveNameExplicit(JsfFileName *name) {
651+
return name->c[1]==':';
652+
}
653+
654+
static bool jsvIsDriveC(char drive) {
655+
#ifdef JSF_BANK2_START_ADDRESS
656+
return (drive&(~0x20)) == 'C'; // make drive case insensitive
657+
#else
658+
return false;
659+
#endif
660+
}
661+
650662
/* If we have a filename like "C:foo", take the 'C:' bit
651663
* off it and return the drive. If explicitOnly==false,
652664
* we also return the drive name if we think a file should
653665
* go somewhere (eg it's *.js or .boot0 it should go in internal flash)
654666
*/
655-
char jsfStripDriveFromName(JsfFileName *name, bool explicitOnly){
667+
static char jsfStripDriveFromName(JsfFileName *name, bool explicitOnly){
656668
#ifndef SAVE_ON_FLASH
657-
if (name->c[1]==':') { // if a 'drive' is specified like "C:foobar.js"
669+
if (jsvIsDriveNameExplicit(name)) { // if a 'drive' is specified like "C:foobar.js"
658670
char drive = name->c[0];
659671
memmove(name->c, name->c+2, sizeof(JsfFileName)-2); // shift back and clear the rest
660672
name->c[sizeof(JsfFileName)-2]=0;name->c[sizeof(JsfFileName)-1]=0;
@@ -675,7 +687,7 @@ char jsfStripDriveFromName(JsfFileName *name, bool explicitOnly){
675687
void jsfGetDriveBankAddress(char drive, uint32_t *bankStartAddr, uint32_t *bankEndAddr){
676688
#ifdef JSF_BANK2_START_ADDRESS
677689
if (drive){
678-
if ((drive&(~0x20)) == 'C'){ // make drive case insensitive
690+
if (jsvIsDriveC(drive)){
679691
*bankStartAddr=JSF_START_ADDRESS;
680692
*bankEndAddr=JSF_END_ADDRESS;
681693
} else {
@@ -688,10 +700,11 @@ void jsfGetDriveBankAddress(char drive, uint32_t *bankStartAddr, uint32_t *bankE
688700
*bankStartAddr=JSF_DEFAULT_START_ADDRESS;
689701
*bankEndAddr=JSF_DEFAULT_END_ADDRESS;
690702
}
691-
/// Create a new 'file' in the memory store - DOES NOT remove existing files with same name. Return the address of data start, or 0 on error
692-
static uint32_t jsfCreateFile(JsfFileName name, uint32_t size, JsfFileFlags flags, JsfFileHeader *returnedHeader) {
703+
static uint32_t _jsfCreateFile(JsfFileName name, uint32_t size, JsfFileFlags flags, JsfFileHeader *returnedHeader, bool explicitOnly) {
704+
// explicitOnly -> only put in the non-default storage while filename explicitly starts with 'C:' (default=false)
693705
jsDebug(DBG_INFO,"CreateFile (%d bytes)\n", size);
694-
char drive = jsfStripDriveFromName(&name, false/* ensure .js/etc go in C */);
706+
bool explicitDriveName = jsvIsDriveNameExplicit(&name);
707+
char drive = jsfStripDriveFromName(&name, explicitOnly/* ensure .js/etc go in C */);
695708
jsfCacheClearFile(name);
696709
uint32_t bankStartAddress,bankEndAddress;
697710
jsfGetDriveBankAddress(drive,&bankStartAddress,&bankEndAddress);
@@ -724,6 +737,14 @@ static uint32_t jsfCreateFile(JsfFileName name, uint32_t size, JsfFileFlags flag
724737
} while (addr && !freeAddr);
725738
// If we don't have space, compact
726739
if (!freeAddr) {
740+
#ifdef JSF_BANK2_START_ADDRESS
741+
if (!explicitOnly && !explicitDriveName && bankStartAddress!=JSF_DEFAULT_START_ADDRESS) {
742+
/* Drive name wasn't explicit but we're not in the default area (eg maybe file ends in .js)
743+
so let's try again with explicitOnly=true to force file into the default area where maybe
744+
there's space */
745+
return _jsfCreateFile(name, size, flags, returnedHeader, true);
746+
}
747+
#endif
727748
//jsiConsolePrintf("%d Free, %d Trash -> need %d\n", freeSpace, trashSpace, requiredSize);
728749
if (!compacted && (requiredSize < (freeSpace+trashSpace))) {
729750
// only try and compact if we're sure there would be enough space - it's better to fail fast!
@@ -756,6 +777,10 @@ static uint32_t jsfCreateFile(JsfFileName name, uint32_t size, JsfFileFlags flag
756777
jsfCachePut(&header, addr);
757778
return addr;
758779
}
780+
/** Create a new 'file' in the memory store - DOES NOT remove existing files with same name. Return the address of data start, or 0 on error */
781+
static uint32_t jsfCreateFile(JsfFileName name, uint32_t size, JsfFileFlags flags, JsfFileHeader *returnedHeader) {
782+
return _jsfCreateFile(name, size, flags, returnedHeader, false);
783+
}
759784

760785
static uint32_t jsfBankFindFile(uint32_t bankAddress, uint32_t bankEndAddress, JsfFileName name, JsfFileHeader *returnedHeader) {
761786
uint32_t addr = bankAddress;
@@ -1066,7 +1091,7 @@ bool jsfWriteFile(JsfFileName name, JsVar *data, JsfFileFlags flags, JsVarInt of
10661091
JsfFileHeader header;
10671092
uint32_t addr = jsfFindFile(name, &header);
10681093
#ifdef JSF_BANK2_START_ADDRESS
1069-
if (!addr && name.c[1]==':'){
1094+
if (!addr && jsvIsDriveNameExplicit(&name)){
10701095
// if not found where it should be, try another bank to not end with two files
10711096
JsfFileName shortname = name;
10721097
jsfStripDriveFromName(&shortname, true/* we're not using the return value - we just want the ':' bit stripped off */);

src/jswrap_storage.c

+20-6
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ int jswrap_storage_getFree(bool checkInternalFlash) {
461461
"class" : "Storage",
462462
"name" : "getStats",
463463
"params" : [
464-
["checkInternalFlash","bool","Check the internal flash (rather than external SPI flash). Default false, so will check external storage"]
464+
["checkInternalFlash","JsVar","`true` = Check internal flash, `false` = external SPI flash. Default `undefined`, so will check both"]
465465
],
466466
"generate" : "jswrap_storage_getStats",
467467
"return" : ["JsVar","An object containing info about the current Storage system"]
@@ -479,17 +479,31 @@ int jswrap_storage_getFree(bool checkInternalFlash) {
479479
}
480480
```
481481
482-
**NOTE:** `checkInternalFlash` is only useful on DICKENS devices - other devices don't use two different flash banks
482+
**NOTE:** `checkInternalFlash` is only useful on DICKENS/BANGLEJS2_IFLASH devices - other devices don't use two different flash banks
483483
*/
484-
JsVar *jswrap_storage_getStats(bool checkInternalFlash) {
484+
JsVar *jswrap_storage_getStats(JsVar *checkInternalFlash) {
485485
JsVar *o = jsvNewObject();
486486
if (!o) return NULL;
487-
uint32_t addr = 0;
488-
#ifdef FLASH_SAVED_CODE2_START
489-
addr = checkInternalFlash ? FLASH_SAVED_CODE_START : FLASH_SAVED_CODE2_START;
490487

488+
#ifdef FLASH_SAVED_CODE2_START
489+
uint32_t addr = FLASH_SAVED_CODE2_START;
490+
if (checkInternalFlash && jsvGetBool(checkInternalFlash))
491+
addr = FLASH_SAVED_CODE_START;
492+
#else
493+
uint32_t addr = FLASH_SAVED_CODE_START;
491494
#endif
492495
JsfStorageStats stats = jsfGetStorageStats(addr, true);
496+
#ifdef FLASH_SAVED_CODE2_START
497+
if (!checkInternalFlash) { // the default - scan both and sum
498+
JsfStorageStats stats2 = jsfGetStorageStats(FLASH_SAVED_CODE_START, true);
499+
stats.total += stats2.total;
500+
stats.free += stats2.free;
501+
stats.fileBytes += stats2.fileBytes;
502+
stats.fileCount += stats2.fileCount;
503+
stats.trashBytes += stats2.trashBytes;
504+
stats.trashCount += stats2.trashCount;
505+
}
506+
#endif
493507
jsvObjectSetChildAndUnLock(o, "totalBytes", jsvNewFromInteger((JsVarInt)stats.total));
494508
jsvObjectSetChildAndUnLock(o, "freeBytes", jsvNewFromInteger((JsVarInt)stats.free));
495509
jsvObjectSetChildAndUnLock(o, "fileBytes", jsvNewFromInteger((JsVarInt)stats.fileBytes));

src/jswrap_storage.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ JsVar *jswrap_storage_list(JsVar *regex, JsVar *filter);
3030
JsVarInt jswrap_storage_hash(JsVar *regex);
3131
void jswrap_storage_debug();
3232
int jswrap_storage_getFree(bool checkInternalFlash);
33-
JsVar *jswrap_storage_getStats(bool checkInternalFlash);
33+
JsVar *jswrap_storage_getStats(JsVar *checkInternalFlash);
3434
void jswrap_storage_optimise();
3535

3636
JsVar *jswrap_storage_open(JsVar *name, JsVar *mode);

0 commit comments

Comments
 (0)