Nice programing

Linux USB : 전원 켜기 및 끄기?

nicepro 2020. 12. 5. 10:38
반응형

Linux USB : 전원 켜기 및 끄기?


Linux에서 특정 USB 포트의 전원을 프로그래밍 방식으로 활성화 및 비활성화하려면 어떻게해야합니까? 그런 일이 가능할까요? Mac 답변도 감사합니다!

나는 BOC를 시도하고 있었고 (당신도 하나를 얻으려고하지 않은 척하지 마십시오!) 결국 이것들 중 하나를 얻었고 우리 서버 모니터에 연결하여 그것을 사용하고 싶습니다.


북마크 살펴보기

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

허브에 연결하고 허브의 전원을 제어해야하는 것 같습니다. 내가 본 루트 허브 중 어느 것도 전원 제어를 지원할 수없는 것 같습니다.


Linux에는 이에 대한 sys 항목이 있습니다. 에서 문서 / USB / 전원 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

자동 일시 중단 설정을 사용해야 할 수도 있습니다. 커널에 시도 중지를 알리지 않고 포트를 자동으로 일시 중지 할 수 있습니다.

행운을 빕니다!


usbfs 상호 작용은이 질문이 원래 답변 된 이후로 여러 번 변경된 것 같습니다. 따라서 Bash 셸에서 Ubuntu Oneiric Ocelot의 허브 포트 전원을 순환하는 방법은 다음과 같습니다.

버스 및 장치 번호 검색 :

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명령 도 참조하십시오 .


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의 저자입니다.


이것은 Linux에서 Logitech USB 무선 마우스를 사용한 예입니다.

장치 "공급 업체"(공급 업체 ID) 및 "ProdID"(제품 ID) 또는 "제조업체"및 "제품"에 따라 "/ proc / bus / usb / devices"의 관련 단락을 읽으십시오 (이러한 모든 값은 장치마다 일정 함). .

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)

순위 Rank = Cnt + 1 (이 예에서는 Rank = 2)을 얻으려면 "Cnt"에 "1"(산술 1)을 추가해야합니다.

따라서 찾고있는 장치는 다음 문자열입니다. 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 스크립트 "USBMS"(USB 마우스 스위치)입니다. 매우 동적이 아니며 "제품"및 "제조업체"상수를 사용하여 "/ proc / bus / usb / devices"의 관련 단락을 찾습니다. "공급 업체"(공급 업체 ID) 및 "ProdID"(제품 id) 대신. 또한 장치의 전원 상태를 확인합니다. 수퍼 유저로 실행합니다.

명령어 : ./USBMS 액션

매개 변수 : 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
                                             )

@Kristian 일반적으로 사용자는이 레이어를 인식하지 않아야하므로 소프트웨어 제어 포트 전원 제어 광고를 찾을 수 없습니다. 오작동하는 버스 전원 장치를 알려진 상태로 강제하고 전원을 위해 USB만을 사용하는 포스트 장치로 바보를 처리하는 것 외에는 많은 사용 사례가 없다고 생각합니다. 아마도 Mark의 장치는 후자 범주에 속합니다. 조잡한 최후의 수단입니다.

앞서 언급했듯이 바인딩 해제 해킹에 대한 구현 세부 정보를 살펴 보지 않았으며 마더 보드에 내장 된 EHCI 호스트 컨트롤러 인 "Intel Corporation 6 시리즈 / C200 시리즈 칩셋 제품군 USB 고급 호스트 컨트롤러 ( 개정판 05). " 이 호스트 컨트롤러에는 EHCI 사양에 따라 포트 전원 스위치의 소프트웨어 제어를 나타내는 HCSPARAMS 세트의 PPC 비트가 있다고 생각합니다.

