Sterowanie zasilaniem USB (wł. / Wył.) W systemie Linux


164

Czy w systemie Linux można ręcznie włączać / wyłączać zasilacze z USB?

Jest taki zewnętrzny wentylator chłodzący USB (taki, którego używasz do chłodzenia się, a nie komputera) i byłoby miło móc nim sterować z terminala, ponieważ chcę ustawić wentylator gdzieś daleko.

Przypuszczam, że może to być również przydatne do wielu innych rzeczy, ponieważ istnieje wiele zabawek USB. Może oczyszczacze powietrza itp. (Chociaż słyszałem, że tak naprawdę nie działają).


9
Podsumuję dla Linuksa> = 2.6.38: plik power/level jest teraz przestarzały; użyj power/control zamiast tego . ( power/wakeupjest ok.) Ponadto akceptuje tylko „auto” i „on”, a nie „suspend”. „auto” jest wystarczająco inteligentne i jeśli zasilanie nie jest wyłączane w stanie bezczynności, jest to wina urządzenia. W każdym razie nie możesz ręcznie wyłączyć zasilania. Aby uzyskać więcej, zobacz odpowiedź poniżej autorstwa tlwhitec i dokumentację jądra: kernel.org/doc/Documentation/usb/power-management.txt
teika kazura.


2
Ta funkcja naprawdę zasługuje na dobre GUI
mikebabcock

Czy wymaga specjalnego sprzętu? Nie jest to całkiem jasne z odpowiedzi,
Vojtěch Dohnal

Odpowiedzi:


63

Uwaga. Informacje zawarte w tej odpowiedzi dotyczą starszych jąder (do 2.6.32). Zobacz odpowiedź tlwhitec, aby uzyskać informacje o nowszych jądrach.

# disable external wake-up; do this only once
echo disabled > /sys/bus/usb/devices/usb1/power/wakeup 

echo on > /sys/bus/usb/devices/usb1/power/level       # turn on
echo suspend > /sys/bus/usb/devices/usb1/power/level  # turn off

(Może być konieczna zmiana z usb1 na usb n )

Źródło: Documentation / usb / power-management.txt.gz


1
Whoa, dzięki za to. Myślałem, że muszę przejść przez libUSB bez względu na wszystko. Masz pomysł, jak uzyskać nazwy podłączonych urządzeń?
kamziro

Według tego posta bez specjalnego sprzętu nie jest to możliwe? blog.andrew.net.au/2009/01/17
NoBugs

7
Otrzymuję błąd odmowy pozwolenia, nawet jeśli używam sudo!
Wally

3
to samo dla mnie „odmowa pozwolenia” nawet po użyciu sudo
Raulp

2
Uprawnienie jest odrzucane, ponieważ polecenie w postaci sudo foo > barjest analizowane jako bezpośrednie wyjście bar, a następnie uruchamiane fooprzy użyciusudo . Przekierowanie kończy się niepowodzeniem, ponieważ dzieje się to przed uzyskaniem dostępu do konta roota. Rozwiązaniem jest użycie sudo sh -c 'echo disabled > /sys/bus/usb/devices/usb1/power/wakeup'i tak dalej: uzyskaj root, uruchom nowe piekło, aby wykonać przekierowanie, a następnie wyślij coś do deskryptora przekierowanego pliku.
wykopać

60

Zgodnie z dokumentacją , w jądrze 2.6.32 wprowadzono kilka zmian w zarządzaniu energią USB , które wydają się być zgodne z wersją 2.6.38 . Teraz musisz poczekać, aż urządzenie przejdzie w stan bezczynności , którym zarządza dany sterownik urządzenia. Sterownik musi to wspierać, w przeciwnym razie urządzenie nigdy nie osiągnie tego stanu. Niestety teraz użytkownik nie ma szans, aby to wymusić. Jeśli jednak masz szczęście i Twoje urządzenie może stać się bezczynne, aby to wyłączyć, musisz:

