Linux USB: включение и выключение питания?

Как программно включить и отключить питание определенного USB-порта в Linux? Возможно ли такое вообще? Ответы Mac также оценили!

Я пытался BOC (не притворяйтесь, что вы не пытались получить его тоже!) и закончил с одним из них, и хотел бы получить некоторую пользу от этой вещи, подключив ее к нашему монитору сервера.

13 ответов


рылся в закладки

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

Похоже, вам нужно подключить его к концентратору и контроль питания хаба. Ни один из корневых концентраторов, которые я видел, не может поддерживать управление питанием.


для этого в Linux есть запись sys. От документация / usb / управление питанием.txt:

власть/уровень

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.)

что-то типа: echo on > /sys/bus/usb/devices/usb5/power/level

возможно, Вам также придется играть с настройкой autosuspend. Не говоря ядру прекратить попытки, оно может автоматически приостановить работу порта.

удачи!


взаимодействие usbfs, похоже, изменилось несколько раз, так как на этот вопрос был первоначально дан ответ. Итак, вот как я задействую питание порта концентратора на Ubuntu Oneiric Ocelot из оболочки Bash.

Поиск Шины и номер устройства:

sudo lsusb -v|less

найдите устройство в иерархии портов шины / концентратора, используя шину и номер устройства:

sudo lsusb -t|less

синтаксис, кажется, " автобусный порт.порт.порт.порт.порт... Например, мышь подключена к внешнему концентратор, который подключается к концентратору моего компьютера, который внутренне подключается к корневому концентратору:

/:  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

Итак, - 2-1.1.1 в приведенном выше случае. Наконец, цикл питания порта:

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

Я не подключил анализатор протокола, чтобы увидеть, что на самом деле происходит в автобусе, но я знаю, что моя мышь выключается, когда я ее развязываю. Я предполагаю, что на нижнем уровне это взаимодействует с хост-контроллером EHCI, чтобы фактически отключить питание порта. Это особенно полезно для встраиваемых устройства, такие как веб-камеры UVC, которые никогда не функционируют должным образом и в противном случае потребуют перезагрузки системы для сброса.

см. также .


вы могли бы использовать uhubctl - утилита командной строки для управления мощностью USB на порт для совместимых USB-концентраторов.

он работает только на концентраторах, которые поддерживают переключение питания на порт, но обратите внимание, что многие современные материнские платы имеют USB-концентраторы, которые поддерживают эту функцию. Кроме того, последняя версия uhubctl поддерживает концентраторы USB 3.0, и хорошей новостью является то, что довольно много новых концентраторов USB 3.0 поддерживают эту функцию.

для компиляции:

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

для список состояния всех концентраторов и портов, которые могут управляться uhubctl:

uhubctl

для отключения питания на Порту 5 одного совместимого концентратора:

uhubctl -a 0 -p 5

включить питание для всех портов всех совместимых концентраторов:

uhubctl -a 1

для выключения питания, а затем на:

uhubctl -a 2 -p 5

читать здесь.

раскрытие информации - я автор uhubctl.


это пример с беспроводной мышью Logitech USB под linux.

прочитайте соответствующий абзац "/ proc / bus / usb / devices "в соответствии с вашими устройствами "Vendor" (идентификатор поставщика) и "ProdID" (идентификатор продукта) или "производитель" и "продукт" (все эти значения постоянны для каждого устройства).

cat /proc/bus/usb/devices

(первый абзац с устройством включен, второй с тем же устройством выключен, но все еще подключен)

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

здесь нужны две переменные. Они расположены в строка" T: "(первая строка абзаца). Эти переменные : Bus (Bus=01 в данном примере) Cnt (Cnt=01 в данном примере)

вам нужно будет добавить "1" (арифметический) в "Cnt", чтобы получить ранг Rank=Cnt+1 (это математическая функция, Rank=2 в данном примере)

