Freezing Dictonary in Flash

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
Drako
Posts: 12
Joined: Thu Oct 19, 2017 9:28 am

Freezing Dictonary in Flash

Post by Drako » Thu May 31, 2018 7:48 am

Hi,

I understand that freezing strings in the flash saves RAM in micropython.

A source file containing

Code: Select all

MY_STRING = 'this is a long string, but I want it to be only a machine word in the RAM of the actual devcie'
which is frozen into the falsh and then imported saves RAM.

Is is also possible to freeze a dictonary into the flash and import it, to reduce the RAM usage? Something like this:

Code: Select all

MY_DICTONARY = {1: 'hello', 2: 'world', 3: 'this is a long string, but I want it to be only a machine word in the RAM of the actual devcie'}
And then import the dictonary?
Or do I have to define each string in the dictonary as a constant and build the dictonary like this:

Code: Select all

MY_STRING_1 = 'hello'
MY_STRING_2= 'wolrd'
MY_STRING_3 = 'this is a long string, but I want it to be only a machine word in the RAM of the actual devcie'

Code: Select all

import my_strings_in_flash

my_dict = {1: my_strings_in_flash.MY_STRING_1, 2 : my_strings_in_flash.MY_STRING_2, 3: my_strings_in_flash.MY_STRING_3} 
The point is, that I want to not have the strings in RAM but in the flash, to reduce unnecessary RAM usage. Freezing the whole dictonary at once into the flash would make the source code more readable.

User avatar
pythoncoder
Posts: 2967
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Freezing Dictonary in Flash

Post by pythoncoder » Thu May 31, 2018 8:06 am

You can save any Python sourcefile in Flash. However this doesn't necessarily save RAM, and it won't if the contents of the source file is a dict. This is because dicts are mutable: MicroPython doesn't "know" that your code won't modify the dict once loaded.

Python strings and bytes objects are immutable, hence they will remain in Flash. However even with these objects you do have to be quite careful: as soon as you perform an operation on them, such as taking a slice, the slice is a new object (precisely because the source is immutable). So the slice lives in RAM.

There are ways to use a memoryview object to avoid this with bytes objects. See this font file for an example.
Peter Hinch

Drako
Posts: 12
Joined: Thu Oct 19, 2017 9:28 am

Re: Freezing Dictonary in Flash

Post by Drako » Thu May 31, 2018 8:26 am

This makes perfect sense. Thanks

User avatar
dhylands
Posts: 2848
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Freezing Dictonary in Flash

Post by dhylands » Thu May 31, 2018 8:13 pm

You could freeze a dictionary in flash if you did it as part of a module coded in C. This probably isn't trivial or anything, but I'm pretty sure it could be done. Whether its worth the effort to actually implement will depend on how much data you're talking about.

The elements would be stored in an array of mp_rom_map_elem_t's, like this: https://github.com/micropython/micropyt ... pyb.c#L115

You would then declare a constant dict like this: https://github.com/micropython/micropyt ... pyb.c#L234

Unfortunately, I don't see any simple support for ROM strings, so this would need to be added.

Drako
Posts: 12
Joined: Thu Oct 19, 2017 9:28 am

Re: Freezing Dictonary in Flash

Post by Drako » Fri Jun 01, 2018 6:39 am

I see.

At the moment I don't have that much data, so implementing it as a C module is problaby not worth the effort.

I am basically attaching strings to error codes, so freezing the strings in the firmware and then building the dictonary in the source code works for now. If I am reaching the limits of my RAM, I will consider the possiblity of implementing it as a C module.

Thanks for the quick replies.

User avatar
pythoncoder
Posts: 2967
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Freezing Dictonary in Flash

Post by pythoncoder » Fri Jun 01, 2018 6:56 am

If the dict values were immutable (e.g. bytes objects) you could use an approach like font-to-py.

A PC utility would take a Python dict as input and create a MicroPython sourcefile as output. The sourcefile would contain a bytes object containing all the values with an accessor class. The accessor would have __getitem__ take as input the key and return a memoryview pointing to the value. (The offsets being stored in a table in the sourcefile as per font-to-py).
Peter Hinch

Post Reply