Page 1 of 1

Freezing Dictonary in Flash

Posted: Thu May 31, 2018 7:48 am
by Drako
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.

Re: Freezing Dictonary in Flash

Posted: Thu May 31, 2018 8:06 am
by pythoncoder
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.

Re: Freezing Dictonary in Flash

Posted: Thu May 31, 2018 8:26 am
by Drako
This makes perfect sense. Thanks

Re: Freezing Dictonary in Flash

Posted: Thu May 31, 2018 8:13 pm
by dhylands
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.

Re: Freezing Dictonary in Flash

Posted: Fri Jun 01, 2018 6:39 am
by Drako
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.

Re: Freezing Dictonary in Flash

Posted: Fri Jun 01, 2018 6:56 am
by pythoncoder
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).