таким образом, устройство, которое вы ищете, является следующей строкой : Bus-Rank (это не математическая функция, это строка, 1-2 в этом примере)

ум также "C:" линия. Он содержит информацию о мощности (токе) устройства. Если есть звездочка в "C: "(как в нашем 1-м примере), то устройство питается. Если нет ("C:"), то устройство" более или менее " отключено, что означает, что всегда есть крошечный ток, когда устройство подключено, иначе мы не смогли бы прочитать всю эту информацию.

обратите внимание на строку "I:". Если поле "I:*" содержит звездочку (как в нашем 1-м примере) , то есть вход, от или к устройству, я не уверен, может быть, оба. Поле заключительная строка содержит используемый драйвер ("usbhid" в нашем 1-м примере)

мы готовы включить питание устройства :

сила

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

ВКЛ

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

ниже приведен простой скрипт bash "USBMS" (USB Mouse Switch), который контролирует мощность устройства в нашем примере выше. Это не очень динамично, и он использует константы" продукт "и" производитель", чтобы найти соответствующий пункт "/proc / bus / usb / устройства" Вместо этого следует использовать "поставщик" (идентификатор поставщика) и "ProdID" (идентификатор продукта). Он также проверяет состояние питания устройства. Запуск от имени суперпользователя.

команда : ./ USBMS action

параметр: action = " off " или " 0 "для выключения питания-action =" on "или" 1 " для включения питания (без кавычек)

#!/bin/bash

     USBmouseProduct="USB RECEIVER"
USBmouseManufacturer="Logitech"

              signal=

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 }' /proc/bus/usb/devices | awk -F= '{print }')
                                                  usbmbus=$(expr $usbmbus0 + 0)
                                                  usbmdev=$(awk 'NR=='$nr1' {print }' /proc/bus/usb/devices)
                                                 usbmrank=$(awk 'NR=='$nr1' {print }' /proc/bus/usb/devices | awk -F= '{print }')
                                                 usbmrank=$(expr $usbmrank + 1)
                                               usbmbusrank="$usbmbus""-""$usbmrank"
                                                usbmpower=$(awk 'NR=='$nr4' {if ( =="C:" ) {print 0}; if ( =="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
                                             )

@Kristian обычно вы не найдете программное обеспечение, контролируемое портом, контролируемым питанием, потому что пользователи не должны осознавать этот уровень. Я не думаю, что есть много вариантов использования для него, кроме как заставить устройства с питанием от шины в известное состояние и обрабатывать тупые как почтовые устройства, которые используют только USB для питания. Возможно, устройство Марка относится ко второй категории. Это грубый механизм в крайнем случае.

Как я уже упоминал, я не рассматривал реализацию детали для разматывания взлома, и я только попробовал его на хост-контроллере EHCI, встроенном в мою материнскую плату, "Intel Corporation 6 Series/C200 Series Chipset Family USB Enhanced Host Controller (rev 05)."Я бы предположил, что этот хост-контроллер имеет бит PPC набора HCSPARAMS, указывающий программное управление коммутаторами питания портов, согласно спецификации EHCI.

Если вы взаимодействуете с внешним концентратором, " концентратор указывает, поддерживает ли он переключение мощности установкой Логическое поле режима переключения мощности в wHubCharacteristics", согласно спецификации USB 2.0. Я не помню, обеспечивают ли тесты соответствия эту функциональность или нет, но если они это делают, вам нужно только найти концентратор с логотипом USB 2.0. Я предполагаю, что Хак отправит запрос функции set port, но он может задействовать больше, чем просто целевой порт. Опять же, в спецификации USB 2.0 " концентратор с выключателями питания может переключать питание на все порты как группа / Банда, на каждый порт по отдельности или иметь произвольный номер банд одного или нескольких портов."Я не уверен, есть ли хороший инструмент командной строки для получения wHubCharacteristics.

