ram alternative to nvram?

  • When I google the topic of using ram instead of flash most results suggest setting up a ram drive & mounting it. But I'm just looking for a few bytes of ram I can use as an alternative to flash. So something like f=open('/some/spare/ram', 'w'); f.write(str(cycle)); f.close() where /some/spare/ram is a location in ram rather than in flash. Does anybody know of some unused GPY ram I could try this on?

  • @robert-hh said in ram alternative to nvram?:

    Having the RAM disk mirrored to RTC memory is hardly usable, since the size is limited to 2048 byte.

    Thanks for your investigations revolving this and for letting us know about the outcome!

  • @andreas I tried to have that RAMdisk mirrored to RTC. That is hardly usable, since the size is limited to 2048 byte.

  • @robert-hh said in ram alternative to nvram?:

    RAMBlockDev is using storage from the regular RAM [but] one could rewrite it to use the RTC RAM for storage.

    Thanks for clarifying that. This sounds like a viable option to me.

    However, using external FRAM would be the more straight option in general, so thanks again for outlining that in your post above.

  • @andreas RAMblkdev is using storage from the regular RAM. Being dead simple, one could rewrite it to use the RTC RAM for storage. Only it had to re-write the full 8k all the time, and keep a temp copy in RAM.
    It seems more efficient to use a dictionary and pickle to store that RTC RAM.

  • @robert-hh said in ram alternative to nvram?:

    In principle the RTC memory is kept during deepsleep

    That's probably true, but just for the sake of completeness and to avoid further confusion: The RAMBlockDev is going straight to normal RAM by using the bytearray within self.data as storage, right?

    Mapping that guy to rtc.memory() might be considered an alternative option of making the content persist across deep sleep cycles.

  • @andreas In principle the RTC memory is kept during deepsleep, but I recall faintly that is is wiped on boot. That could be dropped. Adafruit offer two FRAM modules, and @pythoncoder (Peter Hinch) has made a block device driver for that at: https://github.com/peterhinch/micropython-fram.git
    Peter Hinch' repositories are always worth a look, especially for his good tutorial on asyncio,

  • Thanks a bunch, @robert-hh! We just cross-posted this to [1], giving you appropriate credits for bringing that to Pycom MicroPython.

    We probably have the same intentions as @kjm, using some memory for buffering measurement data when there is no network connectivity.

    However, we all have to be aware that memory content will be lost when going to deep sleep. While that might be obvious for us, I am mentioning this detail for all others coming here for whom that might not be exactly clear.

    [1] https://community.hiveeyes.org/t/zwischenspeicherung-von-daten-innerhalb-verschiedener-volatiler-ram-speicher-des-esp32/2440/4

  • @kjm I searched a little bit in my memory & net and found a ramdisk implementation, which I adapted to Pycom#s firmware. Code below:
    part 1: Ramdisk Block device. Author Damien George, the master brain of MicroPython:

    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

    Part 2: Small script which creates the ramdisk of size 32k.

    import uos
    from ramblkdev import *
    # 512 is the sector size, fixed for FAT, 64 is the number of sectors.
    # 64 -> 32k 
    bdev=RAMBlockDev(512, 64)
    uos.mount(fs, "/ramdisk")

  • @kjm There is this pycom.nvsxxx() set of functions, which can be used for that - still flash. There is some RAM (8k) assigned to the RTC, with a very raw interface.

    from machine import RTC
    rtc.memory("Store some string or bytearray") # stor something there
    stored_value = rtc.memory()  # and get it back

    You can only store strings or byte-array. Complex data has to be serialized. e.g. with json dumps() and loads().
    For serialization you may also use pickle, which is available at https://github.com/micropython/micropython-lib. That lib is a vein of gold for many micropython tasks, maintained by Paul Solokovsky (@pfalcon), who is a major contributor to MicroPython, especially the ESP8266 port.

Log in to reply

Pycom on Twitter