github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/flash.go (about)

     1  //go:build nrf || nrf51 || nrf52 || nrf528xx || stm32f4 || stm32l4 || stm32wlx || atsamd21 || atsamd51 || atsame5x || rp2040
     2  
     3  package machine
     4  
     5  import (
     6  	"errors"
     7  	"io"
     8  	"unsafe"
     9  )
    10  
    11  //go:extern __flash_data_start
    12  var flashDataStart [0]byte
    13  
    14  //go:extern __flash_data_end
    15  var flashDataEnd [0]byte
    16  
    17  // Return the start of the writable flash area, aligned on a page boundary. This
    18  // is usually just after the program and static data.
    19  func FlashDataStart() uintptr {
    20  	pagesize := uintptr(eraseBlockSize())
    21  	return (uintptr(unsafe.Pointer(&flashDataStart)) + pagesize - 1) &^ (pagesize - 1)
    22  }
    23  
    24  // Return the end of the writable flash area. Usually this is the address one
    25  // past the end of the on-chip flash.
    26  func FlashDataEnd() uintptr {
    27  	return uintptr(unsafe.Pointer(&flashDataEnd))
    28  }
    29  
    30  var (
    31  	errFlashCannotErasePage     = errors.New("cannot erase flash page")
    32  	errFlashInvalidWriteLength  = errors.New("write flash data must align to correct number of bits")
    33  	errFlashNotAllowedWriteData = errors.New("not allowed to write flash data")
    34  	errFlashCannotWriteData     = errors.New("cannot write flash data")
    35  	errFlashCannotReadPastEOF   = errors.New("cannot read beyond end of flash data")
    36  	errFlashCannotWritePastEOF  = errors.New("cannot write beyond end of flash data")
    37  	errFlashCannotErasePastEOF  = errors.New("cannot erase beyond end of flash data")
    38  )
    39  
    40  // BlockDevice is the raw device that is meant to store flash data.
    41  type BlockDevice interface {
    42  	// ReadAt reads the given number of bytes from the block device.
    43  	io.ReaderAt
    44  
    45  	// WriteAt writes the given number of bytes to the block device.
    46  	io.WriterAt
    47  
    48  	// Size returns the number of bytes in this block device.
    49  	Size() int64
    50  
    51  	// WriteBlockSize returns the block size in which data can be written to
    52  	// memory. It can be used by a client to optimize writes, non-aligned writes
    53  	// should always work correctly.
    54  	WriteBlockSize() int64
    55  
    56  	// EraseBlockSize returns the smallest erasable area on this particular chip
    57  	// in bytes. This is used for the block size in EraseBlocks.
    58  	// It must be a power of two, and may be as small as 1. A typical size is 4096.
    59  	EraseBlockSize() int64
    60  
    61  	// EraseBlocks erases the given number of blocks. An implementation may
    62  	// transparently coalesce ranges of blocks into larger bundles if the chip
    63  	// supports this. The start and len parameters are in block numbers, use
    64  	// EraseBlockSize to map addresses to blocks.
    65  	EraseBlocks(start, len int64) error
    66  }