CrashGordon
Posts: 10
Joined: Thu Jan 24, 2019 8:55 pm

USB Gadget mode; am I connected?

Tue Mar 12, 2019 5:09 pm

This seems like one of the most basic questions, but then what do I know?

I've set up a Pi Zero W as a USB Gadget. It's powered from the "PWR" connector. I want to know when it's been plugged into a system on the "USB" connector. There must be a flag someplace I can poll, or an event that fires, or something that tells the "device" part of the USB interface that it's actually been enumerated into a system. How can I find this info?

drgeoff
Posts: 9923
Joined: Wed Jan 25, 2012 6:39 pm

Re: USB Gadget mode; am I connected?

Tue Mar 12, 2019 5:34 pm

CrashGordon wrote:
Tue Mar 12, 2019 5:09 pm
This seems like one of the most basic questions, but then what do I know?

I've set up a Pi Zero W as a USB Gadget. It's powered from the "PWR" connector. I want to know when it's been plugged into a system on the "USB" connector. There must be a flag someplace I can poll, or an event that fires, or something that tells the "device" part of the USB interface that it's actually been enumerated into a system. How can I find this info?
I don't quite understand.

1. The data pins on the micro-USB power socket are unconnected. Running a cable between that and a USB host will not let the host "see" the RPi as a USB device.

2. If you power the RPi via the micro-USB power connector and run another cable between the Zero(W)'s micro-USB data socket and a USB host you are joining two power sources together. That is not a good idea.

User avatar
B.Goode
Posts: 8987
Joined: Mon Sep 01, 2014 4:03 pm
Location: UK

Re: USB Gadget mode; am I connected?

Tue Mar 12, 2019 6:16 pm

... and if you are providing clarification - do you have a local display/keyboard on the RPiZero and seek information about how to detect its status from the 'inside', or is this a headless setup where you need to find this information externally?

And what 'flavour' of gadget: Mass Storage, Serial, Network... ?

User avatar
HawaiianPi
Posts: 4871
Joined: Mon Apr 08, 2013 4:53 am
Location: Aloha, Oregon USA

Re: USB Gadget mode; am I connected?

Tue Mar 12, 2019 7:07 pm

As said above, for USB Gadget Mode us only the Pi0 micro USB Data port to provide both power and data connections.

You didn't tell us what OS your main computer is running, and what Gadget Mode you enabled. :?

Assuming Windows and Ethernet Gadget mode, you should see a new USB Ethernet device under Network adapters in Device Manager.
Image
My mind is like a browser. 27 tabs are open, 9 aren't responding,
lots of pop-ups...and where is that annoying music coming from?

CrashGordon
Posts: 10
Joined: Thu Jan 24, 2019 8:55 pm

Re: USB Gadget mode; am I connected?

Tue Mar 12, 2019 7:26 pm

I am currently (pun unintended) powering the Pi from both USBs. I know this can cause issues and ultimately it will run from a battery with appropriate precautions in place. At the moment, for development, both USBs are supplied from the same source so no problem. The "PWR" connection simply keeps the Pi alive as the "USB" is connected and disconnected.

My goal is to build a device that will test and wipe Chromebooks. It will initially connect as a keyboard, identify the specific model, download an appropriate restore image via wifi, then unmount/remount the image as a memory device, reboot the Chromebook in recovery mode and flash the image. The Pi will run from battery so that it doesn't have to reboot every time it's plugged in. I need to know when I'm connected so that I know when to send keystrokes. The Pi will be headless and needs to work out what to do on its own.

PS there is quite a bit of Chromebook stuff I need to work out as well, but that's not for this forum.

User avatar
HawaiianPi
Posts: 4871
Joined: Mon Apr 08, 2013 4:53 am
Location: Aloha, Oregon USA

Re: USB Gadget mode; am I connected?

Tue Mar 12, 2019 9:09 pm

Do you manage a large number of Chromebooks?

Just wondering, because Chromebooks have a built-in Powerwash function, and you seem to be building a complex device to perform a simple function that is already included in Chrome OS.
My mind is like a browser. 27 tabs are open, 9 aren't responding,
lots of pop-ups...and where is that annoying music coming from?

CrashGordon
Posts: 10
Joined: Thu Jan 24, 2019 8:55 pm

Re: USB Gadget mode; am I connected?

Tue Mar 12, 2019 9:26 pm

Single digit number of people, 5 digit number of Chromebooks.

User avatar
HawaiianPi
Posts: 4871
Joined: Mon Apr 08, 2013 4:53 am
Location: Aloha, Oregon USA

Re: USB Gadget mode; am I connected?

Wed Mar 13, 2019 8:36 am

Wow, good luck with your project. Cool idea to use a Pi Zero W.

I just tried my Pi0W on my Chromebook in USB Ethernet Gadget Mode and it worked as expected. I wrote my pre-configured Raspbian Lite USB Gadget Mode image to a micro SD card with Etcher and used a micro-USB cable and USB-A to C adapter to plug it into my Chromebook. After giving the Pi0W time to boot up I was able to SSH into [email protected]

So it seems Chrome OS does recognise a properly configured Pi Zero as a USB Gadget. There was no indication that the Pi Zero Gadget had connected to my Chromebook (it just connected silently), but it did show up in chrome://system under network-devices.

Code: Select all

/device/usb0
  Address: 1a2b3c4d5e6f
  EapAuthenticationCompleted: false
  EapAuthenticatorDetected: false
  Ethernet.LinkUp: true
  Ethernet.PPPoE: false
  IPConfigs/0: /ipconfig/usb0_83_dhcp
  Interface: usb0
  Name: usb0
  Powered: true
  ReceiveByteCount: 5418
  SelectedService: /service/1956
  TransmitByteCount: 7691
  Type: ethernet
  
My mind is like a browser. 27 tabs are open, 9 aren't responding,
lots of pop-ups...and where is that annoying music coming from?

User avatar
thagrol
Posts: 1991
Joined: Fri Jan 13, 2012 4:41 pm
Location: Darkest Somerset, UK
Contact: Website

Re: USB Gadget mode; am I connected?

Wed Mar 13, 2019 1:15 pm

Correct me if I'm wrong but isn't the OP's quesation how do I detect on the Pi when it has been connected to a USB host?

I don't think there is an easy solution, or at least I couldn't find one when I tried though I didn't dig to a particularly low level.

That said. here a few untested suggestions for hacky ways that may work:
  • Hack the gadget driver to provide the required functionality
  • Use an ethernet gadget as well as the HID gadget then check to see if the ethernet gadget thinks a cable is connected
  • Use a custom USB cable to change the state of a GPIO on connection to the host, though this is probably not straight forward as you'll also be powering the Pi through the other connector.
  • Only power the Pi via the data connection and run your send keypress code at boot. A strippted down run from RAM OS would help here(as used in the gpio expander)
  • Forget automatic detection. You need someone to plug/unplug the cable anyway so add a push button to the Pi to trigger your code.
Attempts to contact me outside of thes forums will be ignored unless signed in triplicate, sent in, sent back, queried, lost, found, subjected to public enquiry, lost again, and finally buried in soft peat for three months and recycled as firelighters

MarkTF
Posts: 301
Joined: Tue Mar 03, 2015 4:59 pm

Re: USB Gadget mode; am I connected?

Wed Mar 13, 2019 1:56 pm

The device connection should be registered in dmesg. From the RPi command line

Code: Select all

dmesg | tail
will show the most recent activity so doing this after connecting should give information about the attempt to connect and whether it was successful.

Like all things Linux one can script around this to periodically check the status, parse the result, and kick off some resultant task.

User avatar
thagrol
Posts: 1991
Joined: Fri Jan 13, 2012 4:41 pm
Location: Darkest Somerset, UK
Contact: Website

Re: USB Gadget mode; am I connected?

Wed Mar 13, 2019 3:49 pm

MarkTF wrote:
Wed Mar 13, 2019 1:56 pm
The device connection should be registered in dmesg. From the RPi command line
Not in my experience, at least not on the USB gadget end. But things may have changed recently.
Attempts to contact me outside of thes forums will be ignored unless signed in triplicate, sent in, sent back, queried, lost, found, subjected to public enquiry, lost again, and finally buried in soft peat for three months and recycled as firelighters

