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

Switch to ConfigFS for USB Gadgets #62

Closed
wants to merge 1 commit into from
Closed

Switch to ConfigFS for USB Gadgets #62

wants to merge 1 commit into from

Conversation

GregMefford
Copy link

This is the first step to better support for USB Gadget devices on Windows. I'm working on an additional PR to nerves_init_gadget and also new library (usb_gadget) that will make use of these ConfigFS-based USB Gadget devices.

The thing is that, if we stop compiling in a gadget device in BuildRoot, the system by itself won’t have a /dev/ttyGS0 interface anymore, so I’m questioning whether it should be the default console when it would that you either use nerves_init_gadget or configure your own with usb_gadget for it to exist. I’m fine with that because I think most people will end up wanting that, but thought it was worth bringing up, since it's a breaking change for people who are currently using the compiled-in gadget serial device.

The reason to include CONFIG_BONDING=y is so that we can set up a bonded NIC between the RNDIS and ECM Ethernet devices. This allows us to present both devices to the host device, but set one as the primary and one as the fail-over on the Nerves device side. This way, when you plug into a Windows host, only the RNDIS interface comes up, whereas on Linux, they both come up but only the ECM is active because it's primary. On OSX (by default), it doesn't have RNDIS drivers installed, so it only brings up the ECM interface. If someone has installed RNDIS drivers on OSX, it just behaves like Linux, bringing up both interfaces, with with the RNDIS one in a "failed" state because the Nerves device has it disabled while the ECM one is connected.

Related to #29
Related to #45
Related to #46
Related to nerves-project/nerves_runtime#58

@mobileoverlord
Copy link
Contributor

This is really neat I am pretty excited to the config fs stuff.

@mobileoverlord
Copy link
Contributor

@GregMefford
Copy link
Author

GregMefford commented Aug 4, 2018

I forgot to mention that the reason I left some TBD links in the CHANGELOG is that I would ideally like to link to the relevant repos when they exist, but they obviously don't yet. Here's where I'm currently at with that:

  • Make sure the default config I'm working on for usb_gadget actually works acceptably on all platforms.
  • Push the usb_gadget project as a new repo to the nerves-project org.
  • Prepare an updated nerves_init_gadget that, by default, uses usb_gadget to behave similarly to our current nerves_system_rpi0 gadget devices.
  • Get feedback on usb_gadget and changes to nerves_init_gadget until we're happy with how it works.
  • Release updated versions of things, with docs about version compatibility between them.

@GregMefford
Copy link
Author

So here's my proposal for interoperability with this new system:

  • We can talk about whether this should be 1.4.0 or if we can squeak it in as 1.3.1, given that it's a breaking change that I think should have just been included in 1.3.0.
  • I put in an optional: true dependency on nerves_init_gadget, meaning that it doesn't depend on nerves_init_gadget, but if used in a project that does depend on it, it'll enforce that you have a new-enough (not released yet as of today) version that supports the equivalent configfs gadgets that people are going to expect. If people really know what they're doing and don't want to do that, they can still put override: true on nerves_init_gadget, so I think it should be a safe thing to do.
  • The changes in nerves_init_gadget PR 32 are compatible with either rpi0 version 1.3.0 or this 1.3.1 version I'm proposing, so we would merge that first, then release this new system version that optionally requires that version.

@GregMefford
Copy link
Author

The error message someone would get looks something like this:

$ mix deps.get
Resolving Hex dependencies...

Failed to use "nerves_init_gadget" (version 0.4.0) because
  /Users/gmefford/projects/nerves/nerves_system_rpi0/mix.exs requires >= 0.4.1
  mix.exs specifies ~> 0.4.0

** (Mix) Hex dependency resolution failed, change the version requirements of your dependencies or unlock them (by using mix deps.update or mix deps.unlock). If you are unable to resolve the conflicts you can try overriding with {:dependency, "~> 1.0", override: true}

@GregMefford GregMefford force-pushed the configfs branch 2 times, most recently from 5023e6a to b9d57ef Compare December 27, 2018 01:51
@GregMefford
Copy link
Author

I've updated this PR to add the configfs option, but also leave in the g_cdc functions, built as a kernel module that's loaded by default in an Erlinit --pre-run-exec. I'm thinking that this would be considered a breaking change for anyone who is using a rootfs_overlay to customize their erlinit.config, but I looked around for other options to get this module loaded by default and didn't find any. I'd be happy to try something else if someone has an idea that would just work out of the box (e.g. a magic file that can be placed somewhere to tell the kernel to load a module). I was hoping that it would be automatically loaded when plugging into a USB host, but that does not work.

When compiling it directly into the kernel like we have been in the past, there's not any way I could find to unload it if you want to configure a different device using configfs, so that's why I'm proposing that we include it as a module that can easily be either unloaded or not loaded in the first place.

@Tica2
Copy link

Tica2 commented Aug 16, 2019

Changes from linux-4.14.defconfig help me to emulate keyboard USB gadget.

First need to remove g_cdc module if is enable
rmmod g_cdc

Create device with https://github.com/nerves-project/usb_gadget
Activate
and simulate key pressed:

'a' and 'A'

@device "/dev/hidg0"
def write_hid do
{:ok, f} = File.open(@device, [:write])
# 'a' down
IO.binwrite(f, <<0, 0, 4, 0, 0, 0, 0, 0>>)
# key up
IO.binwrite(f, <<0, 0, 0, 0, 0, 0, 0, 0>>)
# shift a (=A)
IO.binwrite(f, <<32, 0, 4, 0, 0, 0, 0, 0>>)
# key up
IO.binwrite(f, <<0, 0, 0, 0, 0, 0, 0, 0>>)
end

Note:
If g_cdc is removed serial and network is down and need to be created with ConfigFS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants