circuits_gpio icon indicating copy to clipboard operation
circuits_gpio copied to clipboard

Get "error listening on gpio" on every close

Open dzfranklin opened this issue 3 years ago • 0 comments

Device: rpi4 circuits_gpio version: 0.4.8

I open a pin for input, set interrupts, and process the interrupts in a receive loop

  @sensor_pin 23

  def start do
    {:ok, pin} = GPIO.open(@sensor_pin, :input)
    :ok = GPIO.set_pull_mode(pin, :pullup)

    spawn(fn ->
      :ok = GPIO.set_interrupts(pin, :both)
      record_loop(pin, [])
    end)
  end

  def stop(pid) do
    send(pid, {:stop, self()})

    receive do
      {:result, pin, state} ->
        :ok = GPIO.close(pin)
        state_to_result(state)
    end
  end

  defp record_loop(pin, state) do
    receive do
      {:stop, caller} ->
        send(caller, {:result, pin, state})
        nil

      # NOTE: Time is monotonic in the native time unit. However, it is not the same monotonic time
      #   as :erlang.monotonic_time. See <https://github.com/elixir-circuits/circuits_gpio/issues/3>
      {:circuits_gpio, @sensor_pin, time, value} ->
        record_loop(pin, [{time, value} | state])
    end
  end

  defp state_to_result(state) do
    # Omitted, is a pure function of state
  end

Everything appears to work fine. I get the expected data from the interrupts. However, every time I close the pin I see the message error listening on gpio 23. This occurs regardless of whether I manually close the pin or wait for it to be gc'd.

(Skimming through hal_sysfs_interrupts.c I wonder if rpi4 doesn't define the value provided to an interrupt after the pin is closed, and there's a race condition where you get an interrupt before the close propagates somehow, but this is total speculation and I don't understand what I'm talking about)

dzfranklin avatar Oct 13 '21 06:10 dzfranklin