rp2: Crash with hard pin IRQ
Measuring hard IRQ latency with this script:
from machine import Pin, PWM
from time import sleep_ms
import math
# Link 16-17, time 16-18
pin18 = Pin(18, Pin.OUT)
def callback(_):
pin18(1) # Trigger
pin18(0)
pin17 = Pin(17, Pin.IN)
_ = pin17.irq(callback, trigger=Pin.IRQ_RISING, hard=True)
pwm = PWM(Pin(16))
pwm.freq(1000)
pwm.duty_u16(0xffff // 2)
while True:
y = 0
for x in range(100):
y += math.sin(x * 2 * math.pi/100) # 6.2ms of busywork
sleep_ms(10)
The usual latency was a creditable 25μs, but I have measured 100μs. It was not practicable to measure a worst case because the the machine suffers a hard crash usually almost immediately. If I comment out the busywork, leaving just the sleep_ms(10), it runs indefinitely with about 20μs latency.
ESP8266 Pin IRQ regression
This device driver for IR remotes formerly worked on ESP8266. It now crashes with no changes to code. The problem is related to hard Pin IRQ's and the following code sample demonstrates it.
from machine import Pin
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), hard = True)
# ei = pin.irq(handler = cb_pin, trigger = Pin.IRQ_FALLING, hard = True)
while True:
sleep(1)
print(count)
gc.collect()
To test the pin is fed with a burst of 14 pulses of Manchester encoded data repeating every 104ms. Pulses are 889μs or 1778μs wide, the burst lasting 24.9ms. A crash with reboot occurs usually within a few seconds.
A crash also occurs if the commented-out code is used, ensuring that the minimum time between triggers is a leisurely 1.8ms. The crash takes longer to trigger.
Testing was with firmware built from source acquired today.
[EDIT]
I simplified the test by feeding the pin with a 20Hz square wave. The crash occurs after counting about 200 edges.