Controlling a USB power supply (on/off) with Linux
Note. The information in this answer is relevant for the older kernels (up to 2.6.32). See tlwhitec's answer for the information on the newer kernels.
# 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
(You may need to change usb1 to usb n)
Source: Documentation/usb/power-management.txt.gz
Linux USB: turning the power on and off?
Digs through bookmarks
http://blog.andrew.net.au/2009/01/01#usb_power_control
Seems like you need to connect it to a hub and control the hub's power. None of the root hubs I have seen seems to be able to support power control.
How to turn USB port power on and off in Raspberry PI 4
Yes, uhubctl supports RPi4B, I have recently added support for it - you need to use uhubctl version 2.4.0 or later (or build it from master branch). It is also necessary to update USB firmware using sudo rpi-eeprom-update
to make power switching actually work.
Note that you are missing out by using sysfs method to turn USB off on RPi3B+ - using uhubctl you can control either all 4 ports, or 2 of them independently. RPi4B only supports turning off all ports at once.
Turn off power to a USB port
Indeed, that other question did have a technique that worked for what I was trying to do. Note this isn't a generic Linux answer, it will only work on BeagleBone Black and similar devices. (I tested on a BeagleBone Green.) Working backwards from the devmem2
example, this block of C++ code turns the USB power off, then back on:
const size_t page_size_in_bytes = getpagesize();
const size_t address_gpio3_13 = 0x47401c60; // see comment below
const size_t address_start = address_gpio3_13 / page_size_in_bytes * page_size_in_bytes;
const size_t address_offset = address_gpio3_13 - address_start;
int fd = open("/dev/mem", O_RDWR);
void *addr = mmap( 0, page_size_in_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, address_start );
uint8_t *byte_ptr = reinterpret_cast<uint8_t*>(addr);
byte_ptr[address_offset] = 0x00; // turn off USB
std::this_thread::sleep_for( std::chrono::milliseconds(500) );
byte_ptr[address_offset] = 0x01; // turn on USB
munmap( addr, page_size_in_bytes );
close(fd);
(Error handling not included.)
The magic number 0x47401c60
really is a magic number. According to some posts, it looks like a NDA needs to be signed to get access to some of the USB-related documentation. In the ARM335X Technical Reference Manual, the only mention of the 0x47401Cxx address space is the following on page 156:
Block Name Start Address End Address
USB1 Core 0x4740_1C00 0x4740_1FFF
Control the power of a usb port in Python
Look into the subprocess module in the standard library:
What commands you need will depend on the OS.
Windows
For windows you will want to look into devcon
This has been answered in previous posts
import subprocess
# Fetches the list of all usb devices:
result = subprocess.run(['devcon', 'hwids', '=usb'],
capture_output=True, text=True)
# ... add code to parse the result and get the hwid of the device you want ...
subprocess.run(['devcon', 'disable', parsed_hwid]) # to disable
subprocess.run(['devcon', 'enable', parsed_hwid]) # to enable
Linux
See posts on shell comands
import subprocess
# determine desired usb device
# to disable
subprocess.run(['echo', '0', '>' '/sys/bus/usb/devices/usbX/power/autosuspend_delay_ms'])
subprocess.run(['echo', 'auto', '>' '/sys/bus/usb/devices/usbX/power/control'])
# to enable
subprocess.run(['echo', 'on', '>' '/sys/bus/usb/devices/usbX/power/control'])
controlling hub power from linux shell
Found the answer to this. I have to enable PM_SUSPEND in the kernel configuration to get the class files. But then, as mentioned in the comments, RaspberryPi has the power lines directly connected to the power rails
Related Topics
How to Link to a Specific Glibc Version
Understanding Linux /Proc/Pid/Maps or /Proc/Self/Maps
Difference Between Clock_Realtime and Clock_Monotonic
How to Automatically Redirect Http to Https on Apache Servers
How to Recursively Find All Files in Current and Subfolders Based on Wildcard Matching
What Does "&" At the End of a Linux Command Mean
How to Merge Two Files Using Awk
How to Run a Shell Script At Startup
How to Change the Environment Variables of Another Process in Unix
How to Remove the Lines Which Appear on File B from Another File A
How to Make a Program Continue to Run After Log Out from Ssh
Best Practices When Running Node.Js With Port 80 (Ubuntu/Linode)
How to Declare 2D Array in Bash
What Is Double Dot(..) and Single Dot(.) in Linux
Using Printf in Assembly Leads to Empty Output When Piping, But Works on the Terminal
Read Values into a Shell Variable from a Pipe