Another PSRAM option - Lyontek LY68L6400S

Status
Not open for further replies.

KenHahn

Well-known member
I have seen the LY68L6400S mentioned before, but found no confirmation if they were in fact a valid alternate so I brought some in to test since chip shortages are going to be around for awhile.

These appear to be the exact same as the ESP PSRAM64H and have the same chip ID.

You do want the 'S' version for the SOIC. The 'B' version is the WSON package. Here is the Datasheet

Tested 5 chips on 5 Teensy 4.1 using the standard PJRC teensy41_psram_memtest and they work fine.

Available from LCSC, Aliexpress and ProtoSupplies.com will be adding them to our mix of products as well.

Lyontek Ly68L6400S Test on Teensy 4.1.jpg

--- Ken
 
I'd be happy to send some to Paul if he would like to test them himself and add them to his approved alternate list. Not sure if there is a more strenuous test than the standard memtest that can be run to better test performance boundaries.

Regarding chip shortages, my wife is an executive with a fairly large EMS that that specializes in aerospace, medical and military type applications. Chip shortages are causing havoc across the board and prices are going up. I have even seen some crazy price increases lately on some of the standard stuff coming out of China that you wouldn't think would be affected much.
 
Hi Ken - Had to look up 'Electronic Manufacturing Services for Defense & Military' ... Ambulances and Firetrucks for E.M.S. didn't match with Space and Military :)

This chip drought is really widespread - like lots of other markets demand/supply imbalance - only different reasons and challenges to just make more.

If you wanted to test PSRAM on your end and have installed TD 1.54 Beta 9 - running {arduino_install}\hardware\teensy\avr\libraries\LittleFS\examples\LFSintegrity\LFSintegrity.ino

Here is a T_4.1 with twin 8MB 'IPUS' PSRAMS giving these results. Running this will repeatedly cycle across all of the PSRAM address space with writes and reads and some degree of verification that would be caught as FS failing to track files or file content, and below some idea of the expected throughput rates Read and Write.

Testing with 1 chip installed would be:
Code:
//#include <LittleFS.h>
#include <LittleFS_NAND.h>

#define HALFCUT  // HALFCUT defined to fill half the disk
//#define ROOTONLY // NORMAL is NOT DEFINED!
#define NUMDIRS 32  // When not ROOTONLY must be 1 or more
[B]#define MYPSRAM 8	// compile time PSRAM size
[/B]#define MYBLKSIZE 2048 // 2048
//#define SHOW_YIELD_CNT  1 // uncommented shows calls to Yield per second

[B]#define TEST_RAM
[/B]//#define TEST_SPI
//#define TEST_QSPI
//#define TEST_SPI_NAND
//#define TEST_QSPI_NAND
//#define TEST_PROG
//#define TEST_MRAM
...
> 8MB will run out of room and halt with out of space
Change : #define MAXNUM 26 // ALPHA A-Z is 26, less for fewer files
to perhaps : #define MAXNUM 18 // ALPHA A-Z is 26, less for fewer files


or with two soldered:
Code:
//#include <LittleFS.h>
#include <LittleFS_NAND.h>

#define HALFCUT  // HALFCUT defined to fill half the disk
//#define ROOTONLY // NORMAL is NOT DEFINED!
#define NUMDIRS 32  // When not ROOTONLY must be 1 or more
[B]#define MYPSRAM 16	// compile time PSRAM size
[/B]#define MYBLKSIZE 2048 // 2048
//#define SHOW_YIELD_CNT  1 // uncommented shows calls to Yield per second

[B]#define TEST_RAM
[/B]//#define TEST_SPI
//#define TEST_QSPI
//#define TEST_SPI_NAND
//#define TEST_QSPI_NAND
//#define TEST_PROG
//#define TEST_MRAM
...

When it starts in SerMon hit Enter to create folders and start.
'k' : run 1,000 loop iterations of file create, extend, delete
'0' : Zero the loops to run and stop ongoing iterations
'd' : dir of image
'B' : one or more times to fill half of remaining disk space
Big write /0_bigfile.txt took 0.97 Sec for 4169728 Bytes : file3.size()=4169728
Big write KBytes per second 4289.39

