如何使用 WinUSB 与 USB 设备 通信

如何使用 WinUSB 与 USB 设备 通信,第1张

制造 USB 设备的独立硬件供应商 (IHV) 必须经常为应用程序提供访问设备功能的途径。在过去,这意味着使用 Windows 驱动程序模型 (WDM) 为设备实现一个功能驱动程序,

并将该驱动程序安装在设备栈中系统提供的协议驱动程序之上。

Windows 驱动程序基础 (WDF) 现在是 USB 驱动程序的首选模型。

它为 IHV 提供 3 个选项来提供访问 USB 设备的途径:

使用 WDF 用户模式驱动程序框架 (UMDF) 实现用户模式驱动程序。

使用 WDF 内核模式驱动程序框架 (KMDF) 实现内核模式驱动程序。

将 WinUsbsys 作为设备的功能驱动程序安装,

并提供一个使用 WinUSB API <WinUsbdll> 访问设备的应用程序。

WinUSB 在 Windows XP 上不支持 WinUSB 选择性暂停

Windows 8 USB 驱动程序堆栈体系结构

该图分别显示了 USB 20 和 USB 30 的 USB 驱动程序堆栈。

当设备附加到 xHCI 控制器时,Windows 会加载 USB 30 驱动程序堆栈。

USB 30 堆栈是 Windows 8 中的新功能。

当设备连接到 eHCI、oHCI 或 uHCI 控制器时,Windows 会加载 USB 20 驱动程序堆栈。

USB 20 驱动程序堆栈随 Windows XP Service Pack 1 (SP1) 及更高版本的 Windows *** 作系统一起提供。

如果 Windows 无法安装 HP 内核模式,则可能由于以下原因:

1 内核驱动程序已经安装:检查系统中是否已经安装了 HP 内核驱动程序,如果是,请卸载它并尝试重新安装。

2 安全软件阻止:如果您的计算机上安装了杀毒软件或防火墙等安全软件,请检查软件设置是否阻止了 HP 内核模式的安装。您可以尝试禁用这些软件并重新安装以解决此问题。

3 系统管理员权限:HP 内核模式需要管理员权限才能安装。如果您没有管理员权限,则无法安装该驱动程序。

4 *** 作系统兼容性:请确保您正在运行的 *** 作系统与驱动程序的要求相匹配。如果您的 *** 作系统太旧或太新,则可能无法安装该驱动程序。

5 驱动程序文件损坏:检查您下载的驱动程序文件是否完整和未损坏。如果文件损坏,则可能无法成功安装。

如果您无法处理此问题,建议联系设备制造商或 *** 作系统的技术支持团队以获得进一步的帮助或建议。

大家应该都只读内核打印驱动程序是什么,有的用户可能在使用win10系统共享打印机时提示无法安装内核打印驱动程序的情况,遇到这个情况要怎么办呢?这困恼了许多用户,那么win10无法安装内核打印驱动程序怎么解决?下面我们就一起来看看吧。

win10无法安装内核打印驱动程序解决方法:

1、点击开始——运行,输入“gpeditmsc”。

2、点击 计算机配置——管理模板——打印机,双击“不允许安装使用内核模式驱动程序的打印机”,设为“己禁用”。

3、关闭组策略界面,右键我的电脑——管理。

4、点击服务和应用程序——服务——Print spooler ,右键——停止。

5、打开我的电脑,进入 到C:\Windows\System32\spool\drivers\W32X86 文件夹,将里面所有文件删除(注意,此 *** 作会将于己安装的打印机驱动全部删除)。

6、再进到服务界面,将 Print spooler 服务启动。再按正常方式安装打印机驱动即可。

新版显卡驱动,例如:39135-notebook-win7-64bit,

必须要先给win7打《内核模式驱动程序框架》补丁kb2685811----2014-9-10

然后直接安装官网下载的驱动安装,如果重启电脑后发现nv独显不能用,那就是你的主板或者BIOS的支持有问题,建议更新到最新的BIOS版本。

您好,希望以下回答能帮助您

制造 USB 设备的独立硬件供应商 (IHV) 必须经常为应用程序提供访问设备功能的途径。

在过去,这意味着使用 Windows 驱动程序模型 (WDM) 为设备实现一个功能驱动程序,

并将该驱动程序安装在设备栈中系统提供的协议驱动程序之上。

Windows 驱动程序基础 (WDF) 现在是 USB 驱动程序的首选模型。

它为 IHV 提供 3 个选项来提供访问 USB 设备的途径:

使用 WDF 用户模式驱动程序框架 (UMDF) 实现用户模式驱动程序。

使用 WDF 内核模式驱动程序框架 (KMDF) 实现内核模式驱动程序。