echo "0" > "/sys/bus/usb/devices/usbX/power/autosuspend"
echo "auto" > "/sys/bus/usb/devices/usbX/power/level"

lub dla jąder około 2.6.38 i nowszych:

echo "0" > "/sys/bus/usb/devices/usbX/power/autosuspend_delay_ms"
echo "auto" > "/sys/bus/usb/devices/usbX/power/control"

Dosłownie oznacza to przejście w stan wstrzymania w momencie, gdy urządzenie stanie się bezczynne.

Więc jeśli twój wentylator nie jest czymś „inteligentnym”, co może być postrzegane jako urządzenie i kontrolowane przez sterownik, prawdopodobnie nie będziesz miał dużo szczęścia w obecnych jądrach.


Wygląda na to, że spowoduje to ciągłe wyłączanie się urządzenia USB ... (?) W jaki sposób powinienem wznowić zasilanie, gdy to zadziała? Moim celem jest jednorazowe ponowne uruchomienie urządzenia, a nie trwała zmiana konfiguracji zawieszenia.
matanster

4
Aby wznowić zawieszone urządzenie, możesz ponownie wyłączyć „automatyczne zawieszanie” za pomocą echo "on" > "/sys/bus/usb/devices/usbX/power/control", ale myślę, że musisz zrozumieć pierwotny cel. Funkcja automatycznego zawieszania służy jedynie do umożliwienia bezczynnym urządzeniom przejścia w stan niskiego poboru mocy (w którym może wydawać się wyłączone), tylko po to, aby wznowić je później, gdy zajdzie taka potrzeba, przez hosta lub jakieś zdarzenie zewnętrzne. Dzieje się to (lub powinno się zdarzyć) automatycznie. Sam port w rzeczywistości nigdy nie jest naprawdę wyłączony. Naprawdę, przeczytaj dokumentację ;)
tlwhitec

4
Mogę potwierdzić, że działa z jądrami> 3.10. Po prostu mieć pewność, że urządzenie „id” używasz jest poprawne: dmesg | grep "usb"i użyć numeru po „USB”, na przykład: usb 2-4.4: SerialNumber: A0848020można użyć: /sys/bus/usb/devices/2-4.4/power/.... Upewnij się również, że urządzenie nie jest używane. Stworzyłem skrypt, aby uprościć ten proces
lepe

Czy istnieje sposób na zapisanie tej konfiguracji, aby za każdym razem, gdy jest podłączona, nie przywracała ustawień domyślnych? Mam urządzenie, które muszę ustawić sterowanie mocą na „włączone”, aby się ładowało.
quickblueblur

@quickblueblur brzmi dla mnie jak reguła udev .
tlwhitec

24

Znalazłem te rozwiązania, które działają przynajmniej dla poprawnie skonfigurowanego układu koncentratora USB Terminus FE 1.1:

Aby wyłączyć zasilanie wszystkich portów USB huba, możesz odłączyć huba od jądra za pomocą:

echo "1-4.4.4" > /sys/bus/usb/drivers/usb/unbind

aby ponownie włączyć zasilanie - możesz je z powrotem związać za pomocą

echo "1-4.4.4" > /sys/bus/usb/drivers/usb/bind

2. Przełączanie zasilania w każdym porcie z osobna jest trudniejsze: mogłem użyć hubpower do sterowania każdym portem - ale ma to wadę: hubpower najpierw odłącza usbdevfs, co powoduje odłączenie wszystkich urządzeń USB od systemu, przynajmniej na ubuntu :

usb_ioctl.ioctl_code = USBDEVFS_DISCONNECT;
rc = ioctl(fd, USBDEVFS_IOCTL, &usb_ioctl);

Po ioctlwyłączeniu tej opcji mogłem wyłączyć zasilanie poszczególnych portów bez odłączania wszystkich urządzeń - ale zasilanie włącza się natychmiast (prawdopodobnie z powodu niezainicjowanego urządzenia jądra), co powoduje, że urządzenie USB po prostu wykonuje „zimny restart”, co jest tym, co ja ogólnie chciałem zrobić. Moja łatana hubpower jest tutaj


