← index #10328Issue #1807
Related · medium · value 0.237
QUERY · ISSUE

Filesystem mounts created by pyboard.py are unstable.

openby peterhinchopened 2022-12-25updated 2022-12-25
bug

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']
>>> 
CANDIDATE · ISSUE

pyb.mount() feature suggestion

closedby peterhinchopened 2016-01-30updated 2017-05-13

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.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied