Page 1 of 1

Create read-only array in code memory, not RAM?

Posted: Mon Aug 20, 2018 7:21 pm
by Siriushardware
I have a need to define some two dimensional arrays which, at run-time, will be read-only. I would therefore prefer them to be created in code memory rather than in precious RAM.

In 'C' I would force them to be created in ROM by declaring the array as CONST unsigned char myarray=.... etc, is there an equivalent way to force a read only array to be created in code memory rather than in RAM in Micropython?

Re: Create read-only array in code memory, not RAM?

Posted: Mon Aug 20, 2018 9:24 pm
by OutoftheBOTS_
Mico Python has a const() fuction that does the same thing

see http://docs.micropython.org/en/latest/w ... ained.html

Re: Create read-only array in code memory, not RAM?

Posted: Mon Aug 20, 2018 10:12 pm
by Siriushardware
Thank you, I read that, but I still don't get it. I think I must have a blind spot for Python because, try as I might, I can rarely find a simple defined example which shows exactly what I think I want to do when looking through Python related docs. That document shows how to declare a simple variable as a CONST but doesn't seem to give examples for more complex data structures.

Take an actual fragment of code:

Code: Select all

MyArray = [[1,2,3,4,5],
           [5,4,3,2,1],
           [2,4,6,8,0],
           [1,3,5,7,9],
           [0,0,0,0,0]]
This defines and fills a two dimensional array, or what I call an array. (The actual values are irrelevant in this example).

By default this array is in RAM and can be written to as well as read from. I want to declare this to be a read-only array stored in the Flash rather than a read / write array stored in RAM.

What's the actual syntax used to make that distinction?

Re: Create read-only array in code memory, not RAM?

Posted: Mon Aug 20, 2018 11:36 pm
by jickster
OutoftheBOTS_ wrote:Mico Python has a const() fuction that does the same thing

see http://docs.micropython.org/en/latest/w ... ained.html
No it does not. I looked at that C implementation for the Python function `const` and it does absolutely nothing. Literally. It merely returns its input.

Create read-only array in code memory, not RAM?

Posted: Tue Aug 21, 2018 12:38 am
by jickster
Siriushardware wrote:Thank you, I read that, but I still don't get it. I think I must have a blind spot for Python because, try as I might, I can rarely find a simple defined example which shows exactly what I think I want to do when looking through Python related docs. That document shows how to declare a simple variable as a CONST but doesn't seem to give examples for more complex data structures.

Take an actual fragment of code:

Code: Select all

MyArray = [[1,2,3,4,5],
           [5,4,3,2,1],
           [2,4,6,8,0],
           [1,3,5,7,9],
           [0,0,0,0,0]]
This defines and fills a two dimensional array, or what I call an array. (The actual values are irrelevant in this example).

By default this array is in RAM and can be written to as well as read from. I want to declare this to be a read-only array stored in the Flash rather than a read / write array stored in RAM.

What's the actual syntax used to make that distinction?
You CANNOT put something in flash memory simply by using “const” qualifier like you can in C.

When C code is compiled, the resulting binary is meant to be executed on hardware which has the concept of readonly and readwrite memory.

When .py is compiled to bytecode, it’s meant to run on a “virtual” machine for which there is no notion of readonly vs readwrite memory.

With current state of micropython, If you want to put something in a .py in flash, you have to freeze the .py and build it as part of the firmware. This is very cumbersome and in some cases not viable. For example, if your system is deployed in the field and accepts an arbitrary .py file to execute from some user, you cannot just rebuild the firmware every time a new .py file is uploaded.

If you want to move an object from RAM to readonly memory from with a .py, it’s not hard but you have to know the underlying storage mechanism - flash vs OS-provided filesystem - and C-programming to implement it.

Honestly this sounds like a good thing to implement as part of micropython; I’ll create an issue.

https://github.com/micropython/micropython/issues/4067

Re: Create read-only array in code memory, not RAM?

Posted: Tue Aug 21, 2018 8:23 am
by pythoncoder
The const() keyword applies only to integers (or expressions which can evaluate to integers at compile time). It is a signal to the MicroPython compiler which replaces the symbol with a number. This saves time by eliminating a variable access. If the symbol begins with an underscore it also saves RAM. This prevents another module from importing the name so the compiler can skip allocating RAM for it.

At a 'C' level it does indeed return its contents. This allows code using the const keyword to run under CPython.

Storing data in read-only form is difficult. Python copies mutable objects into RAM (because they can be changed in code). So read-only objects must be immutable (bytes or str instances). Even then you have to apply attention to detail in your code to avoid inadvertent RAM use. As soon as you use methods like string join or format, copying to RAM takes place.

So, as far as I can see, lists or arrays can never be stored in read-only form in a way that actually saves RAM. It can be done, with care, using immutable objects and frozen bytecode. See this example with font files.

Re: Create read-only array in code memory, not RAM?

Posted: Tue Aug 21, 2018 7:40 pm
by jickster
pythoncoder wrote:
Tue Aug 21, 2018 8:23 am
Python copies mutable objects into RAM (because they can be changed in code). [/url].
Python copies ALL objects into RAM because when `.make_new` is called, memory is allocated from the heap.
If you create a tuple - which is immutable - it will still exist in RAM.

Re: Create read-only array in code memory, not RAM?

Posted: Tue Aug 21, 2018 8:00 pm
by Siriushardware
jickster wrote:
Tue Aug 21, 2018 12:38 am
You CANNOT put something in flash memory simply by using “const” qualifier like you can in C.
Although disappointing, that is essentially what I needed to know, for now. Thanks for taking the steps to suggest it to be implemented.

Re: Create read-only array in code memory, not RAM?

Posted: Tue Aug 21, 2018 10:19 pm
by jickster
Siriushardware wrote:
Tue Aug 21, 2018 8:00 pm
jickster wrote:
Tue Aug 21, 2018 12:38 am
You CANNOT put something in flash memory simply by using “const” qualifier like you can in C.
Although disappointing, that is essentially what I needed to know, for now. Thanks for taking the steps to suggest it to be implemented.
I would not expect this to ever be implemented.

I fleshed out what an implementation would require
https://github.com/micropython/micropython/issues/4067

Re: Create read-only array in code memory, not RAM?

Posted: Wed Aug 22, 2018 10:33 am
by pythoncoder
jickster wrote:
Tue Aug 21, 2018 7:40 pm
...Python copies ALL objects into RAM because when `.make_new` is called, memory is allocated from the heap.
If you create a tuple - which is immutable - it will still exist in RAM.
True, but you can prevent the copy to RAM using a memoryview, as per the frozen font example I cited above.