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

esp8266: put pin interrupt handler in iRAM #5962

Merged
merged 4 commits into from May 2, 2020

Conversation

dpgeorge
Copy link
Member

@dpgeorge dpgeorge commented Apr 23, 2020

Attempt to fix #5714

@dpgeorge
Copy link
Member Author

@peterhinch if you could test this, that would be great.

@peterhinch
Copy link
Contributor

OK, I now have a test running but it needs to run for a while as the fault was infrequent.

You managed to replicate my original report here so maybe that would be worth repeating?

@peterhinch
Copy link
Contributor

This has now run for over two hours - I'm confident this has fixed it. Previously I doubt it ever ran for more than 15 minutes (without pinging).

This also confirms my belief that the I2C issues were a consequence of the ISR not running - this was breaking the protocol causing the Pyboard I2C slave to fail.

@peterhinch
Copy link
Contributor

I have also run your test. I reduced the PWM frequency to 50Hz (10ms interrupt interval) as I thought 1ms rather ambitious for soft IRQ's. This has run for 30 minutes without error.

On occasion it reconnected to the LAN but the code continued to run:

165577
165677
state: 5 -> 2 (6c0)
rm 0
pm close 7
165777
reconnect
state: 2 -> 0 (0)
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 4
cnt 
165877

connected with misspiggy, channel 3
dhcp client start...
165979
ip:192.168.0.18,mask:255.255.255.0,gw:192.168.0.1
166079
166179

Code:

from machine import Pin, PWM
from time import sleep
import gc

pin = Pin(13, Pin.IN)
count = 0
def cb_pin(_):
    global count
    count += 1

ei = pin.irq(handler = cb_pin, trigger = (Pin.IRQ_FALLING | Pin.IRQ_RISING))
PWM(machine.Pin(2), freq=50, duty=50)
while True:
    sleep(1)
    print(count)
    gc.collect()

@dpgeorge
Copy link
Member Author

You managed to replicate my original report here so maybe that would be worth repeating?

That was actually something subtly different: it didn't lead to a crash, rather it hung the Python code but the "OS" was still running.

This has now run for over two hours - I'm confident this has fixed it.

Ok, that's really great news! But let's wait a bit to merge this in case something else comes up.

@dpgeorge
Copy link
Member Author

I cleaned this up a bit and removed support for hard=True in the Pin.irq() method (because it's no longer possible for this to work). Setting that option will now raise a ValueError.

So ports can put it in a special memory section if needed.
GPIO interrupts can occur when the flash ROM cache is in use and so the
GPIO interrupt handler must be in iRAM.  This commit moves the handler to
iRAM, and also moves mp_sched_schedule to iRAM which is called by
pin_intr_handler.

As part of this fix the Pin class can no longer support hard=True in the
Pin.irq() method, because the VM and runtime are too big to put in iRAM.

Fixes micropython#5714.
These are needed to ensure correct operation of the MicroPython scheduler.
@dpgeorge
Copy link
Member Author

Added a small note to the docs that the hard argument may not be supported on certain ports.

@dpgeorge dpgeorge merged commit 391927c into micropython:master May 2, 2020
@dpgeorge dpgeorge deleted the esp8266-pin-intr-iram branch May 2, 2020 04:33
tannewt pushed a commit to tannewt/circuitpython that referenced this pull request Feb 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ESP8266 Pin IRQ regression
2 participants