Open elbert-wong opened 2 years ago
@elbert-wong - I'm not able to repro on the latest dev branch. I'm seeing the timing below without commenting out any code (I'm using a Pico):
This is to code I'm using:
package main
import (
"machine"
"runtime"
"time"
)
const (
pinIn = machine.GPIO13
pinOut = machine.GPIO15
pinLED = machine.LED
)
var timeout = make(chan bool, 1)
var tstChan = make(chan bool, 1)
func pinConfig() {
pinIn.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
pinLED.Configure(machine.PinConfig{Mode: machine.PinOutput})
pinOut.Configure(machine.PinConfig{Mode: machine.PinOutput})
}
func main() {
pinConfig()
go func() {
time.Sleep(10000 * time.Millisecond)
timeout <- true
}()
pinIn.SetInterrupt(machine.PinFalling, pinFallHandler)
select {
case <-tstChan:
case <-timeout:
}
pinIn.SetInterrupt(machine.PinFalling, nil)
pinOut.High()
time.Sleep(100 * time.Millisecond)
pinOut.Low()
time.Sleep(300 * time.Millisecond)
pinOut.High()
for {
runtime.Gosched()
}
}
func pinFallHandler(pin machine.Pin) {
tstChan <- true
}
@kenbell Thank you for your prompt reply! Could you confirm that the light sleep is enabled in your dev code? (which is also included in release 0.24.0) If I disable the light sleep, the following sleep in main loop works well. But in that case, the select code is blocked for a very long time, if a new ext interrupt triggers again during this block time, we will get a panic (writing a full channel in interrupt).
my issue was found on 0.22.0(with light sleep merged) and also 0.24.0
I have build a dev branch (tinygo version 0.25.0-dev linux/amd64 (using go version go1.18.3 and LLVM version 14.0.6) with outside llvm-14 this morning, still no lucky. But I am not sure whether I am using the tinygo in dev correctly. I just run it as below:
Seems like I fixed this issue by correcting the sleep duration in addSleepTask. But I have no idea why this code works if light-sleep is not enabled. Probably without light-sleep the "select" code block does not run before any sleeping go-routine wakes up. The interrupt event doesn't wake up the main loop, although who is waiting for the channel reading. The scheduler is in busy loop when ext interrupt fires.
In a channel select with timeout, if the select hit the non-timeout branch, we got incorrect sleep time in the following code.
we got correct sleep time if we: comment out the timer go-routine OR comment out the timeout branch in select
Note: to handle the pin edge interrupt, the #2847 code is merged, the issue is reported as #2877
pinOut signal: