it-swarm.com.de

Linux USB: Ein- und Ausschalten der Stromversorgung?

Wie kann ich die Stromversorgung eines bestimmten USB-Ports unter Linux programmgesteuert aktivieren und deaktivieren? Ist so etwas überhaupt möglich? Mac Antworten sind ebenfalls sehr zu schätzen!

Ich habe mich für ein BOC versucht (tun Sie nicht so, als ob Sie nicht versucht hätten, eines zu bekommen!), Und am Ende habe ich eines davon bekommen, und ich möchte die Sache etwas nutzen, indem Sie es an unseren Server-Monitor anschließen.

59
Mark Harrison

Durchsucht Lesezeichen

http://blog.andrew.net.au/2009/01/01#usb_power_control

Es scheint, als müssten Sie ihn an einen Hub anschließen und die Stromversorgung des Hubs steuern. Keiner der Root-Hubs, die ich gesehen habe, scheint die Leistungssteuerung zu unterstützen.

7
Savant Degrees

In Linux gibt es dafür einen Sys-Eintrag. Aus Dokumentation/usb/power-management.txt :

leistungspegel

This file contains one of three words: "on", "auto",
or "suspend".  You can write those words to the file
to change the device's setting.

"on" means that the device should be resumed and
autosuspend is not allowed.  (Of course, system
suspends are still allowed.)

"auto" is the normal state in which the kernel is
allowed to autosuspend and autoresume the device.

"suspend" means that the device should remain
suspended, and autoresume is not allowed.  (But remote
wakeup may still be allowed, since it is controlled
separately by the power/wakeup attribute.)

So etwas wie: echo on > /sys/bus/usb/devices/usb5/power/level

Möglicherweise müssen Sie auch mit der Autosuspend-Einstellung spielen. Ohne dem Kernel mitzuteilen, dass der Versuch abgebrochen wird, wird der Port möglicherweise automatisch ausgesetzt.

Viel Glück!

24
mixonic

Die usbfs-Interaktion scheint sich seit der Beantwortung dieser Frage mehrmals geändert zu haben. Im Folgenden wird beschrieben, wie ich die Hub-Port-Stromversorgung auf Ubuntu Oneiric Ocelot von einer Bash-Shell aus ausführt.

Suchen Sie nach der Bus- und Gerätenummer:

Sudo lsusb -v|less

Suchen Sie das Gerät in der Bus-/Hub-Port-Hierarchie anhand der Bus- und Gerätenummer:

Sudo lsusb -t|less

Die Syntax scheint 'bus-port.port.port.port.port.port ...' zu sein. Beispielsweise ist meine Maus mit einem externen Hub verbunden, der mit dem Hub meines Computers verbunden ist, der intern mit einem Root-Hub verbunden ist:

/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/2p, 480M
    |__ Port 1: Dev 2, If 0, Class=hub, Driver=hub/6p, 480M
        |__ Port 1: Dev 3, If 0, Class=hub, Driver=hub/3p, 480M
            |__ Port 1: Dev 6, If 0, Class=HID, Driver=usbhid, 1.5M

Also im obigen Fall '2-1.1.1'. Schalten Sie abschließend die Port-Stromversorgung aus:

echo '2-1.1.1'|Sudo tee /sys/bus/usb/drivers/usb/unbind
sleep 1
echo '2-1.1.1'|Sudo tee /sys/bus/usb/drivers/usb/bind

Ich habe keinen Protokollanalysator angeschlossen, um zu sehen, was tatsächlich im Bus passiert, aber ich weiß, dass sich das Mauslicht ausschaltet, wenn ich es losbinde. Ich schätze, auf einer niedrigeren Ebene ist dies die Interaktion mit dem EHCI-Host-Controller, um den Port tatsächlich abzuschalten. Dies ist besonders nützlich für eingebettete Geräte, z. B. UVC-Webcams, die nie richtig zu funktionieren scheinen und zum Neustart einen Neustart des Systems erfordern.

Siehe auch den Befehl udevadm.

15

Sie können die Befehlszeilen-Utility uhubctl - verwenden, um die USB-Stromversorgung pro Port für kompatible USB-Hubs zu steuern.

Es funktioniert nur auf Hubs, die die Leistungsumschaltung pro Port unterstützen, aber beachten Sie, dass viele moderne Motherboards über USB-Hubs verfügen, die diese Funktion unterstützen. Die letzte Version von uhubctl unterstützt auch USB 3.0-Hubs. Eine gute Nachricht ist, dass einige neue USB 3.0-Hubs diese Funktion unterstützen.

Kompilieren:

git clone https://github.com/mvp/uhubctl
cd uhubctl
make

So listen Sie den Status aller Hubs und Ports auf, die von uhubctl gesteuert werden können:

uhubctl

So schalten Sie den Port 5 eines einzelnen kompatiblen Hubs aus:

uhubctl -a 0 -p 5

So schalten Sie die Stromversorgung für alle Ports aller kompatiblen Hubs ein:

uhubctl -a 1

So schalten Sie das Gerät aus und wieder ein:

uhubctl -a 2 -p 5

Lesen Sie mehr hier .

Offenlegung - Ich bin der Autor von Uhubctl.

5
mvp

Dies ist ein Beispiel mit einer kabellosen Logitech USB-Maus unter Linux.

Lesen Sie den entsprechenden Absatz von "/ proc/bus/usb/devices" entsprechend Ihrer Geräte "Vendor" (Vendor ID) und "ProdID" (Product ID) Oder "Manufacturer" und "Product" (alle diese Werte sind konstant pro Gerät).

cat /proc/bus/usb/devices

(erster Absatz bei eingeschaltetem Gerät, zweiter bei ausgeschaltetem, aber noch angeschlossenem Gerät)

T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  4 Spd=1.5 MxCh= 0
D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=046d ProdID=c50e Rev=25.10
S:  Manufacturer=Logitech
S:  Product=USB RECEIVER
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr= 70mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=usbhid
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=10ms

T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  4 Spd=1.5 MxCh= 0
D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=046d ProdID=c50e Rev=25.10
S:  Manufacturer=Logitech
S:  Product=USB RECEIVER
C:  #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr= 70mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=10ms

Sie benötigen hier zwei Variablen . Sie befinden sich in der Zeile "T:" (erste Absatzzeile) . Diese Variablen sind: Bus (Bus = 01 in diesem Beispiel) Cnt (Cnt = 01 in diesem Beispiel)

Sie müssen "1" (arithmetische 1) zu "Cnt" hinzufügen, um den Rang .__ zu erhalten. Rang = Cnt + 1 (dies ist eine mathematische Funktion, in diesem Beispiel Rang = 2)

Das Gerät, nach dem Sie suchen, ist also die folgende Zeichenfolge: Bus-Rank (dies ist keine mathematische Funktion, es ist eine Zeichenfolge, 1-2 in diesem Beispiel)

Beachten Sie auch die "C:" - Zeile . Sie enthält Informationen zur Stromstärke (Strom) des Geräts . Wenn in "C: " ein Sternchen (wie in unserem 1. Beispiel) steht, dann Wenn das Gerät nicht mit Strom versorgt wird ("C:"), ist das Gerät "mehr oder weniger" ausgeschaltet, dh es ist immer ein winziger Strom vorhanden, wenn ein Gerät angeschlossen ist. Andernfalls können wir nicht alle Daten lesen diese Info.

Denken Sie an die Zeile "I:". Wenn das Feld "I: *" ein Sternchen enthält (wie in unserem ersten Beispiel), dann werden Eingaben vom oder zum Gerät durchgeführt, ich bin mir nicht sicher, vielleicht beide. Das letzte Zeilenfeld enthält den verwendeten Treiber ("usbhid" in unserem 1. Beispiel)

Wir sind bereit, die Leistung unseres Geräts umzuschalten:

ausschalten

echo -n "Bus-Rank" > /sys/bus/usb/drivers/usb/unbind
echo -n "1-2" > /sys/bus/usb/drivers/usb/unbind (in our example)

ein

echo -n "Bus-Rank" > /sys/bus/usb/drivers/usb/bind
echo -n "1-2" > /sys/bus/usb/drivers/usb/bind (in our example)

Im Folgenden ist ein einfaches Bash-Skript "USBMS" (USB Mouse Switch) dargestellt, das in unserem obigen Beispiel die Leistung des Geräts steuert. Es ist nicht sehr dynamisch und verwendet die Konstanten "Product" und "Manufacturer", um das zu ermitteln relevanten Absatz von "/proc/bus/usb/devices"" Sie sollten stattdessen "Hersteller" (Hersteller-ID) und "ProdID" (Produkt-ID) verwenden. Sie überprüft außerdem den Energiezustand des Geräts. Als Superuser ausführen.

Befehl: ./USBMS-Aktion

parameter: action = "off" oder "0" zum Ausschalten - action = "on" oder "1" zum Einschalten (ohne Anführungszeichen)

#!/bin/bash

     USBmouseProduct="USB RECEIVER"
USBmouseManufacturer="Logitech"

              signal=$1

nr3=$(awk '/Product='"$USBmouseProduct"'/ {print NR}' /proc/bus/usb/devices)
nr3=$(expr $nr3 + 0)
nr2=$(awk '/Manufacturer='"$USBmouseManufacturer"'/ {print NR}' /proc/bus/usb/devices)
nr2=$(expr $nr2 + 0)
nr1=$(expr $nr2 - 3)
nr4=$(expr $nr3 + 1)
nrdiff=$(expr $nr3 - $nr2)

[ $nr3 != 0 -a $nr2 != 0 -a $nrdiff = 1 ] && (
                                                 usbmbus0=$(awk 'NR=='$nr1' {print $2}' /proc/bus/usb/devices | awk -F= '{print $2}')
                                                  usbmbus=$(expr $usbmbus0 + 0)
                                                  usbmdev=$(awk 'NR=='$nr1' {print $8}' /proc/bus/usb/devices)
                                                 usbmrank=$(awk 'NR=='$nr1' {print $5}' /proc/bus/usb/devices | awk -F= '{print $2}')
                                                 usbmrank=$(expr $usbmrank + 1)
                                               usbmbusrank="$usbmbus""-""$usbmrank"
                                                usbmpower=$(awk 'NR=='$nr4' {if ( $1=="C:" ) {print 0}; if ( $1=="C:*" ) {print 1}}' /proc/bus/usb/devices)

                                               case $signal in
                                                              off|0)
                                                                    [ $usbmpower = 1 ] && echo -n "$usbmbusrank" > /sys/bus/usb/drivers/usb/unbind
                                                                    ;;
                                                               on|1)
                                                                    [ $usbmpower = 0 ] && echo -n "$usbmbusrank" > /sys/bus/usb/drivers/usb/bind
                                                                    ;;
                                               esac
                                             )
4
RVF16

@Kristian Normalerweise finden Sie keine durch Software gesteuerte Port-Power-Controlled-Ankündigung, da Benutzer diese Schicht nicht kennen sollten. Ich glaube nicht, dass es viele Anwendungsfälle für ihn gibt, es sei denn, busfähige Geräte mit schlechtem Verhalten in einen bekannten Zustand zu bringen und dumm als Postgeräte zu behandeln, die nur USB für die Stromversorgung verwenden. Vielleicht fällt Marks Gerät in die letztere Kategorie. Es ist ein plumper Mechanismus für den letzten Ausweg.

Wie ich bereits erwähnt habe, habe ich mich nicht mit den Implementierungsdetails für den ungebundenen Hack befasst und habe es nur mit dem EHCI-Host-Controller in meinem Motherboard versucht, einem "Encore-Host-Controller der Intel Corporation 6 Series/C200-Serie" ( rev 05). " Ich würde vermuten, dass dieser Host-Controller das PPC - Bit von HCSPARAMS gesetzt hat, das die Softwaresteuerung der Port-Leistungsschalter gemäß der EHCI-Spezifikation anzeigt.

Wenn Sie eine Schnittstelle zu einem externen Hub herstellen, "zeigt ein Hub anhand der Einstellung des Feldes" Logical Power Switching Mode "in" wHubCharacteristics "an, ob er die Spannungsumschaltung unterstützt oder nicht, gemäß der USB 2.0-Spezifikation. Ich kann mich nicht erinnern, ob die Konformitätstests diese Funktionalität gewährleisten oder nicht, aber wenn dies der Fall ist, müssen Sie nur einen Hub mit dem USB 2.0-Logo finden. Ich vermute, der Hack würde eine Set-Port-Feature-Anfrage senden, aber er kann mehr als nur den Ziel-Port wechseln. Laut USB-2.0-Spezifikation kann "ein Hub mit Power-Switches" die Stromversorgung zu allen Ports als Gruppe/Gruppe, zu jedem Port einzeln umschalten oder eine beliebige Anzahl von Gangs von einem oder mehreren Ports haben. " Ich bin mir nicht sicher, ob es ein Nice-Befehlszeilentool gibt, um wHubCharacteristics zu erhalten.