CrashGordon
Posts: 10
Joined: Thu Jan 24, 2019 8:55 pm

Re: USB Gadget mode; am I connected?

Fri Mar 15, 2019 3:41 pm

I decided to just use a pushbutton. I've already got one that runs "shutdown now" because I like my fs sane, so now I've got two pushbuttons. I'm mystified as to why it's not trivial to get the gadget connection state but I'm not a kernel expert so it might be more complicated than I imagine.

Will5455
Posts: 126
Joined: Sat Jul 21, 2018 8:37 pm
Location: harrisonville mo

Re: USB Gadget mode; am I connected?

Fri Mar 15, 2019 3:54 pm

yeah I just assume when something isn't there "if it where simple and the rpf didn't do it then someone else would have".
I do strange things and am sometimes the techhead stereotype.
deal with it!

CrashGordon
Posts: 10
Joined: Thu Jan 24, 2019 8:55 pm

Re: USB Gadget mode; am I connected?

Tue Apr 30, 2019 8:36 pm

Well I've made considerable progress on this project. I had to bite the bullet and use Developer Mode which eats a LOT of clock time (up to 20 minutes!) but fortunately not a lot of man-hours.

Now I can use hidg0 to send keystrokes to the ChromeBook and ttyGS0 to get responses back. We're actually collecting all the info we need, and sending it back to a server via wifi. All is well.

So it's time to "robustify" the code so that it handles (l)users doing stupid stuff. And I'm back to the problem I tried unsuccessfully to deal with early on: How to tell if I'm actually plugged into a ChromeBook. Here's the problem: If the user doesn't plug the Pi into a ChromeBook but presses the "Start Test" button, the code just hangs forever until the Pi is actually plugged in. When it's plugged in, it happily begins spewing characters, however the first few are missed because (I'm guessing) the CB takes a while to find the port. So I need to know when I'm not plugged in, so that I don't just fling keystrokes into a black hole. There's a 128X32 OLED display I can use to say something like, "Hey dummy - plug it in first!" but I need to know when that's the appropriate message to display.

It seems that the USB gadgets I'm using (serial and keyboard) come into existence and can be opened and written to at boot time, regardless of whether there's anybody listening. They don't return any kind of error (that I've been able to locate); they just wait -- forever -- before sending bytes. Clearly they must /know/ that they're disconnected, because if I send "hello world" to an empty port, then come along tomorrow and plug in, the Chromebook will see something like "llo world". That has to have been buffered someplace and it should be possible to see that the buffer has been holding bytes for x milliseconds without being able to send them.

The keyboard gadget has no timeout value to set. The serial gadget has a "timeout" and a "write_timeout" however setting either or both of those has no effect -- if I write to ttyGS0 when the USB is disconnected, I get no errors or hangs; the characters get written into oblivion. ser.rts and ser.dtr both return True whether I'm connected or not. select.select was unhelpful. os.stat(/dev/hidg0) returns the same data whether plugged in or not.

This shouldn't be this hard :-/

Andyroo

Re: USB Gadget mode; am I connected?

Tue Apr 30, 2019 8:55 pm

Is the too obvious / silly?

If the Pi has a dedicated SD card for this job and this job only AND you power the Pi via the USB port only, it must be connected to a Chromebook when it’s powered on.

Ok not great and prone to human error (wrong SD card, wrong Pi, software updates etc) but better than nothing if no one else has an idea :lol:

User avatar
thagrol
Posts: 1991
Joined: Fri Jan 13, 2012 4:41 pm
Location: Darkest Somerset, UK
Contact: Website

Re: USB Gadget mode; am I connected?

Tue Apr 30, 2019 10:05 pm

CrashGordon wrote:
Tue Apr 30, 2019 8:36 pm
It seems that the USB gadgets I'm using (serial and keyboard) come into existence and can be opened and written to at boot time, regardless of whether there's anybody listening. They don't return any kind of error (that I've been able to locate); they just wait -- forever -- before sending bytes.
That's how most of the USB gadgets work. The Pi end is created when the modules is loaded or the libcomposite config is done regardless of whether a host is connected or not.
Clearly they must /know/ that they're disconnected, because if I send "hello world" to an empty port, then come along tomorrow and plug in, the Chromebook will see something like "llo world". That has to have been buffered someplace and it should be possible to see that the buffer has been holding bytes for x milliseconds without being able to send them.
Well, yeah. But is that buffer in the g_serial code, your code, the kernel's serial port code or somewhere else? Without knowing that it's going to be hard to tell.
The keyboard gadget has no timeout value to set. The serial gadget has a "timeout" and a "write_timeout" however setting either or both of those has no effect -- if I write to ttyGS0 when the USB is disconnected, I get no errors or hangs; the characters get written into oblivion. ser.rts and ser.dtr both return True whether I'm connected or not. select.select was unhelpful. os.stat(/dev/hidg0) returns the same data whether plugged in or not.
That's what "real" serial ports do. With nothing on the other end your written data "get written into oblivion" and your reads never return. As for RTS and DTR, not all serial ports have them and I've no idea if the emulated one provide by the USB gadget does.

Edit: even if RTS/DTR/CTS etc are present there's no gaurantee that they'll actually be used. That depends on the software on each end of the link has configured the serial ports.
This shouldn't be this hard :-/
No, it shouldn't

I suspect you're into hacking the USB gadget source code to provide the hooks you need.

That said, here's a few suggestions for other approaches:
  • Put your test code into a seperate thread. Have that thread set a global flag once it's working. Use a timer in a seperate thread (or a timer callback) to kill the test thread if the flag hasn't been set after a while.
  • Does the chromebook try to set the state of the keyboard LEDs when you zero is first connected? If it does, if your code enumerates as a HID keyboard rather than a generic HID device, and if the HID gadget exposes messages from the host to userland you might be able to listen for that. If you see a message, you're connected, if not you're not
  • Run the zero's OS on a read only file system (for /boot, /, and any other partitions). Users can then pull the plug on hung tests without risking SD card corruption. You'll probably need some feedback to the user so they know it has hung. Be aware that running a read only system requires more than just mounting the partitions ro.
  • Add some extra hardware between the USB slave socket and the zero's GPIO that will prevent (hardware or software) the buttons working if no power is present on the port
I'm sorry that the above isn't of more direct help but my skills aren't up to hacking around in kernel modules.

One last thought: If you're worried about problems with your code when run without being connected to a USB host, you should probably also be worried about how your code behaves if a user disconnects the host (but leaves the Pi powered) part way through a test.
Attempts to contact me outside of thes forums will be ignored unless signed in triplicate, sent in, sent back, queried, lost, found, subjected to public enquiry, lost again, and finally buried in soft peat for three months and recycled as firelighters

hippy
Posts: 6249
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: USB Gadget mode; am I connected?

Tue Apr 30, 2019 10:35 pm

thagrol wrote:
Wed Mar 13, 2019 1:15 pm
Correct me if I'm wrong but isn't the OP's quesation how do I detect on the Pi when it has been connected to a USB host?

I don't think there is an easy solution, or at least I couldn't find one when I tried though I didn't dig to a particularly low level.
Likewise. I recall trying to figure out if a Pi Zero was in host or gadget mode, connected or not, and didn't totally succeed.

There are some sysfs files which should indicate that but they seemed not to entirely reflect the actual status as it was. They seemed to lag until a new state were determined or something like that. For example, I recall it still saying it was a connected gadget even when unplugged from the host.

Things may have changed for the better with the passing of time. That's what I'd go and check out first.

CrashGordon
Posts: 10
Joined: Thu Jan 24, 2019 8:55 pm

Re: USB Gadget mode; am I connected?

Wed May 01, 2019 10:40 pm

It takes a bit more than a minute for the Pi to boot up and be running my code. Since the application involves a small number of people going through a large number of ChromeBooks we can't afford the time of waiting a full minute every time we move from one machine to the next (more, if you allow for a "proper" shutdown before unplugging). So I've added a 1.5F supercapacitor and schottky diode to allow the Pi to run for a while unplugged.

I guess the expedient solution is to throw hardware at what should be a software problem: I'm going to add a comparator on the 5V input, upstream of the diode, to tell me via GPIO whether or not there's power coming in the USB -- if there isn't I'll presume I'm unplugged. If I use a dual package, I can use the other gate to trigger a shutdown just before the supercap collapses. This won't tell me if I'm actually connected but I should be able to presume that after a suitable blind delay, everything's in place.

The installed micro-USB is not going to be used; I'm building a custom hat to mount a USB-A connector. The hat will also hold the SSD1306 display, a couple of pushbuttons, supercap, etc. There's plenty of room for a comparator or two and I have easy access to the power input upstream of the Pi itself.

I don't think the drop from the schottky will cause me any trouble but if it does I'll have to include a little boost converter to make a legit +5. This may turn out to be necessary downstream of the supercap anyway. Those little 1S power banks are everywhere these days and the converter chips they use are cheap as dirt.

User avatar
thagrol
Posts: 1991
Joined: Fri Jan 13, 2012 4:41 pm
Location: Darkest Somerset, UK
Contact: Website

Re: USB Gadget mode; am I connected?

Wed May 01, 2019 11:25 pm

Interesting approach.

A suggestion and a question.

The suggestion: have you considered moving from stock raspbian (or other distro) to buildroot? I'm by no means an expert but I have seen zeros start in a few seconds when using a buildroot image. With buildroot you can also configure things to run entirely from RAM which, if you don't need to write to the SD card removes the need for a safe shutdown.

The question: If you're not using the micro USB how are you intending to get the host connection into and out of the zero? By soldering to the test points on the underside? As you know, USB is not available on the GPIO header.
Attempts to contact me outside of thes forums will be ignored unless signed in triplicate, sent in, sent back, queried, lost, found, subjected to public enquiry, lost again, and finally buried in soft peat for three months and recycled as firelighters

CrashGordon
Posts: 10
Joined: Thu Jan 24, 2019 8:55 pm

Re: USB Gadget mode; am I connected?

Thu May 02, 2019 3:20 pm

I hadn't considered buildroot -- never even heard of it. I'm primarily a hardware guy who can muddle through software pretty successfully. Will definitely check out buildroot.

Yes I plan to use the test points to pull USB from the Pi to the hat. And as I think about it, the schottky may not be necessary since there's noplace for power to go out the port when unplugged... I may try a 10-ohm resistor instead, just to limit inrush when charging the supercap.

(Although if buildroot w/RAM fs works out, I may be going down a whole nother road :- )

CrashGordon
Posts: 10
Joined: Thu Jan 24, 2019 8:55 pm

Re: USB Gadget mode; am I connected? Solved!

Thu Jun 20, 2019 5:51 pm

The Chromebook project is proceeding nicely. I've built 5 of these widgets and they're in regular use. They send csv-formatted data to a node.js server running on my desktop PC which relays it through the Google API to a spreadsheet in the cloud.

Turns out the UX is actually better if the tests don't start until a button is pressed, but I did find a way to detect whether the RPiZW is connected as a gadget. You can open a HID gadget to use as a keyboard whether you're connected or not. And you can write to that HID and that also works whether you're connected or not. BUT when you close the HID (and it's disconnected), that will throw an exception because there's buffered data that hasn't gone out yet. The device is closed, but the exception gets thrown. So I ended up with this:

Code: Select all

HIDPATH = "/dev/hidg0"
def RUThere():
    conn = True
    hid=open(HIDPATH,"bw")
    for x in (0,0,0,0,0,0,0,0): hid.write(x.to_bytes(1,byteorder='big'))
    try:
        hid.close()
    except BlockingIOError:
        conn = False
    return conn
RUThere() returns True if connected, and False if not. State changes pretty much instantly as the Pi is connected/disconnected. N.B the function exits with the device closed, so you'll have to open it to use it. There is a potential race condition if the user disconnects the RPi after this function returns True but you'll have to figure out how to deal with that in your particular application.

Return to “General discussion”