From b56a263d0d43d258b8af7880f6eb290095b65059 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Tue, 9 May 2023 22:03:11 +0200 Subject: [PATCH] machine/flash: remove FlashBuffer, modify flash example to use BlockDevice interface Signed-off-by: deadprogram --- src/examples/flash/main.go | 49 +++++++++++++++++------ src/machine/flash.go | 79 -------------------------------------- 2 files changed, 38 insertions(+), 90 deletions(-) diff --git a/src/examples/flash/main.go b/src/examples/flash/main.go index 923a6f87..504629c9 100644 --- a/src/examples/flash/main.go +++ b/src/examples/flash/main.go @@ -7,7 +7,10 @@ import ( var ( err error - message = "1234567887654321123456788765432112345678876543211234567887654321" + message = "1234567887654321123456788765432112345678876543211234567887654321" + + "1234567887654321123456788765432112345678876543211234567887654321" + + "1234567887654321123456788765432112345678876543211234567887654321" + + "1234567887654321123456788765432112345678876543211234567887654321" ) func main() { @@ -21,30 +24,54 @@ func main() { println("Flash erase block size:", machine.Flash.EraseBlockSize()) println() - flash := machine.OpenFlashBuffer(machine.Flash, machine.FlashDataStart()) original := make([]byte, len(message)) saved := make([]byte, len(message)) // Read flash contents on start (data shall survive power off) - print("Reading data from flash: ") - _, err = flash.Read(original) + println("Reading original data from flash:") + _, err = machine.Flash.ReadAt(original, 0) checkError(err) println(string(original)) + // erase flash + println("Erasing flash...") + needed := int64(len(message)) / machine.Flash.EraseBlockSize() + if needed == 0 { + // have to erase at least 1 block + needed = 1 + } + + err := machine.Flash.EraseBlocks(0, needed) + checkError(err) + // Write the message to flash - print("Writing data to flash: ") - flash.Seek(0, 0) // rewind back to beginning - _, err = flash.Write([]byte(message)) + println("Writing new data to flash:") + _, err = machine.Flash.WriteAt([]byte(message), 0) checkError(err) println(string(message)) // Read back flash contents after write (verify data is the same as written) - print("Reading data back from flash: ") - flash.Seek(0, 0) // rewind back to beginning - _, err = flash.Read(saved) + println("Reading data back from flash: ") + _, err = machine.Flash.ReadAt(saved, 0) checkError(err) + if !equal(saved, []byte(message)) { + println("data verify error") + } + println(string(saved)) - println() + println("Done.") +} + +func equal(a, b []byte) bool { + if len(a) != len(b) { + return false + } + for i, v := range a { + if v != b[i] { + return false + } + } + return true } func checkError(err error) { diff --git a/src/machine/flash.go b/src/machine/flash.go index 885e5c88..716fc4a5 100644 --- a/src/machine/flash.go +++ b/src/machine/flash.go @@ -64,82 +64,3 @@ type BlockDevice interface { // EraseBlockSize to map addresses to blocks. EraseBlocks(start, len int64) error } - -// FlashBuffer implements the ReadWriteCloser interface using the BlockDevice interface. -type FlashBuffer struct { - b BlockDevice - - // start is actual address - start uintptr - - // offset is relative to start - offset uintptr -} - -// OpenFlashBuffer opens a FlashBuffer. -func OpenFlashBuffer(b BlockDevice, address uintptr) *FlashBuffer { - return &FlashBuffer{b: b, start: address} -} - -// Read data from a FlashBuffer. -func (fl *FlashBuffer) Read(p []byte) (n int, err error) { - n, err = fl.b.ReadAt(p, int64(fl.offset)) - fl.offset += uintptr(n) - - return -} - -// Write data to a FlashBuffer. -func (fl *FlashBuffer) Write(p []byte) (n int, err error) { - // any new pages needed? - // NOTE probably will not work as expected if you try to write over page boundary - // of pages with different sizes. - pagesize := uintptr(fl.b.EraseBlockSize()) - - // calculate currentPageBlock relative to fl.start, meaning that - // block 0 -> fl.start - // block 1 -> fl.start + pagesize - // block 2 -> fl.start + pagesize*2 - // ... - currentPageBlock := (fl.start + fl.offset - FlashDataStart()) + (pagesize-1)/pagesize - lastPageBlockNeeded := (fl.start + fl.offset + uintptr(len(p)) - FlashDataStart()) + (pagesize-1)/pagesize - - // erase enough blocks to hold the data - if err := fl.b.EraseBlocks(int64(currentPageBlock), int64(lastPageBlockNeeded-currentPageBlock)); err != nil { - return 0, err - } - - // write the data - for i := 0; i < len(p); i += int(pagesize) { - var last int = i + int(pagesize) - if i+int(pagesize) > len(p) { - last = len(p) - } - - _, err := fl.b.WriteAt(p[i:last], int64(fl.offset)) - if err != nil { - return 0, err - } - fl.offset += uintptr(len(p[i:last])) - } - - return len(p), nil -} - -// Close the FlashBuffer. -func (fl *FlashBuffer) Close() error { - return nil -} - -// Seek implements io.Seeker interface, but with limitations. -// You can only seek relative to the start. -// Also, you cannot use seek before write operations, only read. -func (fl *FlashBuffer) Seek(offset int64, whence int) (int64, error) { - if whence != io.SeekStart { - panic("you can only Seek relative to Start") - } - - fl.offset = uintptr(offset) - - return offset, nil -}