Skip to content

Commit

Permalink
Merge pull request #7 from ironsheep/develop
Browse files Browse the repository at this point in the history
Develop let's publish ver 2.0 of the new tested flash_fs
  • Loading branch information
ironsheep authored Dec 28, 2023
2 parents fed02cd + d2a2ab5 commit d1a21c7
Show file tree
Hide file tree
Showing 35 changed files with 12,022 additions and 3,927 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,9 @@ cython_debug/
#.idea/
REF/isp_dummy_flash.spin2
REF/*-OLD.spin2
_OLD/
*.swp
.vscode/

cgsm_flash_file_demo/

3 changes: 1 addition & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ And last but not least: Always write your commit messages in the present tense.

## License

Licensed under the MIT License. Copyright © 2023 Iron Sheep Productions, LLC.

Licensed under the MIT License.

Follow these links for more information:

Expand Down
57 changes: 54 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ Additional pages:

- [The flash_fs Object I/F Documentation](flash_fs.txt) - the object interface with documentation for each public method
- [SPI FLASH Datasheet](./DOCs/W25Q128JV-210823.pdf) - our FLASH Chip Datasheet
- [FS Theory of Operations](THEOPS.md) - a detailed description of key concepts of this filesystem
- [Regression Testing Status](./RegresssionTests) - regression test code and output logs - growing as we certify each of the features (604+ tests so far)
- [FS Theory of Operations](THEOPSv2.md) - a detailed description of key concepts of this filesystem (See [v1.x FS Theory of...](THEOPS.md) for earlier version)
- [Regression Testing Status](./RegresssionTests) - regression test code and output logs - growing as we certify each of the features (900+ tests so far)

## Flash Filesystem Features

Expand All @@ -39,10 +39,61 @@ Key features of this Flash Filesystem for the P2 Edge Flash chip:
- Filenames are 127 characters plus zero terminator
- Seeks supported
- File Append supported
- Read-Modify-Write supported
- Circular file writes supported
- Supports multi-cog use (first cog to call mount() mounts the filesystem for all cogs to use.)
- **Coming soon** *Directory Support*

## Features of Note

In addition to standard file operations this filesystem contains a couple features worth noting:

### Feature: Circular files

Circulr files are useful when you want to record the most recent journal entries (or event log entries) in a file.

One writes to circular files by appending to them. At file open, one specifies a maximum limit to the file size in bytes, for example:

```spin2
status := flash.open_circular(@"filename", "a", 8_192)
... many writes ...
status := flash.close()
```

In this example you see a file being limited to 8k bytes. This means keep track of the last 8k bytes worth of journal or log entries. Upon close the journal will be reduced to the requested limit.

NOTE: Remember to call `flash.flush()` periodically to keep the pending writes small enough so that you don't run out of flash space.

An `open_circular(..., "r", 8_192)` is provided so that one can open the journal file and start reading at the front of the last 8_192 bytes in the file.


### Feature: File Read-Modify-Write

You can now modiify existing files on flash. Think of a file which contains fixed size records, maybe the state of an array of sensors where each sensor (or group of sensors) is in their own record within the file.

```spin2
status := flash.open(@"filename", %"r+") ' alternatively use FILEMODE_READ_EXTENDED for %"r+"
... many reads and/or replacing writes ...
status := flash.close()
```

Open the file with the new %"r+" mode., then seek to the record you wish to replace and write it (replacing the record already there.) Continue by seeking to locations and writing new records. Of course you can seek to and read the existing records, too. Lastly close the file as normal.

We also provide an open mode of `flash.open(@"filename", %"w+")` where you first have to write the new records before you can seek to them or replace them with new records.

Lastly we've added a `flash.create_file()` method which you can use to create an initialized file with empty records. For example:

```spin2
' create empty file
status := flash.create_file(@"filename", $00, 4_096)
' now do updates to the file
status := flash.open(@"filename", %"r+")
... many reads and/or replacing writes ...
status := flash.close()
```

In this example we are initilizing a file with 4k bytes of zeros. You can use any byte value you wish for the fill value.

## Adding the Flash FS to your own project

This section describes how to quickly get the flash filesystem working in your project.
Expand Down Expand Up @@ -136,7 +187,7 @@ Thank you also to members of the [forum thread - "On-Board Flash File System"](h

## License

Licensed under the MIT License. Copyright © 2023 Iron Sheep Productions, LLC.
Licensed under the MIT License.

Follow these links for more information:

Expand Down
48 changes: 25 additions & 23 deletions REF/Draft_FlashFileSystem_16MB_Demo.spin2
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
CON _CLKFREQ = 320_000_000

debug_top = 20
debug_height = 2400
'debug_height = 2400
debug_height = 1000

OBJ Flash : "Draft_FlashFileSystem_16MB"

Expand All @@ -13,8 +14,8 @@ PUB gox()

PUB go() | i

Flash.Format() 'Comment out this line to not erase all files
Flash.Mount()
Flash.format() 'Comment out this line to not erase all files
Flash.mount()

ShowStats() 'Do a bunch of file stuff while reporting status, along the way
ShowFiles()
Expand All @@ -29,8 +30,8 @@ PUB go() | i
ShowStats()
ShowFiles()

if Flash.Exists(@"file3") and not Flash.Exists(@"Apples")
Flash.Rename(@"file3",@"Apples")
if Flash.exists(@"file3") and not Flash.exists(@"Apples")
Flash.rename(@"file3",@"Apples")

repeat i from 1 to 10'366+20
AppendFile2(@"file1")
Expand All @@ -40,7 +41,7 @@ PUB go() | i
flash.MakeFile(@"AAA", 12000)

flash.MakeFile(@"Made", 10000)
'Flash.Delete(@"file1")
'Flash.delete(@"file1")

ModifyFile(@"file1", 1, @"abc")

Expand All @@ -50,13 +51,14 @@ PUB go() | i

PRI ShowStats() | BlocksUsed, BlocksFree, Files

BlocksUsed, BlocksFree, Files := Flash.Stats()
BlocksUsed, BlocksFree, Files := Flash.stats()
debug(udec(BlocksUsed, BlocksFree, Files))


PRI ShowFiles() | ID, ByteCount, Handle, Ptr, x, byte Filename[$80], byte Buff[15000]
'PRI ShowFiles() | ID, ByteCount, Handle, Ptr, x, byte Filename[Flash.FILENAME_SIZE], byte Buff[15000]
repeat
Flash.Directory(@ID, @Filename, @ByteCount) 'get next file
Flash.directory(@ID, @Filename, @ByteCount) 'get next file
if Filename[0] 'is there a filename?
bytefill(@Buff, 0, 100)
ReadFile(@Filename, @Buff) 'read file
Expand All @@ -68,10 +70,10 @@ PRI ShowFiles() | ID, ByteCount, Handle, Ptr, x, byte Filename[$80], byte Buff[1
PRI ReadFile(pFilename, pBuff) | Handle, x

Handle := Flash.OpenRead(pFilename) 'open file for reading
repeat Flash.SizeOf(pFilename)
byte[pBuff++] := Flash.ReadByte(Handle) 'read bytes
repeat Flash.file_size(pFilename)
byte[pBuff++] := Flash.rd_byte(Handle) 'read bytes

Flash.Close(Handle) 'close file
Flash.close(Handle) 'close file


PRI WriteFile(pFilename, pBuff) | Handle
Expand All @@ -81,10 +83,10 @@ PRI WriteFile(pFilename, pBuff) | Handle
Handle := Flash.OpenWrite(pFilename) 'open file for writing

repeat 'write bytes until 0 written
Flash.WriteByte(Handle, byte[pBuff])
Flash.wr_byte(Handle, byte[pBuff])
while byte[pBuff++]

Flash.Close(Handle) 'close file
Flash.close(Handle) 'close file


PRI AppendFile(pFilename, pBuff) | Handle
Expand All @@ -94,43 +96,43 @@ PRI AppendFile(pFilename, pBuff) | Handle
Handle := Flash.OpenAppendFroncate(pFilename, 9) 'open file for appending

repeat 'write bytes until 0 written
Flash.WriteByte(Handle, byte[pBuff])
Flash.wr_byte(Handle, byte[pBuff])
while byte[pBuff++]

Flash.Close(Handle) 'close file
Flash.close(Handle) 'close file


PRI AppendFile2(pFilename) | Handle

Handle := Flash.OpenAppendFroncate(pFilename, 10) 'open file for appending
repeat 11
Flash.WriteByte(Handle, chr1)
Flash.wr_byte(Handle, chr1)
if chr1 == "9"
chr1 := "0"
else
chr1++
Flash.Close(Handle) 'close file
Flash.close(Handle) 'close file

'Flash.Truncate(pFilename, 0)


PRI ReadFile2(pFilename, pBuff) | Handle, x

Handle := Flash.OpenRead(pFilename) 'open file for reading
repeat Flash.SizeOf(pFilename)
byte[pBuff++] := Flash.ReadByte(Handle) 'read bytes
repeat Flash.file_size(pFilename)
byte[pBuff++] := Flash.rd_byte(Handle) 'read bytes
byte[pBuff] := 0

Flash.Close(Handle) 'close file
Flash.close(Handle) 'close file


PRI ModifyFile(pFilename, Location, pData) | Handle

Handle := Flash.OpenModify(pFilename) 'open file for appending
Flash.Seek(Handle, Location)
Flash.SeekAbs(Handle, Location)
repeat strsize(pData)
Flash.WriteByte(Handle, byte[pData++])
Flash.Close(Handle) 'close file
Flash.wr_byte(Handle, byte[pData++])
Flash.close(Handle) 'close file


DAT
Expand Down
Loading

0 comments on commit d1a21c7

Please sign in to comment.