короче говоря, насколько я знаю, нет большого общего способа справиться с этой проблемой. Однако можно опросить внутренний или внешний концентратор, чтобы определить его уровень поддержки, а затем, если поддерживается, использовать его. Вопрос только в том, сколько времени вы хотите потратить на это.


в OS X вы можете получить доступ к USB-устройству из пользовательского пространства и запросить его приостановку.

вы можете найти общий пример в руководство по интерфейсу USB-устройства. Вам нужно будет использовать IOUSBDeviceInterface182 (или выше) USBDeviceSuspend метод.

Примечание: концентраторы и порты контроллера могут иметь объединенные источники питания, что означает, что один и тот же коммутатор разделяется несколькими портами. если это так, и ваше устройство находится в одной группе как другое активное устройство, он не будет выключен.


власть/уровень

" on " означает, что устройство должно быть возобновлено, а autosuspend-нет допустимый.(Конечно, системные приостановки все еще разрешены.)

"auto" - это нормальное состояние, в котором ядру разрешено autosuspend и автозапуск устройства.

"приостановить" означает, что устройство должно оставаться приостановлено, и autoresume не допускается. (Но удаленное пробуждение все еще может быть разрешено, в виду того что она проконтролирована separaely атрибут питания / пробуждения.)

Шаг 1: так что я, с USB1, USB2, с, с USB3, usb4 ....

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

Шаг 2: как я узнаю, какой из них какой? (

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

Optional 1: в случае, если lsusb показывает и нужно найти конкретный

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

cam=$(lsusb | awk "/$usb/ {print }")
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

дополнительно 2: в случае, если никто не найден-перезагрузка не удается использовать цикл питания Arduino реле над udp

#!/bin/bash

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

function age() {
   local filename=
   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 реле:

#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);
}

Я был бы более склонен отрезать провод и подключить его к последовательному порту с каким-то простым реле, работающим с одного из "готовых" штырей. Затем вы можете просто потянуть линию вниз (сигнал "Я готов к приему") в файл последовательного порта каждый раз, когда есть какая-то isssue. Когда это будет сделано, просто сигнал 'я'

мое понимание этих вещей, однако, заключается в том, что они тянут много тока до полного заряда конденсатора, затем отпустите их все сразу прошить лампочка. Я не могу представить, что такой внезапный разряд хорош для схемы компьютера. для предотвращения обратной связи в последовательный порт может потребоваться несколько диодных ловушек тока.

каждый раз, когда мой будильник гаснет, компьютер выключается!


вы работаете просто " эхо " как root, попробуйте:

echo suspend | sudo tee /sys/bus/usb/devices/usb3/power/level

A несколько USB-концентраторов может включать и выключать свои порты, как описано в ссылке. Мне еще предстоит найти материнскую плату с USB-портами, которые можно включить или отключить.


Не покупайте дорогой смарт-концентратор только для включения и выключения USB-гаджетов.
Все, что вам нужно-это микроконтроллер.

Arduino Nano™ ATmega328 * 1enter image description here

Nano - это 16mhz 8-битный компьютер с 2K RAM и 32K флэш-памяти.
Он имеет 22 программируемый контакты (8 аналоговых и 14 цифровых).
Может!--19-->читать/писать USB, и приведено в действие своим портом microUSB 5.0 V (до 12.0 V внешнего).

// 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();         
         }
}


Изысканные крошечные случаи доступны (также бесплатно 3d печатные).

C4labs Зебра Черный Лед Чехол
6

* используйте только подлинный Arduino Nano™. Остерегайтесь подделки.

обновление: миниатюризации ATtiny и беспроводной интернет микроконтоллеры также доступный.


Как я понимаю, ваши устройства поставляются USB-линией питания VCC (~5V). Проблема в том, что эта линия питания не может управляться из пользовательского пространства в стандартной платформе linux, если вы не взаимодействуете с концентраторами, включенными с управлением питанием. Код ядра Ony может коснуться этой линии питания.