Skip to content

On Windows, specific device gets :einval error on open/3 #68

Open
@sparta-developers

Description

@sparta-developers

We have one device (out of a series of supposedly identical ones) that receives {:error, :einval} when trying to call Circuits.UART.open/3. The :einval error is documented as happening when trying to read from an active connection, but is not documented on open. We tried looking where it is being generated in the C code of circuits_uart and found a few occurrences, but can't find anything wrong.

Confusingly, the same device works fine on Mac and Linux, and all other devices from the same product line work fine even under the exact same Windows setup - it really seems to be just that one device only under Windows.

Setup

  • Version: 1.3.2
  • OS: Windows
  • Platform: Dell XPS13

Expected Behavior

open/3 should work as expected

Actual Behavior

We get the following stack trace:

** (RuntimeError) expected to receive :ok from UART open/3, received "{:error, :einval}"
    (vernal_falls) lib/vernal_falls/splate/firmware.ex:276: VernalFalls.Splate.Firmware.open/1
    (vernal_falls) lib/vernal_falls/splate/firmware.ex:26: VernalFalls.Splate.Firmware.handle_cast/2
    (stdlib) gen_server.erl:637: :gen_server.try_dispatch/4
    (stdlib) gen_server.erl:711: :gen_server.handle_msg/6
    (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", :open}

As a way to prevent the process from crashing, we are pattern matching on the return of open/3 to ensure that we have a successful read and open—this explains the specific RuntimeError in the stacktrace.

We forked circuits_uart and enabled the debugging tool to see what we would get.

These appear to be the relevant log outputs from three different debug files:

164787334: Starting...
164787334: uart_add_wfmo_handles
164787334:   adding read handle (active mode)
164787334: Calling WFMO count=2
164787334: WFMO returned 0
164787336: uart_add_wfmo_handles
164787336: Calling WFMO count=1
164787337: ReadFile on real_stdin failed (port closed)! 109
164787337: WFMO returned 0

We looked up the error 109 for ReadFile and it seems to us that it means "The pipe ended". We have no idea why this particular device "ends pipes" and all other don't, and on Windows only.

There is a comment in erlcmd.c that references weirdness about pipes on Windows, so maybe it's related to that?

When we call Circuits.UART.enumerate(), the device shows up fine. Here are the broken and another, working, one plugged in at the same time:

iex(vernal_falls@LAPTOP)6> Circuits.UART.enumerate()
%{
  "COM7" => %{
    description: "USB Serial Device",
    manufacturer: "Microsoft",
    product_id: 22336,
    vendor_id: 1155
  },
  "COM8" => %{
    description: "USB Serial Device",
    manufacturer: "Microsoft",
    product_id: 22336,
    vendor_id: 1155
  }
}

Steps to Reproduce the Problem

  1. Have the magic device
  2. ???
  3. Reproduce

Joking aside, since it only seems to happen to this specific device on Windows, we're not sure how you'd be able to reproduce it. Please let us know if there is any information we can provide from/about the device that would be useful for debugging this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions