Linuxで特定のUSBポートへの電源をプログラムで有効または無効にするにはどうすればよいですか?そのようなことは可能ですか? Macの回答も歓迎します!
私は [〜#〜] boc [〜#〜] (あなたも取得しようとしないふりをしないでください!)を試みていましたが、結局これらのいずれかになりました。サーバーモニターに接続することで、その機能を活用できます。
ブックマークを掘り下げる
http://blog.andrew.net.au/2009/01/01#usb_power_control
ハブに接続し、ハブの電源を制御する必要があるようです。私が見たルートハブはどれも、電力制御をサポートできないようです。
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
自動サスペンド設定を使用する必要がある場合もあります。カーネルに試行を停止するように指示せずに、ポートを自動的に一時停止する場合があります。
がんばろう!
この質問が最初に回答されてから、usbfsの相互作用は何度も変わったようです。だから、Bash Shellから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 Webカメラなど、適切に機能するように見えず、リセットするにはシステムの再起動が必要になる組み込みデバイスに特に役立ちます。
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
(デバイスの電源がオンになっている最初の段落、同じデバイスの電源がオフになっているがまだ接続されている2番目の段落)
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
ここには2つの変数が必要です。それらは「T:」行(段落の最初の行)にあります。これらの変数は次のとおりです。Bus(この例ではBus = 01)Cnt(この例ではCnt = 01)
ランクRank = Cnt + 1を取得するには、「Cnt」に「1」(算術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スクリプト「USBMS」(USBマウススイッチ)です。それはあまり動的ではなく、「Product」および「Manufacturer」定数を使用して「/ proc/bus/usb/devices」の関連する段落を見つけます。「Vendor」(ベンダー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拡張ホストコントローラー( rev 05)。」このホストコントローラーには、PPCビットのHCSPARAMSセットがあり、EHCI仕様ごとにポートパワースイッチのソフトウェア制御を示していると思います。
外部ハブとインターフェイスする場合、USB 2.0仕様によると、「ハブは、wHubCharacteristicsのLogical Power Switching Modeフィールドの設定により、電力スイッチングをサポートするかどうかを示します」。コンプライアンステストでこの機能が保証されているかどうかは覚えていませんが、保証されている場合は、USB 2.0ロゴのあるハブを見つけるだけで済みます。ハックはポート設定機能のリクエストを送信すると推測しますが、ターゲットポート以外のサイクルも繰り返す可能性があります。繰り返しになりますが、USB 2.0仕様によれば、「電源スイッチを備えたハブは、グループ/ギャングとしてすべてのポートに電力を切り替えたり、各ポートに個別に切り替えたり、1つ以上のポートの任意の数のギャングを使用したりできます」 wHubCharacteristicsを取得するためのNiceコマンドラインツールがあるかどうかはわかりません。
要するに、私が知る限り、この問題を処理するための優れた一般的な方法はありません。ただし、内部または外部ハブに問い合わせてサポートレベルを判断し、サポートされている場合は使用することができます。それは、あなたがそうするのにどれだけの時間を費やしたいのかという問題です。
OS Xでは、ユーザー空間からUSBデバイスにアクセスし、サスペンドを要求できます。
一般的な例は SB Device Interface Guide にあります。 IOUSBDeviceInterface182 (またはそれ以上) SBDeviceSuspend メソッドを使用する必要があります。
注:ハブとコントローラーポートには電源が連動している場合があります。つまり、同じスイッチが複数のポートで共有されています。これが当てはまり、デバイスが別のアクティブなデバイスと同じグループに属している場合、電源は切断されません。
パワー/レベル
「オン」は、デバイスを再開する必要があり、自動サスペンドが許可されていないことを意味します(もちろん、システムのサスペンドも許可されています)。
「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'm ready to receive」)するだけで済みます。完了したら、「i'm full」という信号を送るだけです
しかし、これらのことについての私の理解は、コンデンサを完全に充電するまで大量の電流を流し、それを一度にすべて解放して電球を点滅させることです。このような突然の放電がコンピューターの回路に良いとは想像できません。シリアルポートへのフィードバックを防ぐために、ダイオード電流トラップが必要になる場合があります。
アラームが鳴るたびに、コンピューターはシャットダウンします!
USBガジェットをオンまたはオフにするためだけに高価なスマートハブを購入しないでください。
必要なのはマイクロコントローラーだけです。
Arduino Nano™ATmega328 *
Nanoは、2K RAMおよび32Kのフラッシュストレージを備えた16MHz 8ビットコンピューターです。
22個の プログラム可能な ピン(アナログ8個とデジタル14個)があります。
USBは read/write USBを使用でき、5.0V microUSBポート(最大12.0V外部)で駆動します。
// 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ブラックアイスケース
*本物のArduino Nano™のみを使用してください。 偽造品 に注意してください。
いくつかのusbハブ は、リンクで説明されているように、ポートのオンとオフを切り替えることができます。有効または無効にできるUSBポートを備えたマザーボードをまだ見つけていません。
ルートとして「エコー」だけを実行しています。試してください:
echo suspend | Sudo tee /sys/bus/usb/devices/usb3/power/level