Preallocating ram

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
droidwarrior
Posts: 4
Joined: Mon Aug 07, 2017 6:11 pm

Preallocating ram

Post by droidwarrior » Sun Oct 15, 2017 2:54 am

Hi all,

Having lot of trouble understanding how to preallocate ram for ISR routines no using classes.
Please someone enlight me.


Regards,

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Preallocating ram

Post by Roberthh » Sun Oct 15, 2017 6:57 am

You can preallocate a buffer outside the ISR and declare it that global, like this example below with a circular buffer:

Code: Select all

BUFFERSIZE = const(128)
_data = bytearray(BUFFERSIZE)
_index_put = 0
_index_get = 0

def my_isr(pin):
    global _data, _index_put
    .....
    _data[_index_put] = whatever_you captured_in_the_ISR
    _index_put = (_index_put + 1) % BUFFERSIZE
_data, being global, is also accessible outside the ISR. If you put that in a separate file and maybe also define a function for retrieving values from it, using it looks like using a class.
Last edited by Roberthh on Mon Oct 16, 2017 5:18 am, edited 1 time in total.

droidwarrior
Posts: 4
Joined: Mon Aug 07, 2017 6:11 pm

Re: Preallocating ram

Post by droidwarrior » Sun Oct 15, 2017 8:36 pm

Hi, thanks for your reply.

BUFFERSIZE = const(128)
_data = bytearray(BUFFERSIZE)

* You declared a bytearray to make the variable mutable and to make it contiguos and reuse the same ram positions everytime you write?


def my_isr(pin):
global _data, _index_put

* For what i see, for use the bytearray declared top, one has to include it as a global in every function whether they are ISR o regular code functions. Right?


Regards,

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Preallocating ram

Post by Roberthh » Mon Oct 16, 2017 5:17 am

A regular function within the same module does not have to declare _data as global, because when it's not local, the global name space will be searched for. But it does not hurt to declare it global. An ISR has no known global name space, therefore _data (and other global symbols) must be declared as global. This is just a simple circular buffer example with a global buffer and a variable. The buffer has not to be static, just the name you use as the handle must be static. As far as I recall, the ISR mechanism has changed, at least for the ESP series, in that the actual interrupt just registers your ISR function to be scheduled as soon as possible as regular Python function. These scheduled Pseudo-ISR ares different in that they can allocate memory if needed. This is much more convenient when writing code, since also intrinsic memory allocation is needed, e.g. for floating point operations. On the downside, this mechanism increases the interrupt latency.

There is an optimisation for pointing the ISR to _data, by supplying it as a function argument (thanks to Damien for the hint), like:

Code: Select all

BUFFERSIZE = const(128)
_data = bytearray(BUFFERSIZE)
_index_put = 0
_index_get = 0

def my_isr(pin, data = _data):
    global _index_put
    .....
    data[_index_put] = whatever_you captured_in_the_ISR
    _index_put = (_index_put + 1) % BUFFERSIZE
Doing that the local symbol data is linked to the global symbol _data already at compile time. That works for _data, but not for _index_put.

P.S.: In my first submit there was a typo. Within the ISR it must be written _data[] = ... . The _ letter was missing. Fixed.

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

Re: Preallocating ram

Post by pythoncoder » Mon Oct 16, 2017 7:11 am

Roberthh wrote:
Mon Oct 16, 2017 5:17 am
...As far as I recall, the ISR mechanism has changed, at least for the ESP series, in that the actual interrupt just registers your ISR function to be scheduled as soon as possible as regular Python function....
As I understand it ESP8266 interrupts are still hard interrupts (like the Pyboard).

@droidwarrior The latency of the ESP8266 is much higher than the Pyboard (on the order of 600μs max) because of the underlying RTOS, but the handlers are still subject to the same rules. Soft interrupts are handled by machine.schedule: see the recently revised http://docs.micropython.org/en/latest/p ... rules.html. The latency of soft IRQ's is higher still (on the order of single digits of ms) because they will not be scheduled when a garbage collection is in progress.
Peter Hinch
Index to my micropython libraries.

Post Reply