외부 허브와 인터페이스하는 경우 USB 2.0 사양에 따르면 "허브는 wHubCharacteristics의 Logical Power Switching Mode 필드를 설정하여 전원 전환을 지원하는지 여부를 나타냅니다." 컴플라이언스 테스트가이 기능을 보장하는지 여부는 기억하지 않지만, 그렇다면 USB 2.0 로고가있는 허브 만 찾으면됩니다. 해킹이 포트 설정 기능 요청을 보낼 것이라고 추측하지만 대상 포트 이상을 순환 할 수 있습니다. 다시 말하지만, USB 2.0 사양에 따르면 "전원 스위치가있는 허브는 모든 포트에 그룹 / 갱으로, 각 포트로 개별적으로 또는 임의의 수의 갱으로 하나 이상의 포트로 전원을 전환 할 수 있습니다." wHubCharacteristics를 얻을 수있는 멋진 명령 줄 도구가 있는지 잘 모르겠습니다.

요컨대, 내가 아는 한이 문제를 처리하는 훌륭한 일반적인 방법은 없습니다. 그러나 내부 또는 외부 허브를 조사하여 지원 수준을 확인한 다음 지원되는 경우이를 사용할 수 있습니다. 그렇게하는 데 얼마나 많은 시간을 보내고 싶은지에 대한 질문 일뿐입니다.


OS X에서는 사용자 공간에서 USB 장치에 액세스하여 일시 중지하도록 요청할 수 있습니다.

USB 장치 인터페이스 가이드 에서 일반적인 예를 찾을 수 있습니다 . IOUSBDeviceInterface182 (또는 그 이상) USBDeviceSuspend 메서드 를 사용해야합니다 .

참고 : 허브 및 컨트롤러 포트에는 전원 공급 장치가 통합되어있을 수 있습니다. 즉, 동일한 스위치가 여러 포트에서 공유됩니다. 이 경우 장치가 다른 활성 장치와 동일한 그룹에 있으면 전원이 꺼지지 않습니다.


파워 레벨

"on"은 장치가 재개되어야하며 자동 일시 중단이 허용되지 않음을 의미합니다 (물론 시스템 일시 중단은 여전히 ​​허용됨).

"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 : 찾을 수없는 경우-재부팅이 전원 순환에 실패하면 udp를 통해 Arduino 릴레이를 사용합니다.

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

I'd be more inclined to cut the wire and hook it up to a serial port w/ some type of simple relay running ofF one of the 'recieve ready'pin. Then you could just pull the line down (signal 'i'm ready to receive') to the serial port file every time there is some isssue. When it's done, just signal 'i'm full'

My understanding of those things, however, is that they draw a lot of current until they fully charge the capacitor, then release it all at once to flash the bulb. I can't imagine such a sudden discharge is good for the circuitry of the computer. you may need some diode current traps to prevent feedback into the serial port.

Every time my alarm goes off, the computer shuts down!


A few usb hubs can switch their ports on and off, as explained in the link. I have yet to find a motherboard with usb ports which can be enabled or disabled.


Don't buy an expensive smart hub just for turning USB gadgets on and off.
All you need is a microcontroller.

Arduino Nano™ ATmega328 * 1여기에 이미지 설명 입력

The Nano is a 16MHz 8-bit computer with 2K RAM and 32K of flash storage.
It has 22 programmable pins (8 analog and 14 digital).
It can read/write USB, and is powered by its 5.0V microUSB port (up to 12.0V external).

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


Exquisite tiny cases are available (also free 3d printables).

C4Labs Zebra Black Ice Case
6

* Use Genuine Arduino Nano™ only. Beware of counterfeits.

UPDATE: Miniaturised ATtiny and wireless microcontollers are also available.


Your are running just "echo" as root, try:

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

As I understand, your devices are supplied by USB power line VCC(~5V). The problem is that this power-line can't be controlled from user-space in standard linux framework, unless you interface your device with the hubs enabled with power-control. Ony kernel code can touch this power-line.

참고URL : https://stackoverflow.com/questions/1163824/linux-usb-turning-the-power-on-and-off

반응형