Potwierdzono, że wpisy bind / unbind działają na jądrze linux 2.6.34, chipsecie ICH8 i Ubuntu 10.04.
user1357196

5
bind / unbind nie wyłącza portu USB niezależnie od chipsetu. Urządzenie nadal jest zasilane ...
themihai

1
laser myszy jest wyłączony, klawiatura nie działa, modem przestaje migać - wszystko dobrze na mojej platformie
eri

24

PowerTOP firmy Intel umożliwia przełączanie urządzeń, takich jak urządzenia peryferyjne USB w czasie rzeczywistym. Nazywa się to „tuningiem”.

sudo apt install powertop
sudo powertop
  • Przejdź do opcji „przestrajalne”.
  • Przewiń w dół do swojego urządzenia.
  • Wciśnij Enter, aby przełączyć tryb oszczędzania energii ( dobry / zły )

wprowadź opis obrazu tutaj

Pamiętaj, że Złe oznacza, że ​​urządzenie jest zawsze włączone. Przełączenie na Dobra wyłączy urządzenie po ustawionym czasie nieaktywności (domyślnie 2000 ms).

Zobacz dokumentację PowerTOP, aby dowiedzieć się, jak wprowadzić te zmiany na stałe.
Generuje dla ciebie skrypty konfiguracyjne (prawie tak, jak opisano to na innych plakatach w tym wątku).

UWAGA: Te skrypty nie mają wpływu na zasilanie pinów USB (które jest zawsze włączone).
Wysyłają one tylko protokół sterownika, aby aktywować i dezaktywować urządzenie.

Jeśli chcesz kontrolować moc pinów, możesz użyć obsługiwanego inteligentnego koncentratora USB lub jeszcze lepiej mikrokontrolera .


2
Niesamowite! : D Myślę, że jest to najbardziej przyjazny dla użytkownika sposób na zrobienie tego (chociaż na niskim poziomie wykonuje te same operacje, co opisane w innych odpowiedziach.) Dziękuję i niech twoja odpowiedź dotrze na szczyt;)
Matyas

1
Dziękuję za odpowiedź. Gdzie mam zacząć kopać, aby zmienić ustawiony czas nieaktywny?
mikezter,

Jak wspomniano w poprzednich plakatach, dokumentacja jądra jest tutaj: kernel.org/doc/Documentation/usb/power-management.txt
Dominic Cerisano

10

Możesz użyć mojego narzędzia uhubctl do kontrolowania mocy USB na port dla kompatybilnych koncentratorów USB.


dobre narzędzie w systemie OSX, ale nie znajduje dla mnie żadnego „obsługiwanego inteligentnego centrum” w debianie.
jitter

1
W Linuksie musisz albo uruchomić go jako root (pod sudo), albo skonfigurować uprawnienia udev. Możliwe jest również, że Twój host z systemem Linux nie ma podłączonych zgodnych koncentratorów.
mvp,

przy okazji jest to „beagle bone green”.
jitter


5
echo '2-1' |sudo tee /sys/bus/usb/drivers/usb/unbind

działa dla ubuntu


1
TWOJE JEST JEDYNYM ROZWIĄZANIEM, KTÓRE DZIAŁAŁO W MOJEJ SPRAWIE. Używam laptopa marki acer 12.04LTS Ubuntu.
RicoRicochet

1
Nie wyłącza urządzenia, usuwa je tylko z listy urządzeń. Jak mogę wyłączyć port USB?
rustyx

1
Jest to również jedyne rozwiązanie, które działało dla mnie przy wyłączaniu tabletu Wacom Intuos5 touch M bez odłączania go (w Fedorze 28)
user1738984

2

