Losing the REPL when an IRQ is triggered
- Frédéric Boulanger
- Posts: 4
- Joined: Mon Jun 08, 2015 9:05 pm
- Location: Gif-sur-Yvette, France
- Contact:
Losing the REPL when an IRQ is triggered
I have a WiPy with an extension board with an LED on pin GP16 and a push button on pin GP17.
I use the following code:
from machine import Pin
led=Pin('GP16', Pin.OUT)
btn=Pin('GP17', Pin.IN, Pin.PULL_UP)
def btnhandler(pin):
global led
led.toggle()
btn.irq(trigger=Pin.IRQ_FALLING, handler=btnhandler)
When I press the button, the LED toggles, however, I loose the REPL. I cannot type anything, and Ctrl-C or Ctrl-D have no effect. The WiPy does no longer answer telnet or ftp connections either.
I configured the WiPy to duplicate the REPL on the USB connection, so I tried without duplicating the REPL, but I get the same result: the WiPy continues to execute my code, but it is deaf and dumb...
Can anyone replicate this on a WiPy?
I use the following code:
from machine import Pin
led=Pin('GP16', Pin.OUT)
btn=Pin('GP17', Pin.IN, Pin.PULL_UP)
def btnhandler(pin):
global led
led.toggle()
btn.irq(trigger=Pin.IRQ_FALLING, handler=btnhandler)
When I press the button, the LED toggles, however, I loose the REPL. I cannot type anything, and Ctrl-C or Ctrl-D have no effect. The WiPy does no longer answer telnet or ftp connections either.
I configured the WiPy to duplicate the REPL on the USB connection, so I tried without duplicating the REPL, but I get the same result: the WiPy continues to execute my code, but it is deaf and dumb...
Can anyone replicate this on a WiPy?
- danicampora
- Posts: 342
- Joined: Tue Sep 30, 2014 7:20 am
- Contact:
- Frédéric Boulanger
- Posts: 4
- Joined: Mon Jun 08, 2015 9:05 pm
- Location: Gif-sur-Yvette, France
- Contact:
Re: Losing the REPL when an IRQ is triggered
>>> import os
>>> os.uname()
(sysname='WiPy', nodename='WiPy', release='1.2.0', version='v1.8.2-12-gad9b9c7 on 2016-07-14', machine='WiPy with CC3200')
>>>
>>> os.uname()
(sysname='WiPy', nodename='WiPy', release='1.2.0', version='v1.8.2-12-gad9b9c7 on 2016-07-14', machine='WiPy with CC3200')
>>>
Re: Losing the REPL when an IRQ is triggered
Hi Dany,Frédéric,Frédéric Boulanger wrote:>>> import os
>>> os.uname()
(sysname='WiPy', nodename='WiPy', release='1.2.0', version='v1.8.2-12-gad9b9c7 on 2016-07-14', machine='WiPy with CC3200')
>>>
The same for me, in my case all blocks when I my cc3200 launchpad hits any interrupt and runs the callback
Re: Losing the REPL when an IRQ is triggered
This one's gone a bit quiet. To anyone having this problem, try just adding a 'return' statement after the led.toggle line.
Jim
Jim
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Losing the REPL when an IRQ is triggered
@jgmdavies If you guys confirm that the return statement makes a difference I would argue it's a bug in the WiPy implementation which should be raised as an issue on Github.
Python never requires a return statement: functions return None by default. The Pyboard doesn't require one in interrupt callbacks - see the example code in the tutorial http://docs.micropython.org/en/latest/p ... witch.html.
Python never requires a return statement: functions return None by default. The Pyboard doesn't require one in interrupt callbacks - see the example code in the tutorial http://docs.micropython.org/en/latest/p ... witch.html.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Losing the REPL when an IRQ is triggered
@pythoncoder You're right of course - apologies. I retraced my steps and it's now working fine here, with or without a superfluous 'return' statement. (I personally prefer to include a 'return' as I think it makes the program structure clearer.)
Re: Losing the REPL when an IRQ is triggered
This is very interesting. I arrived at this thread about to post my simple non-functioning IRQ example. Before doing so I thought I had better test it with a return at the end of the handler and lo, it now magically works.
I certainly agree that REQUIRING a return is non-Pythonic, but I hope the documentation can be amended until this is fixed, as this evidence suggests the return statement is apparently still a requirement for interrupt callbacks. In the meantime, at least I can now get on with development after four days of part-time puzzling over this. Thanks!
I certainly agree that REQUIRING a return is non-Pythonic, but I hope the documentation can be amended until this is fixed, as this evidence suggests the return statement is apparently still a requirement for interrupt callbacks. In the meantime, at least I can now get on with development after four days of part-time puzzling over this. Thanks!
Re: Losing the REPL when an IRQ is triggered
Oh dear, I spoke too soon. So here's my problem. I'm just trying to learn how to correctly handle interrupts on the WiPy, but they don't seem to interact well with the REPL. Here's the code of the module (test1.py) I am importing.
import micropython
from machine import Timer
micropython.alloc_emergency_exception_buf(100)
index = 0
def cb(t):
global index
index += 1
return
tim4 = Timer(1, mode=Timer.PERIODIC, width=16)
chan = tim4.channel(Timer.A, freq=10)
chan.irq(trigger=Timer.TIMEOUT, handler=cb)
You will notice this includes the return statement, but it shouldn't be (and probably isn't) required.
After importing, I can use the REPL to examine test1.index and I see it going up nicely. Sadly, after a while (< 1 minute) the REPL just locks up completely (I'm accessing it over a UART.
I'm fairly sure my setup is reasonably up to date:
>>> os.uname()
(sysname='WiPy', nodename='WiPy', release='1.2.0', version='v1.8.2-94-g3d19adf on 2016-08-06', machine='WiPy with CC3200')
If anyone has a clue what's going wrong I'd be glad to hear it. I suspect it might be something to with having to create new integers, and plan to test this theory by just setting the index to a constant value. But I'm stabbing in the dark here, so advice from those more experienced would be helpful.
import micropython
from machine import Timer
micropython.alloc_emergency_exception_buf(100)
index = 0
def cb(t):
global index
index += 1
return
tim4 = Timer(1, mode=Timer.PERIODIC, width=16)
chan = tim4.channel(Timer.A, freq=10)
chan.irq(trigger=Timer.TIMEOUT, handler=cb)
You will notice this includes the return statement, but it shouldn't be (and probably isn't) required.
After importing, I can use the REPL to examine test1.index and I see it going up nicely. Sadly, after a while (< 1 minute) the REPL just locks up completely (I'm accessing it over a UART.
I'm fairly sure my setup is reasonably up to date:
>>> os.uname()
(sysname='WiPy', nodename='WiPy', release='1.2.0', version='v1.8.2-94-g3d19adf on 2016-08-06', machine='WiPy with CC3200')
If anyone has a clue what's going wrong I'd be glad to hear it. I suspect it might be something to with having to create new integers, and plan to test this theory by just setting the index to a constant value. But I'm stabbing in the dark here, so advice from those more experienced would be helpful.
Re: Losing the REPL when an IRQ is triggered
in MicroPython there are 2 types of integers. The first kind are called small ints and are a 31-bit signed integer. These require no memory allocation to use. The second are arbitrary precision integers which require memory allocation.
The largest 31-bit signed small int is 0x3fffffff and if you add 1 to that you get 0x4000000 which requires an mpz int (i.e. a memory allocation).
However, given your example, (incrementing at 10 Hz) it would take just over 3 years to overflow.
The largest 31-bit signed small int is 0x3fffffff and if you add 1 to that you get 0x4000000 which requires an mpz int (i.e. a memory allocation).
However, given your example, (incrementing at 10 Hz) it would take just over 3 years to overflow.