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


Как я могу программно включить и отключить питание для конкретного USB-порта на Linux? Возможно ли такое вообще? Мак ответы оценил, как хорошо!

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

13 59

13 ответов:

роется в закладках

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

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

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

см. также .

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

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

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

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

To список состояния всех концентраторов и портов, которые могут управляться 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=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 / устройства" Вместо этого следует использовать "Vendor" (идентификатор поставщика) и "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, " концентратор с переключателями питания может переключать питание на все порты как группа / бригада, на каждый порт по отдельности или иметь произвольное число банд одного или нескольких портов."Я не уверен, есть ли хороший инструмент командной строки для получения характеристик whub.

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

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

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

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

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

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

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

"приостановить" означает, что устройство должно оставаться приостановлено, и автосуммирование не допускается. (Но удаленное пробуждение все еще может быть разрешено, поскольку она находится под контролем separaely по атрибут 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 }")
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);
}

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

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

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

вы работаете только "эхо" как корень, попробуйте:

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

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

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

Arduino Nano™ ATmega328* 1enter image description here

Nano представляет собой 16 МГц 8-разрядный компьютер с 2K оперативной памяти и 32K флэш-памяти.
Он имеет 22 программируемый контакты (8 аналоговых и 14 цифровых).
Он может читать/писать USB и питается от порта 5.0 в, порт microUSB (до 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 Zebra Black Ice Case
6

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

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

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