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 }