linux 和 windows usb插拔侦测

Posted qianbo_insist

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux 和 windows usb插拔侦测相关的知识,希望对你有一定的参考价值。

1、windowsU口探测事件

设备事件:
WM_DEVICECHANGE
首先要创建一个窗口,把设备事件和窗口关联

HWND h = CreateWindow(TEXT("USB_EVENT"), TEXT(""), 0, 0, 0, 0, 0,
		0, 0, GetModuleHandle(0), 0);

创建回调函数,与窗口回调相联

LRESULT CALLBACK WndProc(HWND h, UINT msg, WPARAM wp, LPARAM lp)

1.1 show me the code


#include <iostream>
#include <windows.h>
#include <dbt.h>
#include <stdio.h>
#include <math.h>
LRESULT CALLBACK WndProc(HWND h, UINT msg, WPARAM wp, LPARAM lp)
{
	if (msg == WM_DEVICECHANGE) {
		if ((DWORD)wp == DBT_DEVICEARRIVAL) {
			DEV_BROADCAST_VOLUME* p = (DEV_BROADCAST_VOLUME*)lp;
			if (p->dbcv_devicetype == DBT_DEVTYP_VOLUME) {
				int l = (int)(log(double(p->dbcv_unitmask)) / log(double(2)));
				std::cout<<'A' + l <<" 入系统"<<std::endl;
			}
		}
		else if ((DWORD)wp == DBT_DEVICEREMOVECOMPLETE) {
			DEV_BROADCAST_VOLUME* p = (DEV_BROADCAST_VOLUME*)lp;
			if (p->dbcv_devicetype == DBT_DEVTYP_VOLUME) {
				int l = (int)(log(double(p->dbcv_unitmask)) / log(double(2)));
				std::cout<<'A' + l <<" 出系统"<<std::endl;
			}
		}
		return TRUE;
	}
	else return DefWindowProc(h, msg, wp, lp);
}
int main() {
	WNDCLASS wc;
	ZeroMemory(&wc, sizeof(wc));
	wc.lpszClassName = TEXT("USB_EVENT");
	wc.lpfnWndProc = WndProc;

	RegisterClass(&wc);
	HWND h = CreateWindow(TEXT("USB_EVENT"), TEXT(""), 0, 0, 0, 0, 0,
		0, 0, GetModuleHandle(0), 0);
	MSG msg;
	while (GetMessage(&msg, 0, 0, 0) > 0) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
}

2 、linux usb 设备检测

使用lsusb命令先可以打印出所有设备,
lsusb -s 001:
使用df -h 可以查看所有盘符,以便于查看程序是否正确
linux内核种定义的事件类型位于include/linux/kobject.h文件,支持的事件类型如下:

enum kobject_action {
KOBJ_ADD,
KOBJ_REMOVE,
KOBJ_CHANGE,
KOBJ_MOVE,
KOBJ_ONLINE,
KOBJ_OFFLINE,
KOBJ_BIND,
KOBJ_UNBIND,
KOBJ_MAX
};

2.1 show me the code

int main(void)
{
    struct sockaddr_nl clt;
    struct timeval t1;
    fd_set fd;
    int buf_size = 2048, len, ret, usb_test;
    //创建套接字
    usb_test = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
    memset(&clt, 0, sizeof(clt));
    clt.nl_pid = getpid();
    clt.nl_family = AF_NETLINK;
    clt.nl_groups = 1;
    setsockopt(usb_test, SOL_SOCKET, SO_RCVBUF, &buf_size, sizeof(buf_size));
    //绑定套接字
    bind(usb_test, (struct sockaddr*)&clt, sizeof(clt));
    while (1)
    {
        char buf[2048];
        memset(&buf,0,sizeof(buf));
        FD_ZERO(&fd);
        FD_SET(usb_test, &fd);
        //监测频率周期
        t1.tv_sec = 0;
        t1.tv_usec = 50 * 1000;
        //监测
        ret = select(usb_test + 1, &fd, NULL, NULL, &t1);
        if(ret < 0)
            continue;
        if(!(ret > 0 && FD_ISSET(usb_test, &fd)))
            continue;
        
        len = recv(usb_test, &buf, sizeof(buf), 0);
        if (len > 0)
        {
            printf("%s\\n", buf);//打印收到的数据
        }
    }
    close(usb_test);
    return 0;
}

插入增加了add 消息
add@/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4:1.0/net/wlan0
add@/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4:1.0/net/wlan0/queues/rx-0
move@/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4:1.0/net/wlx0013ef800008
//移除USB网卡 增加了remove 消息
remove@/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4:1.0/net/wlx0013ef800008/queues/rx-3
remove@/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4:1.0/net/wlx0013ef800008/queues/rx-2

以上是关于linux 和 windows usb插拔侦测的主要内容,如果未能解决你的问题,请参考以下文章

Linux USB 驱动开发—— 热插拔那点事

Linux USB U盘热插拔挂载和卸载

linux环境usb hub 下连接usb口和sd读卡器,sd卡热插拔的问题?

JAVA监控windows7系统的USB插拔事件

Linux上磁盘热插拔是啥意思

请教linux下程序怎么获取热插拔事件