Bytes Used: 4190208, Bytes Total:8388608
'b' : Remove those 'B'ig files
Delete with read verify all #bigfile's
Verify /0_bigfile.txt bytes 4169728 : .................................................. GOOD! >> bytes 4169728
Big read&compare KBytes per second 2317.94
'S' : one or more times to alloc 2MB files
's' : Remove any 'S' files
'g' : run speedBench() - output on chips here:
RAM_DISK Benchmark:
FILE_SIZE = 16384
BUF_SIZE = 2048 bytes
Starting write test, please wait.

write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
4096.00,553,477,488
4096.00,553,437,473
4096.00,522,440,459
5461.33,541,446,470
4096.00,545,460,484

Starting sequential read test, please wait.

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
83167.52,65,6,24
178086.95,30,5,11
260063.48,16,5,7
315076.94,13,5,6
334367.34,10,5,6
 
the one difference I see in the from looking at the datasheets is the max clock speed. It looks like for the Lyontek LY68L6400S the clock is maxed at 100Mhz while for the ESP its at 133 Mhz. This shouldn't be a problem as the default clock is set at 88Mhz. We have tested the ESP chips up to pretty close to the max and it worked. Only warning would be not to exceed 100Mhz in your apps.
 
I'd be happy to send some to Paul if he would like to test them himself and add them to his approved alternate list.

Sure. Send me just 2 chips. I'll solder one to a Teensy 4.1 and run the memory test. Assuming it passes, I'll use the other for a photo to add to the PSRAM page. The 3 photos on the page today are the 3 chips I have personally tested. PJRC is currently shipping the Espressif chip, but we've purchased Ap Memory parts and will switch to those when the Espressif parts run out.

I'm pretty sure all of these various 8 MB QSPI PSRAM chips are really the same chip made by Ap Memory and then printed with different part numbers for different buyers.
 
mjs513, the datasheet I linked to from LCSC site is Rev 0.7 and shows 144MHz max data rate. There is an older datasheet I have come across that showed 100MHz, so I think they updated it at some point. The actual Lyontek website doesn't currently show a datasheet I could find and they list the part as sampling, though they are clearly shipping.

Paul, chips are in the mail. Should have them tomorrow.
 
@mjs513 - running test noted p#4 - when a 'R'estart the myfs fails to survive?

Across a warm restart the EXTMEM/PSRAM image will be present ...

It seems - IIRC - SPIFFS on PSRAM would survive warm restart.

Making these changes allows PSRAM Warm Restart to survive data.

This will never happen on RAM1 - though it would also work on RAM2 with DMAMEM as 'static' on Warm Restart.

If a USER Sketch does not want this behavior - then setup() could add ::
Code:
	if (!myfs.begin(buf, sizeof(buf))) {
	  ...
	}
	[B]myfs.quickFormat();[/B]