将 WinUsbsys 作为设备的功能驱动程序安装,

并提供一个使用 WinUSB API <WinUsbdll> 访问设备的应用程序。

WinUSB 在 Windows XP 上不支持 WinUSB 选择性暂停

Windows 8 USB 驱动程序堆栈体系结构

该图分别显示了 USB 20 和 USB 30 的 USB 驱动程序堆栈。

当设备附加到 xHCI 控制器时,Windows 会加载 USB 30 驱动程序堆栈。

USB 30 堆栈是 Windows 8 中的新功能。

当设备连接到 eHCI、oHCI 或 uHCI 控制器时,Windows 会加载 USB 20 驱动程序堆栈。

USB 20 驱动程序堆栈随 Windows XP Service Pack 1 (SP1) 及更高版本的 Windows *** 作系统一起提供。

如您还有疑问可继续追问。

一、Linux device driver 的概念

系统调用是 *** 作系统内核和应用程序之间的接口,设备驱动程序是 *** 作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以象 *** 作普通文件一样对硬件设备进行 *** 作。设备驱动程序是内核的一部分,它完成以下的功能:

1、对设备初始化和释放;

2、把数据从内核传送到硬件和从硬件读取数据;

3、读取应用程序传送给设备文件的数据和回送应用程序请求的数据;

4、检测和处理设备出现的错误。

在Linux *** 作系统下有三类主要的设备文件类型,一是字符设备,二是块设备,三是网络设备。字符设备和块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了,块设备则不然,它利用一块系统内存作缓冲区,当用户进程对设备请求能满足用户的要求,就返回请求的数据,如果不能,就调用请求函数来进行实际的I/O *** 作。块设备是主要针对磁盘等慢速设备设计的,以免耗费过多的CPU时间来等待。

已经提到,用户进程是通过设备文件来与实际的硬件打交道。每个设备文件都都有其文件属性(c/b),表示是字符设备还是块设备另外每个文件都有两个设备号,第一个是主设备号,标识驱动程序,第二个是从设备号,标识使用同一个设备驱动程序的不同的硬件设备,比如有两个软盘,就可以用从设备号来区分他们。设备文件的的主设备号必须与设备驱动程序在登记时申请的主设备号一致,否则用户进程将无法访问到驱动程序。

最后必须提到的是,在用户进程调用驱动程序时,系统进入核心态,这时不再是抢先式调度。也就是说,系统必须在你的驱动程序的子函数返回后才能进行其他的工作。如果你的驱动程序陷入死循环,不幸的是你只有重新启动机器了,然后就是漫长的fsck。

二、实例剖析

我们来写一个最简单的字符设备驱动程序。虽然它什么也不做,但是通过它可以了解Linux的设备驱动程序的工作原理。把下面的C代码输入机器,你就会获得一个真正的设备驱动程序。

由于用户进程是通过设备文件同硬件打交道,对设备文件的 *** 作方式不外乎就是一些系统调用,如 open,read,write,close…, 注意,不是fopen, fread,但是如何把系统调用和驱动程序关联起来呢这需要了解一个非常关键的数据结构:

STruct file_operatiONs {

int (seek) (struct inode ,struct file , off_t ,int);

int (read) (struct inode ,struct file , char ,int);

int (write) (struct inode ,struct file , off_t ,int);

int (readdir) (struct inode ,struct file , struct dirent ,int);

int (select) (struct inode ,struct file , int ,select_table );

int (ioctl) (struct inode ,struct file , unsined int ,unsigned long);

int (mmap) (struct inode ,struct file , struct vm_area_struct );

int (open) (struct inode ,struct file );

int (release) (struct inode ,struct file );

int (fsync) (struct inode ,struct file );

int (fasync) (struct inode ,struct file ,int);

int (check_media_change) (struct inode ,struct file );

int (revalidate) (dev_t dev);

}

这个结构的每一个成员的名字都对应着一个系统调用。用户进程利用系统调用在对设备文件进行诸如read/write *** 作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数。这是linux的设备驱动程序工作的基本原理。既然是这样,则编写设备驱动程序的主要工作就是编写子函数,并填充file_operations的各个域。

下面就开始写子程序。

#include <linux/typesh> 基本的类型定义

#include <linux/fsh> 文件系统使用相关的头文件

#include <linux/mmh>

#include <linux/errnoh>

#include <asm/segmenth>

unsigned int test_major = 0;

static int read_test(struct inode inode,struct file file,char buf,int count)

{

int left; 用户空间和内核空间

if (verify_area(VERIFY_WRITE,buf,count) == -EFAULT )

return -EFAULT;

for(left = count ; left > 0 ; left--)

{

__put_user(1,buf,1);

buf++;

}

return count;

}

