Linux USB: включение и выключение? - PullRequest
60 голосов
/ 22 июля 2009

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

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

image

Ответы [ 13 ]

24 голосов
/ 22 июля 2009

Для этого в Linux есть запись sys. От Documentation / usb / power-management.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

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

Удачи!

15 голосов
/ 30 октября 2011

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

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

sudo lsusb -v|less

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

sudo lsusb -t|less

Синтаксис выглядит как «bus-port.port.port.port.port ...». Например, моя мышь подключена к внешнему концентратору, который подключается к концентратору моего компьютера, который внутренне подключается к корневому концентратору:

/:  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, которые, кажется, никогда не функционируют должным образом и в противном случае для перезагрузки системы требуется перезагрузка.

См. Также команду udevadm.

7 голосов
/ 22 июля 2009

Копает закладки

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

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

5 голосов
/ 10 марта 2017

Вы можете использовать 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.

4 голосов
/ 12 августа 2011

Это пример с беспроводной мышью 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: *» содержит звездочку (как в нашем 1-м примере), то есть ввод с устройства или на устройство, я не уверен, может быть, оба. Поле последней строки содержит используемый драйвер ("usbhid" в нашем первом примере)

Мы готовы к включению питания нашего устройства:

выключить

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 / devices» Вместо этого вы должны использовать «Vendor» (идентификатор поставщика) и «ProdID» (идентификатор продукта). Он также проверяет состояние питания устройства. Запуск от имени суперпользователя.

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

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

#!/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
                                             )
3 голосов
/ 26 декабря 2011

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

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

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

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

2 голосов
/ 04 октября 2013

мощность / уровень

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

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

«приостановить» означает, что устройство должно оставаться приостановленным, и Автообновление не допускается. (Но удаленное пробуждение все еще может быть разрешено, поскольку он управляется отдельно атрибутом power / wakeup.)

Шаг 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 $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

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

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

#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 голосов
/ 22 июля 2009

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

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

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

1 голос
/ 05 июня 2017

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

Arduino Nano ™ ATmega328 * 1enter image description here

Nano - это 16-МГц 8-разрядный компьютер с 2 КБ ОЗУ и 32 КБ флэш-памяти.
Он имеет 22 * ​​1015 * программируемых контактов (8 аналоговых и 14 цифровых).
Он может для чтения / записи USB и питается от своего порта microUSB 5,0 В (до 12,0 В внешнего).

// 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 Zebra Black Ice
6

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

ОБНОВЛЕНИЕ: также доступны миниатюрные ATtiny и беспроводные микроконтроллеры.

1 голос
/ 01 мая 2013

A Несколько USB-концентраторов могут включать и выключать свои порты, как описано в ссылке. Я еще не нашел материнскую плату с USB-портами, которые можно включить или отключить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...