Kurz gesagt, es gibt, soweit ich weiß, keine großartige generische Art, mit diesem Problem umzugehen. Es ist jedoch möglich, einen internen oder externen Hub abzufragen, um den Unterstützungsgrad zu ermitteln, und ihn dann zu verwenden, falls er unterstützt wird. Es ist nur eine Frage, wie viel Zeit Sie damit verbringen möchten.

3

In OS X können Sie vom Benutzerbereich aus auf ein USB-Gerät zugreifen und es zum Anhalten auffordern.

Ein allgemeines Beispiel finden Sie im USB Device Interface Guide . Sie müssen die Methode IOUSBDeviceInterface182 (oder höher) USBDeviceSuspend verwenden.

Hinweis: Hubs und Controller-Ports verfügen möglicherweise über getrennte Netzteile. Dies bedeutet, dass derselbe Switch von mehreren Ports gemeinsam genutzt wird. Ist dies der Fall und befindet sich Ihr Gerät in derselben Gruppe wie ein anderes aktives Gerät, wird es nicht heruntergefahren.

2
Hasturkun

leistungspegel

"Ein" bedeutet, dass das Gerät wieder aufgenommen werden soll und das Autosuspend nicht .__ ist. erlaubt. (Systemaussetzungen sind natürlich weiterhin zulässig.)

"auto" ist der normale Zustand, in dem der Kernel autosuspendieren und automatisch wiederaufnehmen.

"suspend" bedeutet, dass das Gerät suspendiert bleiben soll und Autoresume ist nicht erlaubt. (Das Remote-Wakeup kann jedoch weiterhin zulässig sein, da es separat vom Power/Wakeup-Attribut gesteuert wird.)

Schritt 1:also habe ich usb1, usb2, usb3, usb4 ....

$ cat /sys/bus/usb/devices/usb*/power/level
auto
auto
auto
auto

