Linux USB: включение и выключение питания? - программирование

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

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

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

USB_Powered_Woot-Off_Lights7x1Detail.jpg

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

4b9b3361

Ответ 1

Обход по закладкам

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

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

Ответ 2

В 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 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

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

Удачи!

Ответ 3

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

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

Ответ 4

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

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

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

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

Ответ 5

Это пример беспроводной мыши Logitech USB под Linux.

Прочтите соответствующий параграф "/proc/bus/usb/devices" в соответствии с вашими устройствами "Поставщик" (идентификатор продавца) и "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", чтобы получить ранг Ранг = Cnt + 1 (это математическая функция, Rank = 2 в этом примере)

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

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

Разум завершает линию "I:". Если поле "I: *" содержит звездочку (как в нашем первом примере), то есть вход, с или на устройство, я не уверен, может быть, и то, и другое. В последнем поле строки указан используемый драйвер ( "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 script "USBMS" (USB-мышь), который управляет мощностью устройства в нашем примере выше. Он не очень динамичен и использует константы "Продукт" и "Производитель", чтобы найти соответствующий абзац "/proc/bus/usb/devices", Вместо этого следует использовать "Поставщик" (идентификатор продавца) и "ProdID" (идентификатор продукта). Он также проверяет состояние питания устройства. Запуск как суперпользователь.

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

: action = "off" или "0" для выключения - действие = "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
                                             )

Ответ 6

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

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

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

Ответ 7

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

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

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

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

Ответ 8

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

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

Скомпилировать:

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

Чтобы просмотреть статус всех концентраторов и портов, которые можно контролировать с помощью uhubctl:

uhubctl

Вам может потребоваться добавить -i, чтобы просмотреть состояние внутренних USB-концентраторов (они по умолчанию исключены).

Чтобы отключить питание порта 5 одного совместимого концентратора:

uhubctl -a 0 -p 5

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

uhubctl -a 1

Чтобы отключить питание, выполните следующие действия:

uhubctl -a 2 -p 5

Подробнее читайте здесь.

Отказ от ответственности - я автор uhubctl.

Ответ 9

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

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

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

Ответ 10

У вас работает только "echo" как root, попробуйте:

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

Ответ 11

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

Ответ 12

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

Arduino Nano ™ ATmega328 * 1введите описание изображения здесь

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

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

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

Ответ 13

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