kopia lustrzana https://github.com/peterhinch/micropython_eeprom
Littlefs support. Test scripts adapted to use it.
rodzic
d792a2be7f
commit
4624fb41c6
14
README.md
14
README.md
|
@ -1,6 +1,6 @@
|
|||
# 1. MicroPython drivers for nonvolatile memory
|
||||
|
||||
These drivers support nonvolatile memory chips.
|
||||
These drivers support nonvolatile memory chips and the littlefs filesystem.
|
||||
|
||||
Currently supported devices use technologies having superior performance
|
||||
compared to flash. Resultant storage has much higher write endurance. In some
|
||||
|
@ -18,7 +18,7 @@ The drivers have the following common features:
|
|||
a `readwrite` method.
|
||||
3. Alternatively the array can be formatted and mounted as a filesystem using
|
||||
methods in the `uos` module. Any filesystem supported by the MicroPython build
|
||||
may be employed.
|
||||
may be employed: FAT and littlefs have been tested. The latter is recommended.
|
||||
4. Drivers are portable: buses and pins should be instantiated using the
|
||||
`machine` module.
|
||||
5. Buses may be shared with other hardware. This assumes that the application
|
||||
|
@ -59,6 +59,8 @@ In the table below the Interface column includes page size in bytes.
|
|||
| Microchip | 24xx64 | I2C 128 | 8KiB | EEPROM | [I2C.md](./i2c/I2C.md) |
|
||||
| Adafruit | 1895 | I2C n/a | 32KiB | FRAM | [FRAM.md](./fram/FRAM.md) |
|
||||
|
||||
**STM chip support under development**
|
||||
|
||||
Documentation:
|
||||
[SPI.md](./spi/SPI.md)
|
||||
[I2C.md](./i2c/I2C.md)
|
||||
|
@ -104,8 +106,8 @@ in the ioctl and (if necessary) implementing a block erase method.
|
|||
|
||||
The nature of the drivers in this repo implies that the page size in the ioctl
|
||||
is arbitrary. Littlefs requires a minimum size of 128 bytes -
|
||||
[theoretically 104](https://github.com/ARMmbed/littlefs/blob/master/DESIGN.md)
|
||||
but the driver only allows powers of 2. Testing was done with 512 bytes.
|
||||
[theoretically 104](https://github.com/ARMmbed/littlefs/blob/master/DESIGN.md).
|
||||
The driver only allows powers of 2. Testing was done with 512 bytes.
|
||||
|
||||
Currently I have not had success with littlefs but it hasn't yet officially
|
||||
been released. The test programs therefore use FAT.
|
||||
The test programs use littlefs and therefore require MicroPython V1.12 or
|
||||
later.
|
||||
|
|
|
@ -62,13 +62,13 @@ class BlockDevice:
|
|||
|
||||
# IOCTL protocol.
|
||||
def readblocks(self, blocknum, buf, offset=0):
|
||||
return self.readwrite(offset + (blocknum << self._nbits), buf, True)
|
||||
self.readwrite(offset + (blocknum << self._nbits), buf, True)
|
||||
|
||||
def writeblocks(self, blocknum, buf, offset=0):
|
||||
def writeblocks(self, blocknum, buf, offset=None):
|
||||
offset = 0 if offset is None else offset
|
||||
self.readwrite(offset + (blocknum << self._nbits), buf, False)
|
||||
|
||||
def ioctl(self, op, arg):
|
||||
#print("ioctl(%d, %r)" % (op, arg))
|
||||
if op == 4: # BP_IOCTL_SEC_COUNT
|
||||
return self._a_bytes >> self._nbits
|
||||
if op == 5: # BP_IOCTL_SEC_SIZE
|
||||
|
|
11
fram/FRAM.md
11
fram/FRAM.md
|
@ -79,16 +79,17 @@ Installation: copy files 1 and 2 (optionally 3) to the target filesystem.
|
|||
|
||||
The driver supports mounting the FRAM chips as a filesystem. Initially the
|
||||
device will be unformatted so it is necessary to issue code along these lines
|
||||
to format the device. Code assumes one or more devices:
|
||||
to format the device. Code assumes one or more devices and also assumes the
|
||||
littlefs filesystem:
|
||||
|
||||
```python
|
||||
import uos
|
||||
import os
|
||||
from machine import I2C
|
||||
from fram_i2c import FRAM
|
||||
fram = FRAM(I2C(2))
|
||||
uos.VfsFat.mkfs(fram) # Omit this to mount an existing filesystem
|
||||
vfs = uos.VfsFat(fram)
|
||||
uos.mount(vfs,'/fram')
|
||||
# Format the filesystem
|
||||
os.VfsLfs2.mkfs(fram) # Omit this to mount an existing filesystem
|
||||
os.mount(fram,'/fram')
|
||||
```
|
||||
The above will reformat a drive with an existing filesystem: to mount an
|
||||
existing filesystem simply omit the commented line.
|
||||
|
|
|
@ -47,21 +47,6 @@ class FRAM(BlockDevice):
|
|||
productID = ((res[1] & 0x0F) << 8) + res[2]
|
||||
return manufacturerID == _MANF_ID and productID == _PRODUCT_ID
|
||||
|
||||
def __setitem__(self, addr, value):
|
||||
if isinstance(addr, slice):
|
||||
return self.wslice(addr, value)
|
||||
self._buf1[0] = value
|
||||
self._getaddr(addr, 1)
|
||||
self._i2c.writevto(self._i2c_addr, (self._addrbuf, self._buf1))
|
||||
|
||||
def __getitem__(self, addr):
|
||||
if isinstance(addr, slice):
|
||||
return self.rslice(addr)
|
||||
self._getaddr(addr, 1)
|
||||
self._i2c.writeto(self._i2c_addr, self._addrbuf)
|
||||
self._i2c.readfrom_into(self._i2c_addr, self._buf1)
|
||||
return self._buf1[0]
|
||||
|
||||
# In the context of FRAM a page == a chip.
|
||||
# Args: an address and a no. of bytes. Set ._i2c_addr to correct chip.
|
||||
# Return the no. of bytes available to access on that chip.
|
||||
|
|
13
i2c/I2C.md
13
i2c/I2C.md
|
@ -77,17 +77,18 @@ Installation: copy files 1 and 2 (optionally 3) to the target filesystem.
|
|||
# 4. The device driver
|
||||
|
||||
The driver supports mounting the EEPROM chips as a filesystem. Initially the
|
||||
device will be unformatted so it is necessary to issue code along these lines to
|
||||
format the device. Code assumes one or more 64KiB devices:
|
||||
device will be unformatted so it is necessary to issue code along these lines
|
||||
to format the device. Code assumes one or more 64KiB devices and also assumes
|
||||
the littlefs filesystem:
|
||||
|
||||
```python
|
||||
import uos
|
||||
import os
|
||||
from machine import I2C
|
||||
from eeprom_i2c import EEPROM, T24C512
|
||||
eep = EEPROM(I2C(2), T24C512)
|
||||
uos.VfsFat.mkfs(eep) # Omit this to mount an existing filesystem
|
||||
vfs = uos.VfsFat(eep)
|
||||
uos.mount(vfs,'/eeprom')
|
||||
# Format the filesystem
|
||||
os.VfsLfs2.mkfs(eep) # Omit this to mount an existing filesystem
|
||||
os.mount(eep,'/eeprom')
|
||||
```
|
||||
The above will reformat a drive with an existing filesystem: to mount an
|
||||
existing filesystem simply omit the commented line.
|
||||
|
|
|
@ -93,11 +93,19 @@ def test():
|
|||
# ***** TEST OF FILESYSTEM MOUNT *****
|
||||
def fstest(format=False):
|
||||
eep = get_eep()
|
||||
# ***** CODE FOR FATFS *****
|
||||
#if format:
|
||||
#uos.VfsFat.mkfs(eep)
|
||||
#vfs=uos.VfsFat(eep)
|
||||
#try:
|
||||
#uos.mount(vfs,'/eeprom')
|
||||
#except OSError: # Already mounted
|
||||
#pass
|
||||
# ***** CODE FOR LITTLEFS *****
|
||||
if format:
|
||||
uos.VfsFat.mkfs(eep)
|
||||
vfs=uos.VfsFat(eep)
|
||||
uos.VfsLfs2.mkfs(eep)
|
||||
try:
|
||||
uos.mount(vfs,'/eeprom')
|
||||
uos.mount(eep,'/eeprom')
|
||||
except OSError: # Already mounted
|
||||
pass
|
||||
print('Contents of "/": {}'.format(uos.listdir('/')))
|
||||
|
@ -109,9 +117,14 @@ def cptest():
|
|||
if 'eeprom' in uos.listdir('/'):
|
||||
print('Device already mounted.')
|
||||
else:
|
||||
vfs=uos.VfsFat(eep)
|
||||
#vfs=uos.VfsFat(eep)
|
||||
#try:
|
||||
#uos.mount(vfs,'/eeprom')
|
||||
#except OSError:
|
||||
#print('Fail mounting device. Have you formatted it?')
|
||||
#return
|
||||
try:
|
||||
uos.mount(vfs,'/eeprom')
|
||||
uos.mount(eep,'/eeprom')
|
||||
except OSError:
|
||||
print('Fail mounting device. Have you formatted it?')
|
||||
return
|
||||
|
|
|
@ -82,4 +82,3 @@ class EEPROM(BlockDevice):
|
|||
nbytes -= npage
|
||||
start += npage
|
||||
addr += npage
|
||||
return buf
|
||||
|
|
17
spi/SPI.md
17
spi/SPI.md
|
@ -4,6 +4,8 @@ This driver supports the Microchip 25xx1024 series of 128KiB SPI EEPROMs and
|
|||
the STM M95M02-DR 256KiB device. These have 1M and 4M cycles of write endurance
|
||||
respectively (compared to 10K for Pyboard Flash memory).
|
||||
|
||||
**NOTE: STM chip not yet tested**
|
||||
|
||||
Multiple chips may be used to construct a single logical nonvolatile memory
|
||||
module. The driver allows the memory either to be mounted in the target
|
||||
filesystem as a disk device or to be addressed as an array of bytes.
|
||||
|
@ -75,18 +77,19 @@ Installation: copy files 1 and 2 (optionally 3) to the target filesystem.
|
|||
# 4. The device driver
|
||||
|
||||
The driver supports mounting the EEPROM chips as a filesystem. Initially the
|
||||
device will be unformatted so it is necessary to issue code along these lines to
|
||||
format the device. Code assumes two Microchip devices:
|
||||
device will be unformatted so it is necessary to issue code along these lines
|
||||
to format the device. Code assumes two Microchip devices and also assumes the
|
||||
littlefs filesystem:
|
||||
|
||||
```python
|
||||
import uos
|
||||
import os
|
||||
from machine import SPI, Pin
|
||||
from eeprom_spi import EEPROM
|
||||
cspins = (Pin(Pin.board.Y5, Pin.OUT, value=1), Pin(Pin.board.Y4, Pin.OUT, value=1))
|
||||
eep = EEPROM(SPI(2, baudrate=20_000_000), cspins)
|
||||
uos.VfsFat.mkfs(eep) # Omit this to mount an existing filesystem
|
||||
vfs = uos.VfsFat(eep)
|
||||
uos.mount(vfs,'/eeprom')
|
||||
# Format the filesystem
|
||||
os.VfsLfs2.mkfs(eep) # Omit this to mount an existing filesystem
|
||||
os.mount(eep,'/eeprom')
|
||||
```
|
||||
The above will reformat a drive with an existing filesystem: to mount an
|
||||
existing filesystem simply omit the commented line.
|
||||
|
@ -122,7 +125,7 @@ Arguments:
|
|||
|
||||
SPI baudrate: The 25LC1024 supports baudrates of upto 20MHz. If this value is
|
||||
specified the platform will produce the highest available frequency not
|
||||
exceeding this figure.
|
||||
exceeding this figure. Note that the STM chip has a maximum rate of 5MHz.
|
||||
|
||||
### 4.1.2 Methods providing byte level access
|
||||
|
||||
|
|
|
@ -97,11 +97,19 @@ def test(stm=False):
|
|||
# ***** TEST OF FILESYSTEM MOUNT *****
|
||||
def fstest(format=False, stm=False):
|
||||
eep = get_eep(stm)
|
||||
# ***** CODE FOR FATFS *****
|
||||
#if format:
|
||||
#uos.VfsFat.mkfs(eep)
|
||||
#vfs=uos.VfsFat(eep)
|
||||
#try:
|
||||
#uos.mount(vfs,'/eeprom')
|
||||
#except OSError: # Already mounted
|
||||
#pass
|
||||
# ***** CODE FOR LITTLEFS *****
|
||||
if format:
|
||||
uos.VfsFat.mkfs(eep)
|
||||
vfs=uos.VfsFat(eep)
|
||||
uos.VfsLfs2.mkfs(eep)
|
||||
try:
|
||||
uos.mount(vfs,'/eeprom')
|
||||
uos.mount(eep,'/eeprom')
|
||||
except OSError: # Already mounted
|
||||
pass
|
||||
print('Contents of "/": {}'.format(uos.listdir('/')))
|
||||
|
@ -113,9 +121,15 @@ def cptest(stm=False):
|
|||
if 'eeprom' in uos.listdir('/'):
|
||||
print('Device already mounted.')
|
||||
else:
|
||||
vfs=uos.VfsFat(eep)
|
||||
#vfs=uos.VfsFat(eep)
|
||||
#try:
|
||||
#uos.mount(vfs,'/eeprom')
|
||||
#except OSError:
|
||||
#print('Fail mounting device. Have you formatted it?')
|
||||
#return
|
||||
#vfs=uos.VfsFat(eep)
|
||||
try:
|
||||
uos.mount(vfs,'/eeprom')
|
||||
uos.mount(eep,'/eeprom')
|
||||
except OSError:
|
||||
print('Fail mounting device. Have you formatted it?')
|
||||
return
|
||||
|
|
|
@ -163,4 +163,3 @@ class EEPROM(BlockDevice):
|
|||
nbytes -= npage
|
||||
start += npage
|
||||
addr += npage
|
||||
return buf
|
||||
|
|
Ładowanie…
Reference in New Issue