Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WiPy: interrupts not returning to main loop? #2406

Closed
dmartauz opened this issue Sep 9, 2016 · 15 comments
Closed

WiPy: interrupts not returning to main loop? #2406

dmartauz opened this issue Sep 9, 2016 · 15 comments
Labels
ports Relates to multiple ports, or a new/proposed port

Comments

@dmartauz
Copy link

dmartauz commented Sep 9, 2016

I would like to move following discussion from MP forum to GitHub, because in my opinion it is a major problem:
http://forum.micropython.org/viewtopic.php?f=11&p=13664#p13664

Based on my tests (build MicroPython v1.8.3-41-g253e1a6 on 2016-08-23) the issue is not only about loosing REPL but interrupts do not return to main loop ("e.g. printing some values with time delay indefinitely) started in main.py either.

When tested with MicroPython v1.8.1-65-gcbffd0a on 2016-06-18 interrupts return ok (but umqtt does not work - problem for my project).

@dpgeorge
Copy link
Member

dpgeorge commented Sep 9, 2016

The 2 main differences for WiPy between v1.8.1 and v1.8.3 are an upgraded FreeRTOS library, and addition of multithreading. Both of those things could impact the behaviour of IRQs.

Can you please post here a minimal example which fails on 1.8.3 and passes on 1.8.1?

@dmartauz
Copy link
Author

dmartauz commented Sep 9, 2016

Thanks for fast response. This is minimal main.py which I just tested with 1.8.1 and 1.8.3:

SW1 = machine.Pin('GP17', mode=machine.Pin.IN, pull=machine.Pin.PULL_UP)

def SW1callback(line):
    print("uSW USR1 pressed")
    return

SW1irq = SW1.irq(trigger=machine.Pin.IRQ_RISING, handler=SW1callback)

while True:
    print(time.time())
    time.sleep_ms(1000)

1.8.1 - output:

473385892
473385893
473385894
uSW USR1 pressed
uSW USR1 pressed
uSW USR1 pressed
473385895
473385896
473385897

1.8.3 - output:

473385624
473385625
473385626
uSW USR1 pressed
uSW USR1 pressed
uSW USR1 pressed

And it hangs here until I press the switch again.

Btw is multithreading documented somewhere?

@dpgeorge
Copy link
Member

dpgeorge commented Sep 9, 2016

Thanks, that definitely looks like a bug.

Btw is multithreading documented somewhere?

The _thread module is implemented almost fully on WiPy, as documented by CPython: https://docs.python.org/3/library/_thread.html

@dpgeorge
Copy link
Member

dpgeorge commented Sep 9, 2016

@dmartauz I don't have a WiPy to test against right now but I'm pretty sure that disabling threading will fix the problem. You can disable it by changing lines 105-106 of cc3200/mpconfigport.h to:

#define MICROPY_PY_THREAD                           (0)
#define MICROPY_PY_THREAD_GIL                       (0)

If this works for you then I'll temporarily disable threading on cc3200 until a proper fix is worked out.

@robert-hh
Copy link
Contributor

robert-hh commented Sep 10, 2016

I gave it a try. Using plain interrupt with version 1.8.1 just caused the REPL to disappear. Disabling threading made REPL stable, and the ISR was called, just the print statement in the ISR never showed anything. But a counter, which I used instead, was increased. Actual test code:

import machine
import time

count = 0

SW1 = machine.Pin('GP17', mode=machine.Pin.IN, pull=machine.Pin.PULL_UP)

def SW1callback(line):
    global count
    print("uSW USR1 pressed")
    count += 1
    return

SW1irq = SW1.irq(trigger=machine.Pin.IRQ_RISING, handler=SW1callback)

while True:
    print(time.time(), count)
    time.sleep_ms(1000)

Newly created MP version: MicroPython v1.8.4-30-g99b05f4-dirty on 2016-09-10; WiPy with CC3200

Update: The same version with threading enabled also ran stable. So maybe the issue went away with version 1.8.4.
B.T.W.: A single switch press caused count increases between 3 and 400; so much about bouncing.

@dmartauz
Copy link
Author

Damien, Robert, I am currently on holiday and I don't have WiPy with me. I will do the build and testing with and without threading disabled on Monday 19.9.

@jgmdavies
Copy link

All,
I still can't get simple timer irqs to work, even with 1.8.4 - please see http://forum.micropython.org/viewtopic.php?f=11&t=2127&p=13807#p13807
I'm wondering how we know which Timers 'should' work in this situation, i.e. perhaps Timer 1 is in use for the WiFi or the REPL or something else?
Thanks,
Jim

@robert-hh
Copy link
Contributor

robert-hh commented Sep 17, 2016

@dpgeorge: changing mpconfigport.h according to your suggestion seems to cure the problem for the moment. The test code timer4.py or jgmdavies runs for 35000 interrupts now. The impression, that it went away with 1.8.4 was wrong. Only sometimes it can take very long until the test stops. It seems to depend on the network activity.

@blueslow
Copy link

Interupts still not working MicroPython v1.8.5 on Wipy, it does return to main but hangs a short while after:

PYB: soft reboot
Platform WiPy
Phyton Version: 3.4.0,(3, 4, 0),
Fw version: 1.2.0
MicroPython v1.8.5-6-g5c93d0b on 2016-10-18; WiPy with CC3200
Type "help()" for more information.

dir()
['micropython', 'os', 'machine', 'UART', 'main', 'counter', 'WLAN', 'sys', 'pinInterrupt', 'name', 'uart']
main()
Initital value 1
Counter 0
Counter 0
Counter 0
Counter 0
Counter 0
Counter 0
Counter 1
Platform WiPy
Phyton Version: 3.4.0,(3, 4, 0),
Fw version: 1.2.0
MicroPython v1.8.5-6-g5c93d0b on 2016-10-18; WiPy with CC3200
Type "help()" for more information.

After main loop printed Counter 0 for the sixth time the GP23 signal is connected to gnd via a button. The interupt routine pinInterrupt is called at least once (No debouncing on button) and counter is increased. This fact is shown on the seventh Counter print out from main. Then the rst button is pressed and it return to REPL. Ctrl-C will not abort the running code. Some times it works but on later press of GP23 button it hangs.

boot.py is empty apart from a comment.
This is the code in main.py:

`# main.py -- put your code here!
from machine import UART
from network import WLAN
import sys
import os
import machine
import micropython

uart = UART(0, baudrate=115200)
os.dupterm(uart)

micropython.alloc_emergency_exception_buf(100)
counter = 0

def pinInterrupt(pin):
global counter
counter += 1

def main():

m1UpButton=machine.Pin('GP30', mode=machine.Pin.IN, 
                        pull=machine.Pin.PULL_UP)
print("Initital value %d" % m1UpButton.value())
m1UpButton.irq(trigger=machine.Pin.IRQ_FALLING, handler=pinInterrupt)

while True:
    s=machine.disable_irq()
    cnt = counter
    machine.enable_irq(s)
    print("Counter %d" % cnt)
    for i in range(20000):
        pass

m1UpButton.irq().disable()
print("Exit") 

`

I have also tested,

robert-hh commented on 10 Sep • edited

code above it does not return to main loop, allthough interrupt continue to work, but pressing ctrl.c does not make it return to REPL. Here is a short print out:
473385652 0
473385653 0
473385654 0
uSW USR1 pressed
uSW USR1 pressed
uSW USR1 pressed
uSW USR1 pressed
uSW USR1 pressed
uSW USR1 pressed

Consequently the error is not corrected in V1.8.5

/Blueslow

@robert-hh
Copy link
Contributor

Did you disable threading in mpconfigport.h as suggested by Damien?

#define MICROPY_PY_THREAD (0)
#define MICROPY_PY_THREAD_GIL (0)

@blueslow
Copy link

blueslow commented Oct 18, 2016

No I did not. I saw the note about it but forgot to mention it. I used the pre built release as is from http://micropython.org/download. I have not the right tool chain installed and I have not looked in to the details of building the firmware for micropython running on the wipy. Any tips on how to install the tools chain for ARM under linux?

dpgeorge added a commit that referenced this issue Oct 19, 2016
Running Python code on a hard interrupt is incompatible with having a GIL,
because most of the time the GIL will be held by the user thread when the
interrupt arrives.  Hard interrupts mean that we should process them right
away and hence can't wait until the GIL is released.

The problem with the current code is that a hard interrupt will try to
exit/enter the GIL while it is still held by the user thread, hence leading
to a deadlock.

This patch works around such a problem by just making GIL exit/enter a
no-op when in an interrupt context, or when interrupts are disabled.

See issue #2406.
@dpgeorge
Copy link
Member

This issue should now be fixed by 17ba6ef. Please test and report back if it's working for you, thanks!

@blueslow
Copy link

Hi,

Conclusion it works, at least in the short term. Good work Damien, thanks.

This is how I tested:
I downloaded zip from
http://micropython.org/resources/firmware/wipy-20161019-v1.8.5-18-g84679e0.zip
extracted it and copied mcuimg.bin to /flash/sys/ with ftp and made a
hard reset.

I have executed my script stated in 2406
#2406 and also
Robert-hh's scripts during 10 minutes each. Both scripts now seems to
work. Both scripts can also be interrupted by ctrl-c. FTP and telnet
connections works even during executing Robert-hh script (have not
tested it with my script). FTP and telnet connections also works after
the scripts been interrupted by ctrl-c.I have also built and downloaded
the mcuimg.bin from the git repository and the scripts works equally well.

Another problem:
This is regardless of any scripts running.
However the FTP stops working after password is sent by the client,
after connection is established when i build it my self. FTP client
eventually times out, but the WIPY hangs and the heartbeat led goes off
and remains so. until reset switch is pressed or wipy power cycled. This
has also been observed in a previous build (1.8.5-11) which I made and
has noting to do with 2406.
#2406 More likely
something is wrong with my tool chain or me doing the wrong things when
building.

/Klas

Den 2016-10-19 kl. 05:33, skrev Damien George:

This issue should now be fixed by 17ba6ef
17ba6ef.
Please test and report back if it's working for you, thanks!


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#2406 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AKjiRpgOJXwwXr5iAGd8xIJ-tprOCndMks5q1Y9-gaJpZM4J42xC.

@robert-hh
Copy link
Contributor

I cannot confirm the build issue. I updated to the latest state (git pull), rebuilt the image, downloaded it to WIpy. FTP still runs. Which client & which OS are you using?

@blueslow
Copy link

blueslow commented Oct 19, 2016

Robert-hh, my ftp issue is a completely different problem of what is discussed in this thread so people may regard this as offtopic.
Robert-hh the build issue is in my setup not in the repository that I guess dpgeorge built (http://micropython.org/resources/firmware/wipy-20161019-v1.8.5-18-g84679e0.zip), which I used to confirm the corrections. I'm using Linux mint 18 with filezilla. and that works unless I'm building the cc3200 mcuimg.bin by myself with the command make BTARGET=application BTYPE=release BOARD=WIPY. That problem was also in the V1.8.5-11, one strange thing allthough with that build was that it worked initially but stopped working after I downloaded a couple of files and executed some scripts but after that it does not work. So the problem is eithher in my toolchain, my command that build the mcuimg or in the Wipy itself. What I would like to have are means to instrument the FTP code with safe printouts to try to determine were it goes astray. The toolchian that I'm using is the downloaded from the following source: https://launchpad.net/~team-gcc-arm-embedded/+archive/ubuntu/ppa

@pfalcon pfalcon added ports Relates to multiple ports, or a new/proposed port and removed ports Relates to multiple ports, or a new/proposed port labels Oct 22, 2016
dmanso pushed a commit to dmanso/micropython that referenced this issue Oct 30, 2016
Running Python code on a hard interrupt is incompatible with having a GIL,
because most of the time the GIL will be held by the user thread when the
interrupt arrives.  Hard interrupts mean that we should process them right
away and hence can't wait until the GIL is released.

The problem with the current code is that a hard interrupt will try to
exit/enter the GIL while it is still held by the user thread, hence leading
to a deadlock.

This patch works around such a problem by just making GIL exit/enter a
no-op when in an interrupt context, or when interrupts are disabled.

See issue micropython#2406.
tannewt pushed a commit to tannewt/circuitpython that referenced this issue Dec 20, 2019
Improve USB eject by resetting on replug
@projectgus projectgus closed this as not planned Won't fix, can't repro, duplicate, stale Aug 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ports Relates to multiple ports, or a new/proposed port
Projects
None yet
Development

No branches or pull requests

7 participants