Filesystem mounts created by pyboard.py are unstable.
When pyboard.py is used to mount a block device the mount can be lost. There are various circumstances in which this occurs.
The repro avoids external hardware by using the ramdisk from the docs. On a Pyboard 1.1 the following scripts were installed:
ramdisk.py
class RAMBlockDev:
def __init__(self, block_size, num_blocks):
self.block_size = block_size
self.data = bytearray(block_size * num_blocks)
def readblocks(self, block_num, buf):
for i in range(len(buf)):
buf[i] = self.data[block_num * self.block_size + i]
def writeblocks(self, block_num, buf):
for i in range(len(buf)):
self.data[block_num * self.block_size + i] = buf[i]
def ioctl(self, op, arg):
if op == 4: # get number of blocks
return len(self.data) // self.block_size
if op == 5: # get block size
return self.block_size
import os
bdev = RAMBlockDev(512, 50)
os.VfsFat.mkfs(bdev)
os.mount(bdev, '/ramdisk')
print(os.listdir('/'))
print(os.listdir('/ramdisk'))
ramdisk_lst.py
import os
print(os.listdir('/'))
The following CPython scripts were created:
make_ramdisk.py
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import pyboard
pyb = pyboard.Pyboard('/dev/ttyACM0')
pyb.enter_raw_repl()
print(pyb.exec('import ramdisk'))
pyb.exit_raw_repl()
test_ramdisk.py
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import pyboard
pyb = pyboard.Pyboard('/dev/ttyACM0')
pyb.enter_raw_repl()
print(pyb.exec('import ramdisk_lst'))
pyb.exit_raw_repl()
In this session the mount disappears killed by test_ramdisk.py:
$ ./make_ramdisk.py
b"['flash', 'ramdisk']\r\n[]\r\n"
[adminpete@capybara]: /mnt/qnap2/data/Projects/MicroPython/micropython/tools
$ ./test_ramdisk.py
b"['flash']\r\n"
In this one it persists. It is possible to enter and leave mpremote at will with the mount intact:
$ ./make_ramdisk.py
b"['flash', 'ramdisk']\r\n[]\r\n"
[adminpete@capybara]: /mnt/qnap2/data/Projects/MicroPython/micropython/tools
$ mpremote
Connected to MicroPython at /dev/ttyACM0
Use Ctrl-] to exit this shell
>>> import os
>>> os.listdir('/')
['flash', 'ramdisk']
>>>
In this session it disappears, killed by mpremote ls ::
$ ./make_ramdisk.py
b"['flash', 'ramdisk']\r\n[]\r\n"
[adminpete@capybara]: /mnt/qnap2/data/Projects/MicroPython/micropython/tools
$ mpremote ls :
ls :
323 boot.py
497 main.py
2999 pybcdc.inf
534 README.txt
17538 upower.py
3252 ttest.py
8634 sdcard.py
8698 sdcard_mod.py
65 ramdisk_lst.py
782 ramdisk.py
[adminpete@capybara]: /mnt/qnap2/data/Projects/MicroPython/micropython/tools
$ mpremote
Connected to MicroPython at /dev/ttyACM0
Use Ctrl-] to exit this shell
>>> import os
>>> os.listdir('/')
['flash']
>>>
pyb.mount() feature suggestion
When testing code using block protocol devices an issue arises where a coding error causes the program to fail between mounting the device and umounting it. In this instance the device remains mounted. The program then fails on a subsequent run with an OSError "device already mounted". While this can be circumvented by trapping the OSError, it's not ideal.
It would be better if the mount command implemented the context manager protocol.