T:\arduino-1.8.15\hardware\teensy\avr\libraries\LittleFS\src\LittleFS.h
Code:
class LittleFS_RAM : public LittleFS
{
public:
	LittleFS_RAM() { }
	bool begin(uint32_t size) {
#if defined(__IMXRT1062__)
		return begin(extmem_malloc(size), size);
#else
		return begin(malloc(size), size);
#endif
	}
	bool begin(void *ptr, uint32_t size) {
		//Serial.println("configure "); delay(5);
		configured = false;
		if (!ptr) return false;
[B]//		memset(ptr, 0xFF, size); // always start with blank slate[/B]
		size = size & 0xFFFFFF00;
		memset(&lfs, 0, sizeof(lfs));
		memset(&config, 0, sizeof(config));
		config.context = ptr;
		config.read = &static_read;
		config.prog = &static_prog;
		config.erase = &static_erase;
		config.sync = &static_sync;
		if ( size > 1024 * 1024 ) {
			config.read_size = 256; // Must set cache_size. If read_buffer or prog_buffer are provided manually, these must be cache_size.
			config.prog_size = 256;
			config.block_size = 2048;
			config.block_count = size / config.block_size;
			config.block_cycles = 900;
			config.cache_size = 256;
			config.lookahead_size = 512; // (config.block_count / 8 + 7) & 0xFFFFFFF8;
		}
		else {
			config.read_size = 64;
			config.prog_size = 64;
			config.block_size = 256;
			config.block_count = size / 256;
			config.block_cycles = 50;
			config.cache_size = 64;
			config.lookahead_size = 64;
		}
		config.name_max = LFS_NAME_MAX;
		config.file_max = 0;
		config.attr_max = 0;
		configured = true;
[B]		if (lfs_mount(&lfs, &config) < 0) {
			memset(ptr, 0xFF, size); // always start with blank slate
[/B]			if (lfs_format(&lfs, &config) < 0) return false;
		[B]}[/B]
		//Serial.println("formatted");
		if (lfs_mount(&lfs, &config) < 0) return false;
		//Serial.println("mounted atfer format");
		mounted = true;
		return true;
	}
...
 
@mjs513 - I see above code does duplicate Mount as written ... but it works ... and gives the Idea
Code:
		if (lfs_mount(&lfs, &config) < 0) {
			memset(ptr, 0xFF, size); // always start with blank slate
			if (lfs_format(&lfs, &config) < 0) return false;
			[B]if (lfs_mount(&lfs, &config) < 0) return false;[/B]
		}

Does this seem like a good change to make? Seems to me it could add value to a running system that might encounter an intermittent error or Warm Restart and not present total data loss.

Repeating the test in p#4 it 'generally' works after "R"estart Teensy. But there is something in the LittleFS not surviving?
Code:
printDirectory RAM_DISK
--------------
[B][COLOR="#FF0000"]FILE	0_2MBfile.txt		2048000[/COLOR][/B]
FILE	0_bigfile.txt		4169728

 0 dirs with 2 files of Size 6217728 Bytes
 Total 2 files of Size 6217728 Bytes
Bytes Used: 6246400, Bytes Total:8388608