Schritt 2:woher weiß ich, wer welcher ist? ( 

# echo "on" | tee /sys/bus/usb/devices/usb*/power/level
# cat /sys/bus/usb/devices/usb*/power/level
on
on
on
on

Optional 1:falls der lsusb zeigt und einen bestimmten finden muss

#!/bin/bash
usb="046d:082d" # Find ME, Replace the ID 

cam=$(lsusb | awk "/$usb/ {print $6}")
echo $cam
if [ ! -z "$cam" -a "$cam" != " " ]; then
  for X in /sys/bus/usb/devices/*;
  do
    a=$(cat "$X/idVendor" 2>/dev/null)
    b=$(cat "$X/idProduct" 2>/dev/null)
    c="$a:$b"
    if [ ! -z "$c" -a "$c" != " " ] && [ "$c" == "$usb" ]; then
      d=$(echo $X | sed "s/\/sys\/bus\/usb\/devices\///g")
      echo "[FOUND] $d"

      #Sudo sh -c "echo on > /sys/bus/usb/devices/$d/authorized"
      sleep 2
      #Sudo sh -c "echo on > /sys/bus/usb/devices/$d/authorized"
      lsusb
      break

    fi
  done;
fi

Optional 2:Falls keiner gefunden wird - Neustart schlägt fehl, Arduino-Relay über UDP zu verwenden

#!/bin/bash

file="/var/www/html/video/now.jpeg"

function age() {
   local filename=$1
   local changed=`stat -c %Y "$filename"`
   local now=`date +%s`
   local elapsed
   let elapsed=now-changed
   echo $elapsed
}

while true
do
  target="/dev/video99"
  foundon="none"
  warn="[WARNING]:"
  ok="[OK]:"
  for i in 0 1 2 3 4
  do
    tmp="/dev/video$i"
    if [ -e $tmp ]; then
      foundon="/dev/video$i"
    #else
    #  echo "no $i"
    fi
  done

  b="none"
  if [ "$foundon" = "$b" ]; then
    echo "$warn No camera is found - inform reboot or arduino boot"

  else
    echo "$ok ln -s $foundon $target"

    ### Camera is available but something is not correct so ###
    file_age=$(age "$file")
    echo The age of $file is $file_age seconds.

    if [[ ! -f $file ]]; then
      echo "file is not found. Kernel sucks for 500mA USB's"
    else
      echo "found file: $file_age"
      if [[ $file_age -gt 240 ]]; then
        echo "$warn greater then 240 seconds"

      else
        echo "$ok - less then 240 seconds"

      fi
    fi
  fi

ls /dev/video*
sleep 5

done

Arduino-Relais: 

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

byte mac[]={0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xAD};
IPAddress ip(10,109,4,166);
byte gateway[]= {10,109, 0, 1};
byte subnet[]= {255, 255, 248,0};

unsigned int localPort = 8888;

char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
char  ReplyBuffer[] = "ackv1";
EthernetUDP Udp;
int led1 = 2;
int led2 = 3;

void setup() {
  Ethernet.begin(mac,ip);
  //Ethernet.begin(mac, ip, '8.8.8.8', gateway, subnet);
  Udp.begin(localPort);

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);

  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
}

void loop() {
  int packetSize = Udp.parsePacket();
  if(packetSize) {
    delay(1000);
    digitalWrite(led1, HIGH);    // turn the LED off by making the voltage LOW
    delay(3000);
    digitalWrite(led1, LOW);   // turn the LED on (HIGH is the voltage level)

    delay(1000);
    digitalWrite(led2, HIGH);    // turn the LED off by making the voltage LOW
    delay(3000);
    digitalWrite(led2, LOW);   // turn the LED on (HIGH is the voltage level)


    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
  delay(10);
}
2
YumYumYum

Ich würde eher geneigt sein, den Draht zu durchtrennen und an einen seriellen Port anzuschließen, mit einem einfachen Relais, das von einem der "Empfangen" -Pins ausgeführt wird. Dann können Sie einfach die Leitung nach unten ziehen (Signal "Ich bin bereit zu empfangen"), und jedes Mal, wenn ein Problem vorliegt, zur Datei des seriellen Anschlusses. Wenn es fertig ist, signalisieren Sie einfach "Ich bin voll"

Ich verstehe diese Dinge jedoch so, dass sie sehr viel Strom verbrauchen, bis sie den Kondensator vollständig aufgeladen haben, und lassen ihn dann auf einmal los, um die Glühlampe zu blinken. Ich kann mir nicht vorstellen, dass eine solche plötzliche Entladung gut für die Schaltung des Computers ist. Möglicherweise benötigen Sie Diodenstromfallen, um eine Rückkopplung in den seriellen Anschluss zu verhindern.

Bei jedem Wecker wird der Computer heruntergefahren!

1
Ape-inago

Ein wenige USB-Hubs können ihre Ports ein- und ausschalten, wie im Link erläutert. Ich muss noch ein Motherboard mit USB-Ports finden, das aktiviert oder deaktiviert werden kann.

1
ptonelli

Sie führen einfach "echo" als root aus, versuchen Sie:

echo suspend | Sudo tee /sys/bus/usb/devices/usb3/power/level
0
Adaś

Kaufen Sie keine teuren Smart Hubs, nur um USB-Gadgets ein- und auszuschalten.
Alles was Sie brauchen, ist ein Mikrocontroller.

Arduino Nano ™ ATmega328 *1 enter image description here

Der Nano ist ein 16-MHz-8-Bit-Computer mit 2K RAM und 32K Flash-Speicher.
Es hat 22 programmierbare Pins (8 analoge und 14 digitale).
Es kann lesen/schreiben USB und wird von seinem 5,0-V-microUSB-Anschluss (bis zu 12,0 V extern) mit Strom versorgt.

// USB Blinker
// Blink LED while receiving USB stream
//
// For Arduino Nano™

int LED = 13;

// setup() is run once at powerup or when reset button is pressed
//
void setup() {
        pinMode(LED, OUTPUT);   // Configure pin D13 as output 
        Serial.begin(9600);     // Open 9600bps USB stream
}

// loop() runs forever at 16Mhz, blinking the LED at 1Hz when receiving USB data.
// 
void loop() { 
        if (Serial.available() > 0) {           // When stream is buffering
                digitalWrite(LED, HIGH);        //   turn on LED 
                delay(500);                     //   wait half second
                digitalWrite(LED, LOW);         //   turn off LED
                delay(500);                     //   wait half second
                while (Serial.available() > 0)  //   drain the buffer
                        Serial.read();         
         }
}


Exquisite winzige Fälle sind verfügbar (auch kostenlose 3D-Ausdrucke ).

C4Labs Zebra Black Ice Case
6

* Verwenden Sie nur Original Arduino Nano ™. Hüten Sie sich vor Fälschungen .

UPDATE: Miniaturisierte ATtiny und Wireless Mikrocontroller sind ebenfalls verfügbar.

0