Linux USB: включение и выключение питания?
Как я могу программно включить и отключить питание для конкретного USB-порта на Linux? Возможно ли такое вообще? Мак ответы оценил, как хорошо!
Я пытался получить BOC (не притворяйтесь, что Вы тоже не пытались его получить!) и в конечном итоге с одним из них, и хотел бы получить некоторую пользу от этой вещи, подключив его к нашему монитору сервера.
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*
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
* используйте только подлинный Arduino Nano™. Остерегайтесь подделки.обновление: миниатюризации ATtiny и беспроводной интернет микроконтоллеры также доступный.
Как я понимаю, ваши устройства поставляются USB-линией питания VCC (~5V). Проблема в том, что эта линия питания не может управляться из пользовательского пространства в стандартной среде linux, если вы не взаимодействуете с устройством с концентраторами, включенными с помощью power-control. Код ядра Ony может коснуться этой линии электропередач.