ramdisk ramfs trouble-shooting

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

ramdisk ramfs trouble-shooting

Post by davef » Fri Feb 12, 2021 8:52 pm

Straight from the docs and on a ESP8266:

Code: Select all

import os

bdev = RAMBlockDev(512, 5) #  ~2K5
os.VfsFat.mkfs(bdev)
os.mount(bdev, '/ramdisk')
Then a file called ramfs.py:

Code: Select all

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
And use it like this:

Code: Select all

#  put header in a new datalog.csv file
try:
    with open('/ramdisk/datalog.csv', 'w') as outfile:
        outfile.write('Time' + ',' 'Batt voltage' + '\n')
except OSError as error:
    try:
        with open('errors.txt', 'a') as outfile:
            outfile.write(str(error) + '\n')
    except OSError:
        print('oops')
But at random times it appears that something fails when writing to
/ramdisk and the device re-boots ... with no messages in errors.txt.

gc.mem_free() indicates that there is 4-5 times more memory available
than the 2K5 used for /ramdisk

Could someone suggest where to throw some error-trapping into
class RAMBlockDev to gain some insight into what is going wrong?

Thanks

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: ramdisk ramfs trouble-shooting

Post by davef » Sun Feb 14, 2021 9:10 pm

Putting the header into datalog.csv is maybe not where it fails. Later in the program where I actually write data to this file:

Code: Select all

        time = '18:00'   

        try:
            with open('/ramdisk/datalog.csv', 'a') as outfile:
                outfile.write(time + ',')
                outfile.write(str(battery_26V) + ',')
                outfile.write('\n')
        except OSError as error:
            try:
                with open('errors.txt', 'a') as outfile:
                    outfile.write(time + '\n')
                    outfile.write('2nd write' + '\n')
                    outfile.write(str(error) + '\n')
            except OSError:
                print('oops')
I do get an "error" ... the error is <28> . I have no idea what the 28 means.

Sure would be nice to get a ramdisk working on the ESP8266 before the flash wears-out.

Thanks.

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: ramdisk ramfs trouble-shooting

Post by jimmo » Mon Feb 15, 2021 1:45 am

davef wrote:
Sun Feb 14, 2021 9:10 pm
I do get an "error" ... the error is <28> . I have no idea what the 28 means.
#define MP_ENOSPC (28) // No space left on device

To look up these codes, in regular Python

>>> import os
>>> os.strerror(28)
'No space left on device'

Or look at micropython-lib/errno/errno.py

2.5kiB, and perhaps more importantly only 5 blocks, is not a lot of room for a filesystem. (I know you're a bit constrained by RAM).

But in this case instead of all the trouble of a bytearray-backed filesystem, you could just append entries to an in-memory bytearray?

i.e.

Code: Select all

data = bytearray(5*512)
data_mv = memoryview(data)
offset = 0
record_size = 4+4

def add_record(t, v):
  data_mv[offset:offset+record_size] = struct.pack('<II', t, v)
  offset += record_size
davef wrote:
Sun Feb 14, 2021 9:10 pm
ESP8266 before the flash wears-out.
If you're using littlefs (now the default) it does wear levelling. But yeah, flushing (or closing) the file on every write will cause a whole block to get written.

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: ramdisk ramfs trouble-shooting

Post by davef » Mon Feb 15, 2021 3:00 am

jimmo,

Thank you very much. I looked around for an error 28 but couldn't find anything. I'll check the link you provided.

It is only one file about 1-2K long that over a 6 hour period gets a small amount of data saved to it every minute. I will consider your example.

Looks like my gc.mem_free() knowledge is lacking ... my process is to run the program, do Ctrl C then gc.mem_free() I had about 15-16K free so took off 2-3K for the ramdisk and incorrectly concluded that I had plenty of space left. What is the proper way to query free space?

Thanks,
Dave

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: ramdisk ramfs trouble-shooting

Post by jimmo » Mon Feb 15, 2021 3:26 am

davef wrote:
Mon Feb 15, 2021 3:00 am
Looks like my gc.mem_free() knowledge is lacking ... my process is to run the program, do Ctrl C then gc.mem_free() I had about 15-16K free so took off 2-3K for the ramdisk and incorrectly concluded that I had plenty of space left. What is the proper way to query free space?
In this case the free space error is coming from the filesystem - i.e. FAT tried to allocate another sector/cluster/block and they were all in use. The error is literally "the disk is out of space".

Post Reply