关闭USB端口的电源

时间:2016-05-07 08:02:06

标签: linux ubuntu usb beagleboneblack

我正在寻找一种方法来关闭(并重新打开)USB端口的电源。解决方案可以是C,bash等。我正在使用BeagleBone运行32位Ubuntu 16.04 for armhf。

> uname -srvm
Linux 4.4.6-ti-r15 #1 SMP Tue Apr 5 12:32:22 UTC 2016 armv7l

我在StackOverflow和AskUbuntu上尝试过很多事情,包括:

#include <linux/usbdevice_fs.h>

int main(void)
{
    int fd = open( "/dev/bus/usb/001/002", O_WRONLY );
    if (fd < 0) return 1;

    int rc = ioctl( fd, USBDEVFS_RESET, 0 );
    if (rc < 0) return 2;

    close( fd );
    return 0;
}

我需要关闭(并最终重新启动)的USB设备是Champtek FS310条形码阅读器,当我运行lsusb时,它显示为磁卡读卡器:

> lsusb
Bus 001 Device 002: ID 040b:6543 Weltrend Semiconductor Manhattan Magnetic Card Strip Reader
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

> lsusb -t
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=musb-hdrc/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
    |__ Port 1: Dev 2, If 1, Class=Human Interface Device, Driver=usbhid, 1.5M

我发现运行这两个命令会导致设备关闭:

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

奇怪的是,它只会在“绑定”期间关闭,而不是“解除绑定”。但是一旦它以这种方式关闭,我发现将其重新打开的唯一方法是重新启动计算机,这不是一个有用的解决方案。

1 个答案:

答案 0 :(得分:1)

事实上,其他问题确实有一种技术可以解决我想做的事情。请注意,这不是一般的Linux答案,它只适用于BeagleBone Black和类似设备。 (我在BeagleBone Green上进行了测试。)从devmem2示例向后工作,这块C ++代码关闭USB电源,然后重新开启:

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);

(不包括错误处理。)

幻数0x47401c60确实是一个神奇的数字。根据一些帖子,看起来需要签署NDA才能访问一些与USB相关的文档。在ARM335X技术参考手册中,仅提及0x47401Cxx地址空间如下所示:

Block Name    Start Address    End Address
USB1 Core     0x4740_1C00      0x4740_1FFF