这个函数是为read调用准备的。当调用read时,read_test()被调用,它把用户的缓冲区全部写1。buf 是read调用的一个参数。它是用户进程空间的一个地址。但是在read_test被调用时,系统进入核心态。所以不能使用buf这个地址,必须用__put_user(),这是kernel提供的一个函数,用于向用户传送数据。另外还有很多类似功能的函数。请参考,在向用户空间拷贝数据之前,必须验证buf是否可用。这就用到函数verify_area。为了验证BUF是否可以用。

static int write_test(struct inode inode,struct file file,const char buf,int count)

{

return count;

}

static int open_test(struct inode inode,struct file file )

{

MOD_INC_USE_COUNT; 模块计数加以,表示当前内核有个设备加载内核当中去

return 0;

}

static void release_test(struct inode inode,struct file file )

{

MOD_DEC_USE_COUNT;

}

这几个函数都是空 *** 作。实际调用发生时什么也不做,他们仅仅为下面的结构提供函数指针。

struct file_operations test_fops = {

read_test,

write_test,

open_test,

release_test,

};

设备驱动程序的主体可以说是写好了。现在要把驱动程序嵌入内核。驱动程序可以按照两种方式编译。一种是编译进kernel,另一种是编译成模块(modules),如果编译进内核的话,会增加内核的大小,还要改动内核的源文件,而且不能动态的卸载,不利于调试,所以推荐使用模块方式。

int init_module(void)

{

int result;

result = register_chrdev(0, "test", &test_fops); 对设备 *** 作的整个接口

if (result < 0) {

printk(KERN_INFO "test: can't get major number\n");

return result;

}

if (test_major == 0) test_major = result; / dynamic /

return 0;

}

在用insmod命令将编译好的模块调入内存时,init_module 函数被调用。在这里,init_module只做了一件事,就是向系统的字符设备表登记了一个字符设备。register_chrdev需要三个参数,参数一是希望获得的设备号,如果是零的话,系统将选择一个没有被占用的设备号返回。参数二是设备文件名,参数三用来登记驱动程序实际执行 *** 作的函数的指针。

如果登记成功,返回设备的主设备号,不成功,返回一个负值。

void cleanup_module(void)

{

unregister_chrdev(test_major,"test");

}

在用rmmod卸载模块时,cleanup_module函数被调用,它释放字符设备test在系统字符设备表中占有的表项。

一个极其简单的字符设备可以说写好了,文件名就叫testc吧。

下面编译 :

$ gcc -O2 -DMODULE -D__KERNEL__ -c testc –c表示输出制定名,自动生成o文件

得到文件testo就是一个设备驱动程序。

如果设备驱动程序有多个文件,把每个文件按上面的命令行编译,然后

ld -r file1o file2o -o modulename。

驱动程序已经编译好了,现在把它安装到系统中去。

$ insmod –f testo

如果安装成功,在/proc/devices文件中就可以看到设备test,并可以看到它的主设备号。要卸载的话,运行 :

$ rmmod test

下一步要创建设备文件。

mknod /dev/test c major minor

c 是指字符设备,major是主设备号,就是在/proc/devices里看到的。

用shell命令

$ cat /proc/devices

就可以获得主设备号,可以把上面的命令行加入你的shell script中去。

minor是从设备号,设置成0就可以了。

我们现在可以通过设备文件来访问我们的驱动程序。写一个小小的测试程序。

#include <stdioh>

#include <sys/typesh>

#include <sys/stath>

#include <fcntlh>

main()

{

int testdev;

int i;

char buf[10];

testdev = open("/dev/test",O_RDWR);

if ( testdev == -1 )

{

printf("Cann't open file \n");

exit(0);

}

read(testdev,buf,10);

for (i = 0; i < 10;i++)

printf("%d\n",buf[i]);

close(testdev);

}

编译运行,看看是不是打印出全1

以上只是一个简单的演示。真正实用的驱动程序要复杂的多,要处理如中断,DMA,I/O port等问题。这些才是真正的难点。上述给出了一个简单的字符设备驱动编写的框架和原理,更为复杂的编写需要去认真研究LINUX内核的运行机制和具体的设备运行的机制等等。希望大家好好掌握LINUX设备驱动程序编写的方法。

以上就是关于如何使用 WinUSB 与 USB 设备 通信全部的内容,包括:如何使用 WinUSB 与 USB 设备 通信、windows无法安装hp内核模式、win10无法安装内核打印驱动程序怎么解决等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9333491.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-27
下一篇2023-04-27

发表评论

登录后才能评论

评论列表(0条)

    保存