	 Loop Count: 7 (#fileCycle=0), Bytes read 1763328, written 0, #Files=2
	dirV...113_us	[  1.21 M](0.00024 M elap) Awaiting input 0123456789RdwcghkFqvplmusSBbyYxfan+-? loops left 0 >

[B][  1.21 M](0.00024 M elap) Awaiting input 0123456789RdwcghkFqvplmusSBbyYxfan+-? loops left 0 > RESTART Teensy ...[/B]
T:\arduino-1.8.15\hardware\teensy\avr\libraries\LittleFS\examples\LFSintegrity\LFSintegrity.ino Jun 17 2021 11:34:43
LittleFS Test : File Integrity
printDirectory RAM_DISK
--------------
[B][COLOR="#FF0000"]FILE	0_2MBfile.txt		0[/COLOR][/B]
FILE	0_bigfile.txt		4169728

Maybe there is LittleFS data in the Cache not yet pushed to the PSRAM?

YES :: Putting this in "R" for software Restart fixes the issue :: arm_dcache_flush_delete(buf, MYPSRAM * 1024 * 1024 );

.flush() is a LittleFS virtual function.
The User Sketch would need to call this to allow TyComm/Reset or other WarmRestart to assure data integrity

@mjs513 - can you see how to add that .flush() function to class LittleFS_RAM : public LittleFS, where it adds the arm_dcache_flush_delete()?
 
Last edited:
@defragster
Will take a look at that. Didn’t do much with the psram. That chuck was Paul. Can’t remember about spiffs … was way too long ago now.
 
mjs513, the datasheet I linked to from LCSC site is Rev 0.7 and shows 144MHz max data rate. There is an older datasheet I have come across that showed 100MHz, so I think they updated it at some point. The actual Lyontek website doesn't currently show a datasheet I could find and they list the part as sampling, though they are clearly shipping.

Paul, chips are in the mail. Should have them tomorrow.

Thanks for the clarification will have pick up a few :)
 
Oh yeah - That was Paul on Release Day ...

Yes, SPIFFS is a forgotten memory ... but I do recall ... IIRC ... it survived warm restarts as written.

@Paul this could improve the usability or debugability when a user uses RAM2 or PSRAM for fast 'temp' storage. Is it worth working through this?

@mjs513 - this seems to be working:
Code:
class LittleFS_RAM : public LittleFS
{
public:
	LittleFS_RAM() { }
	bool begin(uint32_t size) {
#if defined(__IMXRT1062__)
		return begin(extmem_malloc(size), size);
#else
		return begin(malloc(size), size);
#endif
	}
...	FLASHMEM
	uint32_t formatUnused(uint32_t blockCnt, uint32_t blockStart) {
		return 0;
	}
[B]	void flush() {
		Serial.printf("    arm_dcache_flush_delete: ptr=0x%x, size=%d\n", config.context, config.block_count * config.block_size);
		arm_dcache_flush_delete(config.context, config.block_count * config.block_size );
	}
[/B]

But this "FILE" got lost as I did it moving from the virtual function:
Code:
class LittleFSFile : public File
...
	virtual void flush() {
		[B]if (file) lfs_file_sync(lfs, file);[/B]
	}

LFSIntegrity was HANDY to find the Error - it was showing '0xFF' found for file data not expected - which showed the formatted block not written because the data cache was not Flushed.

This data cache flush - when called - would prevent that to allow warm restart to survive with FS intact.
 
@Paul this could improve the usability or debugability when a user uses RAM2 or PSRAM for fast 'temp' storage. Is it worth working through this?

Flushing the CPU cache does make sense for the ramdisk. But it should be done from the static_sync() function, not with an API addition at the filesystem level.

Code:
        static int static_sync(const struct lfs_config *c) {
                // flush cache here
                return 0;
        }
 
Reopening this thread. Not sure why it got closed. Maybe a mistake?

Thanks, Might have been browser spasm here - was typing a reply and 'focus' was not in the post area ... may have tabbed back and had focus on that check box ... opps.


Tested against RAM2 :: DMAMEM char buf[490000];

Again generally works - except without 'file *' flush the lfs core hasn't updated the DIR entry it seems and file size on 'B'igfile write is not correct and LFSIntegrity catches an error.

LFSIntegrity was not doing ANY FLUSH( file ) - perhaps it should have been - though it is clear when data is not flushed errors are detected.

Using the obvious seeming FLUSH() was a fail ...


>> FIXED ?????
Making a change like this seems to be working with no added code on user part as this is called by the lfs core code as needed, even across a 'Hardware' driven reset with TyComm/Reset:
Code:
class LittleFS_RAM : public LittleFS
{
...
private:
...
	static int static_sync(const struct lfs_config *c) {
		Serial.printf("    arm_dcache_flush_delete: ptr=0x%x, size=%d\n", c->context, c->block_count * c->block_size);
		arm_dcache_flush_delete(c->context, c->block_count * c->block_size );
		return 0;
	}

Here is above code showing the PRINT on creating a BigFile - tested an DMAMEM and here on PSRAM:
Code:
 RAM_DISK +++ Add [sz 0 add 5120] @KB/sec 800.38 {524.81}  ++ I   Verify /I_file.txt 5120B  @KB/sec 2348.62 
:: /J_file.txt     arm_dcache_flush_delete: ptr=0x70000000, size=8388608
    [B]arm_dcache_flush_delete: ptr=0x70000000, size=8388608[/B]
 RAM_DISK +++ Add [sz 0 add 5632] @KB/sec 920.86 {595.41}  ++ J   Verify /J_file.txt 5632B  @KB/sec 2321.52 
:: /A_file.txt     arm_dcache_flush_delete: ptr=0x70000000, size=8388608
    [B]arm_dcache_flush_delete: ptr=0x70000000, size=8388608[/B]
 RAM_DISK +++ Add [sz 0 add 6144] @KB/sec 954.48 {624.77}  ++ A   Verify /A_file.txt 6144B  @KB/sec 2308.04 
[  0.10 M](0.01127 M elap) Awaiting input 0123456789RdwcghkFqvplmusSBbyYxfan+-? loops left 0 >
Start Big write of 4147200 Bytes    arm_dcache_flush_delete: ptr=0x70000000, size=8388608
..................................................    [B]arm_dcache_flush_delete: ptr=0x70000000, size=8388608[/B]

Big write /0_bigfile.txt took  0.97 Sec for 4145152 Bytes : file3.size()=4145152
	Big write KBytes per second 4267.55 

Bytes Used: 4214784, Bytes Total:8388608
 
Below should be the extent of the changes for 'static' RAM ( PSRAM and DMAMEM/RAM2 ) LittleFS to survive device Warm Restart/Reset

I can make a PULL REQUEST : Here is the edited file :: View attachment LittleFS.h

Only edits to LFSIntegrity are to make the FS use PSRAM/EXTMEM or RAM2/DMAMEM > start of file replacement below.

Code:
@@ -298,7 +298,7 @@ public:
		//Serial.println("configure "); delay(5);
		configured = false;
		if (!ptr) return false;
[B]		[COLOR="#FF0000"]memset(ptr, 0xFF, size); // always start with blank slate[/COLOR]
		// memset(ptr, 0xFF, size); // always start with blank slate
[/B]		size = size & 0xFFFFFF00;
		memset(&lfs, 0, sizeof(lfs));
		memset(&config, 0, sizeof(config));
@ -329,9 +329,12 @@ public:
		config.file_max = 0;
		config.attr_max = 0;
		configured = true;
[COLOR="#FF0000"]		if (lfs_format(&lfs, &config) < 0) return false;
		//Serial.println("formatted");
		if (lfs_mount(&lfs, &config) < 0) return false;[/COLOR]
[B]		if (lfs_mount(&lfs, &config) < 0) {
			memset(ptr, 0xFF, size); // always start with blank slate
			if (lfs_format(&lfs, &config) < 0) return false;
			//Serial.println("formatted");
			if (lfs_mount(&lfs, &config) < 0) return false;
		}[/B]
		//Serial.println("mounted atfer format");
		mounted = true;
		return true;
@ -361,6 +364,8 @@ private:
		return 0;
	}
	static int static_sync(const struct lfs_config *c) {
[B]		// Serial.printf("    arm_dcache_flush_delete: ptr=0x%x, size=%d\n", c->context, c->block_count * c->block_size);
		arm_dcache_flush_delete(c->context, c->block_count * c->block_size );
[/B]		return 0;
	}
};
@ @@

Code:
//#include <LittleFS.h>
#include <LittleFS_NAND.h>

#define HALFCUT  // HALFCUT defined to fill half the disk
#define ROOTONLY // NORMAL is NOT DEFINED!
#define NUMDIRS 32  // When not ROOTONLY must be 1 or more
[B]#define MYPSRAM 8	// compile time PSRAM size[/B]
#define MYBLKSIZE 2048 // 2048
//#define SHOW_YIELD_CNT  1 // uncommented shows calls to Yield per second

#define TEST_RAM
//#define TEST_SPI
//#define TEST_QSPI
//#define TEST_SPI_NAND
//#define TEST_QSPI_NAND
//#define TEST_PROG
//#define TEST_MRAM

IntervalTimer clocked10ms;
uint32_t yCalls = 0;
uint32_t yCallsMax = 0;
uint32_t yCallsLast = 0;
uint32_t yCallsIdx = 0;
uint32_t yCallsSum = 0;
#ifdef SHOW_YIELD_CNT
void yield() {
	yCalls++;
}
#endif
void clock_isr() {
	yCallsIdx++;
	if ( yCallsIdx >= 100 ) {
		if (yCallsSum > 0 )
			Serial.printf( "\n yps=%lu [mx=%lu]\t", yCallsSum, yCallsMax * 100);
		yCallsIdx = 0;
		yCallsSum = 0;
		yCallsMax = 0;
	}
	yCallsSum += yCalls - yCallsLast;
	if ( yCalls - yCallsLast > yCallsMax ) yCallsMax = yCalls - yCallsLast;
	yCallsLast = yCalls;
}

// Set for SPI usage
//const int FlashChipSelect = 10; // AUDIO BOARD
const int FlashChipSelect = 4; // PJRC Mem board 64MB on #5, #6 : NAND 1Gb on #3, 2GB on #4
//const int FlashChipSelect = 5; // PJRC Mem board 64MB on #5, #6 : NAND 1Gb on #3, 2GB on #4
//const int FlashChipSelect = 6; // digital pin for flash chip CS pin


#ifdef TEST_RAM
LittleFS_RAM myfs;
// RUNTIME :: extern "C" uint8_t external_psram_size;
[B]EXTMEM char buf[MYPSRAM * 1024 * 1024];	// USE DMAMEM for more memory than ITCM allows - or remove
//DMAMEM char buf[490000];	// USE DMAMEM for more memory than ITCM allows - or remove
[/B]char szDiskMem[] = "RAM_DISK";
#elif defined(TEST_SPI)
//const int FlashChipSelect = 10; // Arduino 101 built-in SPI Flash
#define FORMATSPI
//#define FORMATSPI2
LittleFS_SPIFlash myfs;
char szDiskMem[] = "SPI_DISK";
#elif defined(TEST_MRAM)
//const int FlashChipSelect = 10; // Arduino 101 built-in SPI Flash
LittleFS_SPIFram myfs;
char szDiskMem[] = "FRAM_DISK";
#elif defined(TEST_PROG)
LittleFS_Program myfs;
char szDiskMem[] = "PRO_DISK";
#elif defined(TEST_QSPI_NAND)
char szDiskMem[] = "QSPI_NAND";
LittleFS_QPINAND myfs;
#elif defined(TEST_SPI_NAND)
char szDiskMem[] = "SPI_NAND";
LittleFS_SPINAND myfs;
#else // TEST_QSPI
LittleFS_QSPIFlash myfs;
char szDiskMem[] = "QSPI_DISK";

#endif

File file3;

uint32_t DELSTART = 3; // originally was 3 + higher bias more to writes and larger files - lower odd
#define SUBADD 512	// bytes added each pass (*times file number)
#define BIGADD 1024	// bytes added each pass - bigger will quickly consume more space
[B]#define MAXNUM 10	// ALPHA A-Z is 26, less for fewer files[/B]
#define MAXFILL 2048 // 66000	// ZERO to disable :: Prevent iterations from over filling - require this much free
#define DELDELAY 0 	// delay before DEL files : delayMicroseconds
#define ADDDELAY 0 	// delay on ADD FILE : delayMicroseconds
...
 
@mjs513 - if you are bored and want to have some fun - let me know if you can give this a try.

With p#16 code the drive FS appears to survive to LFSIntegrity standards where lfs core code does all the work as it had the static sync() callback for a reason.
> survival tested with:
-> 'R' command in LFSIntegrity
-> TyCommander issues Host side Teensy 'Reset'
-> TeensyLoader Reprogram
-> Teensy Button press and Reset

opps ... in typing that I wonder what happens when the arm_dcache_flush_delete() is done with a RAM1 address ???
>> Maybe it need to verify the Memory area of "c->context" is not an address in RAM1 ???
-> make the _flush_ conditional on address >= :: ptr=0x20200000
Code:
// EXTMEM char buf[MYPSRAM * 1024 * 1024];
arm_dcache_flush_delete: ptr=0x70000000, size=8388608

Code:
// DMAMEM char buf[490000];
 arm_dcache_flush_delete: ptr=0x20200000, size=489984

Code:
// char buf[400000]; // RAM1
[B][COLOR="#FF0000"]arm_dcache_flush_delete: ptr=0x200023c8, size=399872[/COLOR][/B]

Edited code:
Code:
	static int static_sync(const struct lfs_config *c) {
[B]		if ( c->context >= (void *)0x20200000 ) {[/B]
			Serial.printf("    arm_dcache_flush_delete: ptr=0x%x, size=%d\n", c->context, c->block_count * c->block_size);
			arm_dcache_flush_delete(c->context, c->block_count * c->block_size );
		}
		return 0;

That stops _dcache_flush_ on RAM1 - though it didn't seem to have any trouble.
 
@KenHahn - sorry for polluting your thread ... Though it does IMHO greatly increase the value/utility of popping PSRAM chips onto T_4.1's knowing that when possible data is preserved.

Paul - Mike ... Kurt/Frank :: if seen as WORTHY and Working I'll move this to LittleFS thread ...
 
Flushing the CPU cache does make sense for the ramdisk. But it should be done from the static_sync() function, not with an API addition at the filesystem level.

Code:
        static int static_sync(const struct lfs_config *c) {
                // flush cache here
                return 0;
        }

Thanks Paul - You are correct!

... an hour later I just now see your post and see I went the right direction ... and have it working.

The other half of the change is to not assume the RAM disk always needs to be started with a fresh format. In the case of RAM1 that still happens as Zeroed Ram1 will never mount. But for RAM2 and PSRAM they have some static properties across reset, restart and reprogram when those areas stay powered.
 
defragster said:
@mjs513 - if you are bored and want to have some fun - let me know if you can give this a try.
Usually not bored, only sometimes.

Definitely think its worth trying and adding if it works. I will download and give the new LittleFS.h a try that you posted in #16
 
Usually not bored, only sometimes.

Definitely think its worth trying and adding if it works. I will download and give the new LittleFS.h a try that you posted in #16

bored ... i KNEW that wasn't the case :)

Code:
I see it as viewed now but here is the current version with the no flush on RAM1 : [ATTACH]25062._xfImport[/ATTACH]

Tested here with LFSIntegrity.ino - not sure if there were any other real world like examples to play with?

But as noted that sketch did good telling me when I had issues and allows for lots of File I/O in some fashion : # loop iterations and the B and S file creation.

BTW - tried the B on the RAM1 drive and that was a FAIL because of the small 256 Byte alloc units at 390KB of RAM1. I see it does use 2048 over 1MB in use.

Of course my github is a mess ... not sure if we had any other pending changes ....
 
@defragster.

First your modified LittleFS.h is throwing errors on lowlevelFormat. So I used codecompare and updated the one the is bundled with Teensyduino1.54b9. See attached.

I took a slightly different approach than you did. Instead of using LFSIntegrity I used a modifed LittleFS_teensy_test1a sketch see attached zip.

On first pass it will print the directory on start and then add files or append if they already exist. So pass 1:
Code:
LittleFS Test
TotalSize (Bytes): 8388608
started
printDirectory
--------------

 0 dirs with 0 files of Size 0 Bytes

MAKE files
printDirectory
--------------
DIR	structureData1 / 

 0 dirs with 0 files of Size 0 Bytes

 1 dirs with 0 files of Size 0 Bytes

--------------
printDirectory
--------------
DIR	structureData1 / 
	FILE	temp_test.txt		19

 0 dirs with 1 files of Size 19 Bytes
FILE	temp_test1.txt		19
FILE	temp_test2.txt		19
FILE	temp_test3.txt		1024

 1 dirs with 3 files of Size 1062 Bytes

Disk Usuage:
Bytes Used: 10240, Bytes Total:8388608
Test for SOME DATA TO TEST
Note No files on start. Doing a Restart with the 'R' command that I added to the original sketch. The first pass shows that it retained the files and appended new data:
Code:
LittleFS Test
TotalSize (Bytes): 8388608
started
printDirectory
--------------
FILE	bigfile.txt  		616448
DIR	structureData1 / 
	FILE	temp_test.txt		19

 0 dirs with 1 files of Size 19 Bytes
FILE	temp_test1.txt		19
FILE	temp_test2.txt		19
FILE	temp_test3.txt		1024

 1 dirs with 4 files of Size 617510 Bytes

MAKE files
printDirectory
--------------
FILE	bigfile.txt  		616448
DIR	structureData1 / 
	FILE	temp_test.txt		19

 0 dirs with 1 files of Size 19 Bytes
FILE	temp_test1.txt		19
FILE	temp_test2.txt		19
FILE	temp_test3.txt		1024

 1 dirs with 4 files of Size 617510 Bytes

--------------
printDirectory
--------------
FILE	bigfile.txt  		616448
DIR	structureData1 / 
	FILE	temp_test.txt		38

 0 dirs with 1 files of Size 38 Bytes
FILE	temp_test1.txt		38
FILE	temp_test2.txt		38
FILE	temp_test3.txt		2048

 1 dirs with 4 files of Size 618572 Bytes

Disk Usuage:
Bytes Used: 630784, Bytes Total:8388608
Test for SOME DATA TO TEST
So I would say it looks like its working if you do a warm restart.
 

Attachments

  • littlefs_teensy_test1a.ino
    9.1 KB · Views: 57
  • LittleFS.h
    15.9 KB · Views: 90
@defragster.

First your modified LittleFS.h is throwing errors on lowlevelFormat. So I used codecompare and updated the one the is bundled with Teensyduino1.54b9. See attached.

I took a slightly different approach than you did. Instead of using LFSIntegrity I used a modifed LittleFS_teensy_test1a sketch see attached zip.

On first pass it will print the directory on start and then add files or append if they already exist. So pass 1:
...


Just noted my github is a mess ... I seem to have some included KurtE change to pass in *Serial? for output redirect?

That had nothing to do with the change at hand though ... going to look at your code now ???
 
Just noted my github is a mess ... I seem to have some included KurtE change to pass in *Serial? for output redirect?

That had nothing to do with the change at hand though ... going to look at your code now ???

Well, looks like the option to pass in *Serial has been incorporated:
Code:
bool lowLevelFormat(char progressChar=0, Print* pr=&Serial);
This is what is up at: https://github.com/PaulStoffregen/LittleFS/blob/main/src/LittleFS.h. Think you may need a refresh :) Me too most of the time. I forgot to remove @KurtE's date modifications from my local directory first pass through :)

I saw what you did when I updated using CodeCompare.
 
Well, looks like the option to pass in *Serial has been incorporated:
Code:
bool lowLevelFormat(char progressChar=0, Print* pr=&Serial);
This is what is up at: https://github.com/PaulStoffregen/LittleFS/blob/main/src/LittleFS.h. Think you may need a refresh :) Me too most of the time. I forgot to remove @KurtE's date modifications from my local directory first pass through :)

I saw what you did when I updated using CodeCompare.

Left me confused ... too long since touching LittleFS - I did a sync from github and I have this :: bool lowLevelFormat(char progressChar=0, Print* pr=&Serial);
Seemed to match with td1.54 b9 as I did code compares to make sure I had no other needed changes.

Paul liked the sync() idea - that is probably needed on any FLASH using data_cache as well, or pending changes would be lost on Power Loss on what should be 'permanent' media?

I'll go back to doing a PR with your confirmation that it is at least sane and seemingly safe and complete.

This will require any 'Warm Start' user on RAM2 or PSRAM Media to do some format if they expect to start with a fresh drive on any entry to setup() - but that is easier to explain than 'Lost Data' because they found a bug and edited code to new code, or touched the Button, or had a code Fault after some hours or days of trusting the data to be there.

Looking at the .ld files I don't see any easy way to avoid using this hardcoded value to skip RAM1 flush? :: if ( c->context >= (void *)0x20200000 ) {
> Not sure this is a usable 'named item' :: RAM (rwx): ORIGIN = 0x20200000
 
Status
Not open for further replies.
Back
Top