Issue with pin interrupt?
-
I have an app which reads values from adxl362 and saves theme to the sd card. In order to know when to fetch data from the fifo in the adxl362 I am using pin interrupts. This interrupt triggers approximatly 3 times a second.
Additionally I have two slow timers and an other pininterrupt running.
The app fails approximatly all 60 second with the following guru mediation error:
Guru Meditation Error of type LoadProhibited occurred on core 0. Exception was unhandled. Register dump: PC : 0x400eb244 PS : 0x00060230 A0 : 0x800eb298 A1 : 0x3ffe1f50 0x400eb244: mp_call_function_n_kw at pycom-micropython-sigfox/esp32/../py/runtime.c:562 A2 : 0x3ffe4560 A3 : 0x00000001 A4 : 0x00000000 A5 : 0x3ffe1f70 A6 : 0x00050223 A7 : 0x00000000 A8 : 0x800eb244 A9 : 0x3ffe1f30 A10 : 0x00000001 A11 : 0x00060223 A12 : 0x00060220 A13 : 0x3ffc5b20 A14 : 0x00000003 A15 : 0x00060223 SAR : 0x0000001a EXCCAUSE: 0x0000001c EXCVADDR: 0x00000011 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xfffffffe Backtrace: 0x400eb244:0x3ffe1f50 0x400eb298:0x3ffe1f70 0x400dcca8:0x3ffe1fa0 0x400e1656:0x3ffe1fc0 0x400d8234:0x3ffe2050 0x400eb244: mp_call_function_n_kw at pycom-micropython-sigfox/esp32/../py/runtime.c:562 0x400eb298: mp_call_function_1 at pycom-micropython-sigfox/esp32/../py/runtime.c:562 0x400dcca8: pin_interrupt_queue_handler at pycom-micropython-sigfox/esp32/mods/machpin.c:300 0x400e1656: TASK_Interrupts at pycom-micropython-sigfox/esp32/util/mpirq.c:58 0x400d8234: freertos_entry at pycom-micropython-sigfox/esp32/mpthreadport.c:129
In the background the ftp server is running. By clicking update in an ftp app I can force the error to trigger much faster ...
Any ides? Am I doing something wrong or is this a bug?
-
@danielm said in Issue with pin interrupt?:
Did referencing of the handler help to prevent those issues?
Actually I don't remember the outcome of this test. But it must have been unsatisfying.
Anyway, just found the following commit in github:
Looks like this is exactly about the issue I ecountered. Going to compile this myself and test...
-
@this-wiederkehr
Did referencing of the handler help to prevent those issues?
-
Just to clarify: I checked with pure micropython unix port and it has the same behavior with id(inst.method).
Thinking about it in detail this behavior makes sense. The reason I think is, that its infeasible to hold a reference to each method of each instance in memory (there are possibly thousands of instances). And an instance method is pretty simple just the class method with
self
set.In cpython they may have solved this with weakrefs but as long as I know micropython does not have weakrefs.
Anyway, the reason I did look into this is: I suspected that my interrupt handler (which is an instance method) is collected by the gc. The error will not be triggered immediately after the gc run, but only when that specific memory region where the instance.method was located before gets rewritten...
????I'll try to hold a reference to the handler by assigning it to an instance variable (this should prevent it from being collected by the gc.
def __init__(self): self.callback = self.handler int_pin.callback(trigger=Pin.IRQ_RISING, handler=self.callback) def handler(self): # do whatever has to be done =)
-
@daniel
Could you please provide a comment for the post above?
-
Might be totally unrelated but I see:
id(module)
stays constant on multiple callsid(module.Class)
stays constant on multiple calls
id(module.Class.method)
stays constant on multiple callsinst = module.Class()
id(inst)
stays constant on multiple callsbut
id(inst.method)
changes continuously on each call (increasing)Looks like inst.method is allocated each time we call it. Why is that? Is this the expected behavior?
interestingly you can easily run out of memory:
gc.disable() while True: id(inst.method)
while on all other calls you will never run out of memory...
Just checked with cpython. Doing the above will result in two different ids but you can not exhaust memory like above.
This is all found on 1.6.12.b1
Just wonder if this causes problems
-
@danielm: I also read your post. Indeed, it looks similar.
It looks like something is messed with the pointers to python objects... That would also explain the strange exception in the callback. Due to some reason it finds a slice although there should not be a slice.
may be due to the gc reallocating stuff or some error in the thread sync??? Honestly I have no clue ...
When I have time I'll try to run gc and interrupt exclusively and see whether the error persists: basically disabling gc in the main loop and only collect if interrupts are disabled...
-
It seems that you are having similar issues: https://forum.pycom.io/topic/935/unhandled-exception-in-interrupt-handler
It runs more stable with recent FW versions (tested with 1.6.12.b1) but it crashes anyway.
-
@robert-hh sorry, forgot to mention.
it's a lopy and I rebuilt everything from the sources checkedout yesterday:
https://github.com/pycom/pycom-micropython-sigfox
https://github.com/pycom/pycom-esp-idfSo, it should be identical to:
(sysname='LoPy', nodename='LoPy', release='1.6.12.b1', version='v1.8.6-593-g8e4ed0fa on 2017-04-12', machine='LoPy with ESP32', lorawan='1.0.0')But I don't have access to it to check right now.
-
@this.wiederkehr Which version of the firmware are you using? It's always helpful to add the the response from:
import uos uos.uname()
-
Sometimes I also get the following error:
Guru Meditation Error of type LoadProhibited occurred on core 0. Exception was unhandled. Register dump: PC : 0x4019abec PS : 0x0006063f A0 : 0x800f72a9 A1 : 0x3ffc5a90 0x4019abec: mp_decode_uint at pycom-micropython-sigfox/esp32/../py/bc.c:50 (discriminator 1) A2 : 0x3ffc5afc A3 : 0x3f409d60 A4 : 0x3f40b6b8 A5 : 0x3f40b6b8 A6 : 0x00000000 A7 : 0x40000000 A8 : 0x0023bccf A9 : 0x00000000 A10 : 0x0023bcd0 A11 : 0x00000019 A12 : 0x3f4078f8 A13 : 0x0000e79e A14 : 0x3f4078f8 A15 : 0x00000000 SAR : 0x0000001a EXCCAUSE: 0x0000001c EXCVADDR: 0x0023bccf LBEG : 0x400e3da4 LEND : 0x400e3dd0 LCOUNT : 0x00000eb3 0x400e3da4: gc_realloc at pycom-micropython-sigfox/esp32/../py/gc.c:668 0x400e3dd0: gc_realloc at pycom-micropython-sigfox/esp32/../py/gc.c:685 Backtrace: 0x4019abec:0x3ffc5a90 0x400f72a9:0x3ffc5ab0 0x400eed03:0x3ffc5b50 0x400eb254:0x3ffc5b90 0x400eb2bc:0x3ffc5bb0 0x400f6e30:0x3ffc5bd0 0x400eed03:0x3ffc5c70 0x400eb254:0x3ffc5cb0 0x400eb281:0x3ffc5cd0 0x400d8c92:0x3ffc5cf0 0x400d8f61:0x3ffc5d90 0x400d7f8c:0x3ffc5db0 0x4019abec: mp_decode_uint at pycom-micropython-sigfox/esp32/../py/bc.c:50 (discriminator 1) 0x400f72a9: mp_execute_bytecode atpycom-micropython-sigfox/esp32/../py/vm.c:1309 0x400eed03: fun_bc_call at pycom-micropython-sigfox/esp32/../py/objfun.c:276 0x400eb254: mp_call_function_n_kw at pycom-micropython-sigfox/esp32/../py/runtime.c:562 0x400eb2bc: mp_call_method_n_kw at pycom-micropython-sigfox/esp32/../py/runtime.c:591 0x400f6e30: mp_execute_bytecode at pycom-micropython-sigfox/esp32/../py/vm.c:980 0x400eed03: fun_bc_call at pycom-micropython-sigfox/esp32/../py/objfun.c:276 0x400eb254: mp_call_function_n_kw atpycom-micropython-sigfox/esp32/../py/runtime.c:562 0x400eb281: mp_call_function_0 at pycom-micropython-sigfox/esp32/../py/runtime.c:562 0x400d8c92: parse_compile_execute at pycom-micropython-sigfox/esp32/../lib/utils/pyexec.c:534 0x400d8f61: pyexec_file at pycom-micropython-sigfox/esp32/../lib/utils/pyexec.c:505 0x400d7f8c: TASK_Micropython at pycom-micropython-sigfox/esp32/mptask.c:243
or this one here:
Guru Meditation Error of type LoadStoreAlignment occurred on core 0. Exception was unhandled. Register dump: PC : 0x400ec3d9 PS : 0x0006003f A0 : 0x800eb04d A1 : 0x3ffc5b60 0x400ec3d9: mp_map_lookup at pycom-micropython-sigfox/esp32/../py/map.c:152 A2 : 0x40370027 A3 : 0x000002ae A4 : 0x00000000 A5 : 0x3ffe4040 A6 : 0x40370027 A7 : 0x3ffc69bc A8 : 0x800d82f4 A9 : 0x3ffc5b50 A10 : 0x3ffc66bc A11 : 0x00000019 A12 : 0x0006002f A13 : 0x3ffe3da0 A14 : 0x00000378 A15 : 0x00000000 SAR : 0x00000002 EXCCAUSE: 0x00000009 EXCVADDR: 0x40370027 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0x00000000 Backtrace: 0x400ec3d9:0x3ffc5b60 0x400eb04d:0x3ffc5b90 0x400eb0b4:0x3ffc5bb0 0x400f6356:0x3ffc5bd0 0x400eed03:0x3ffc5c70 0x400eb254:0x3ffc5cb0 0x400eb281:0x3ffc5cd0 0x400d8c92:0x3ffc5cf0 0x400d8f61:0x3ffc5d90 0x400d7f8c:0x3ffc5db0 0x400ec3d9: mp_map_lookup at pycom-micropython-sigfox/esp32/../py/map.c:152 0x400eb04d: mp_load_global at pycom-micropython-sigfox/esp32/../py/runtime.c:562 0x400eb0b4: mp_load_name at pycom-micropython-sigfox/esp32/../py/runtime.c:562 0x400f6356: mp_execute_bytecode at pycom-micropython-sigfox/esp32/../py/vm.c:278 0x400eed03: fun_bc_call at pycom-micropython-sigfox/esp32/../py/objfun.c:276 0x400eb254: mp_call_function_n_kw at pycom-micropython-sigfox/esp32/../py/runtime.c:562 0x400eb281: mp_call_function_0 at pycom-micropython-sigfox/esp32/../py/runtime.c:562 0x400d8c92: parse_compile_execute at pycom-micropython-sigfox/esp32/../lib/utils/pyexec.c:534 0x400d8f61: pyexec_file at pycom-micropython-sigfox/esp32/../lib/utils/pyexec.c:505 0x400d7f8c: TASK_Micropython at pycom-micropython-sigfox/esp32/mptask.c:243
-
Ah yea, my callback functions are very easy instance methods which just do:
self.todo = 1
In the main loop i check for these flags and reset theme. at the end of the loop i call
machine.idle()
Interestingly, if I disable all the other callbacks except for the one related to the adxl362 I get:
Unhandled exception in callback handler TypeError: 'slice' object is not callable
Even tough there is no slice object in the callback involved.
After that the program freezes. No further interrupts.
I'm not runnin out of memory: In the main loop I call gc.collect whenever there is less than 10000bytes available. At that point it goes up to around 50000 bytes.