Zasilanie USB 5v jest zawsze włączone (nawet gdy komputer jest wyłączony, na niektórych komputerach i na niektórych portach). Prawdopodobnie będziesz musiał zaprogramować Arduino za pomocą jakiegoś przełącznika i sterować nim przez bibliotekę szeregową z USB podłączonego do komputer.

Innymi słowy, połączenie tego samouczka przełącznika i tego samouczka dotyczącego komunikacji przez bibliotekę szeregową z Arduino podłączonym przez USB.


2

Powodem, dla którego ludzie publikują takie pytania, jest przerażająca - wręcz „ ZŁA ” - funkcja automatycznego wstrzymywania USB .

Automatyczne zawieszenie zmniejsza moc do „bezczynnego” urządzenia USB i jeśli sterownik urządzenia nie obsługuje tej funkcji prawidłowo, kontakt z urządzeniem może być niemożliwy. Zatem włączanie / wyłączanie portu USB jest objawem problemu, a nie samym problemem.

Pokażę Ci, jak GLOBALNIE wyłączyć automatyczne zawieszanie, eliminując potrzebę ręcznego włączania i wyłączania portów USB:

Krótka odpowiedź:

Nie trzeba do edycji „ autosuspend_delay_ms ” indywidualnie: automatyczne usypianie USB może być wyłączone globalnie i uporczywie za pomocą następujących poleceń:

sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="/&usbcore.autosuspend=-1 /' /etc/default/grub

update-grub

systemctl reboot

Na końcu „długiej odpowiedzi” pojawia się zrzut ekranu Ubuntu 18.04, który ilustruje, w jaki sposób osiągnięto moje wyniki.

Długa odpowiedź:

Prawdą jest, że dokumentacja jądra zarządzania energią USB stwierdza, że ​​autosuspend ma zostać wycofane, a zamiast tego „ autosuspend_delay_ms ” służy do wyłączania automatycznego zawieszania USB:

"In 2.6.38 the "autosuspend" file will be deprecated
and replaced by the "autosuspend_delay_ms" file."

JEDNAK moje testy wykazały, że ustawienie usbcore.autosuspend=-1w / etc / default / grub, jak poniżej, może być używane jako GLOBALNY przełącznik funkcji automatycznego zawieszania USB - NIE musisz edytować poszczególnych plików " autosuspend_delay_ms ".

Ten sam dokument, do którego prowadzi powyższy link, stwierdza, że ​​wartość „0” jest WŁĄCZONA, a wartość ujemna jest WYŁĄCZONA :

power/autosuspend_delay_ms

    <snip> 0 means to autosuspend
    as soon as the device becomes idle, and negative
    values mean never to autosuspend.  You can write a
    number to the file to change the autosuspend
    idle-delay time.

Na poniższym zrzucie ekranu Ubuntu 18.04 z adnotacjami, pokazującym, w jaki sposób moje wyniki zostały osiągnięte (i można je odtworzyć), proszę zauważyć, że domyślną wartością jest „0” ( włączone ) w autosuspend_delay_ms .

Następnie zauważ, że po TYLKO ustawieniu usbcore.autosuspend=-1w Grub, te wartości są teraz ujemne ( wyłączone ) po ponownym uruchomieniu. Pozwoli mi to zaoszczędzić kłopotów z edytowaniem poszczególnych wartości i może teraz wyłączyć automatyczne zawieszanie USB za pomocą skryptu.

screengrab: autosuspend wartości Przed i po edycji globalnej

Mam nadzieję, że to sprawia, że ​​wyłączenie automatycznego zawieszania USB jest trochę łatwiejsze i bardziej skryptowalne -


1

Miałem problem podczas podłączania telefonu z Androidem, nie mogłem naładować telefonu, ponieważ włącznik zasilania włącza się i wyłącza ... PowerTop pozwolił mi znaleźć to ustawienie i był przydatny do rozwiązania problemu (przyczyną problemu była wartość automatyczna):

echo 'on' | sudo tee /sys/bus/usb/devices/1-1/power/control
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.