导读:
摘要:在虚拟设备驱动程序(vxd)的设计中,两个尤为关键,且又令人困扰的问题是vxd的虚拟化和vxd与应用程序间的通信机制。下面,对这两个问题作一详细的探讨。 一、vxd的虚拟化 由于windows允许同时运行多个任务,所以出现多个进程试图同时访问同一物理设备的情况时,如果多个应用程序通过同一个dll驱动程序(注意和虚拟设备驱动程序vxd的区别)访问设备,......
摘要: 遥望,当年第一款mmorpg网络游戏《万王之王》风靡中国市场时,玩家热情高涨,激情飞扬的场景还历历在目,至今仍有许多玩家念念不忘当年在《万王》中创造的辉煌。 如今,有数款曾被誉为“2004年最值得期待的3d网络游戏”,由起初的十数万人同时在线的浩大声势,转眼间变成只有不到数万人苦苦支撑的冷清局面。 我们不禁问到,中国网络游戏玩家怎么了? 事实上,在吃着“韩国泡菜”和“美式汉堡”成长起来的中国网......
正文
摘要本文介绍了usb设备bulk模式驱动程序的设计。该设计使用fifo消息队列、信号量机制和定时器中断机制,可在不同的操作系统中实现。文中所用到的程序体系结构对于实现不同usb设备进行bulk模式通讯是通用的。
关键词usb;bulk模式;驱动设计
引言
通用串行总线(usb)是一种串行接口,具有自动配置能力和良好的兼容性,从而简化了计算机与外设的连接,被计算机外设硬件制造商广泛采纳。usb总线标准由1.1版升级到2.0版后,传输率由12mbps增加到了480mbps,更适宜于高速数据传输。usb设备支持打印机、扫描仪、数码相机等外设时,由于这些外设与主机间传输的数据量大,要求驱动程序采用bulk模式进行高速数据传输。
usb设备驱动的整体结构
usb设备驱动的整体结构包括如下五个主要部分:usb应用程序接口、usb设备驱动函数、usb中断服务程序、usb回调接口程序、usb标准事件处理程序。
usb应用程序接口
usb应用程序接口主要功能是对usb驱动器进行软硬件初始化、打开端口、关闭端口、读端口、写端口和端口控制操作。当设备驱动器装入系统设备表时,i/o系统就调用该应用程序接口。
usb应用程序接口的一个例程所包含的函数:
·usb_init( ) -- usb端口驱动函数的安装和初始化、硬件配置。
·usb_open( ) -- 打开usb端口。
·usb_close( ) -- 关闭usb端口。
·usb_read( ) -- 对usb端口进行读操作。
·usb_write( ) -- 对usb端口进行写操作。
·usb_ioctl( ) -- 对usb设备进行i/o控制操作。
usb设备驱动函数
1、usb_init()-- 初始化usb端口
usb_init函数初始化特定usb端口驱动器,进行软硬件配置。
初始化步骤如下:
(1) 将usb设备驱动器安装到i/o系统设备表中。
(2) 获取usb控制器使用的中断号。
(3) 获取各端口所需的系统资源,包括内存、信号量和消息队列。
(4) 初始化usb驱动器数据结构与usb端口状态寄存器。
(5) 启动usb标准事件处理程序。
(6) 启用控制端口0和usb中断最小支持集。
2、usb_open()-- 打开usb端口
usb_open函数允许应用程序打开一个usb端口,选择dma数据传输方式。
执行打开调用的典型步骤如下:
(1) 如果不是默认的控制端口0,要检查端口状态是否为"configured"。
(2) 如果不允许多次打开,要确认端口还没有打开。
(3) 确认端口对当前选择的接口有效。
(4) 选择dma传输,设置dma控制器使用该端口的fifo作为目的地址。
(5) 设置端口为打开状态。
3、usb_close()-- 关闭usb端口
usb_close函数允许usb应用程序关闭一个端口,并关闭dma通道。
执行关闭调用的典型步骤为:
(1) 关闭dma通道,放弃端口对dma控制器的使用。
(2) 设置端口为关闭状态。
4、usb_read()-- 对usb端口进行读操作
usb_read函数允许usb应用程序从输出端口或控制端口读取数据。
调用读函数的典型步骤为:
(1) 设置端口号、类型和方向。
(2) 确认端口处于打开状态。
(3) 设置端口信号量,避免多次调用。
(4) 调用readdma( ) 进行dma写操作。函数内执行步骤为:
(a) 启动dma从端口接收fifo的读操作,将数据从端口传送到内存。
(b) 等待dma完成中断。(dma中断向端口消息队列发送一条消息表示数据传输完成。)
(c) 重复进行(a)~(c)步骤直至接收到全部数据或usb主机结束传输。如果usb控制器检测到短包中断或零字节包,或者出现等待超时,则停止dma传送,并转(d)步骤执行。
(d) 向usb主机发送一个零字节包,完成控制状态步骤。
(5) 释放端口信号量。
(6) 返回接收到的字节数或错误信息。
5、usb_write()-- 对usb端口进行写操作
usb_write函数允许usb应用程序写数据到输入端口或控制端口。
执行写调用的典型步骤为:
(1) 确认端口号、类型和方向。
(2) 确认端口处于打开状态。
(3) 获取端口信号量,避免多次调用。
(4) 调用writedma( )进行dma写操作。函数内执行步骤为:
(a) dma将内存数据传送到目标端口的fifo,并等待dma完成中断。
(b) 若从接收fifo接收到usb主机的一个零字节包,或者出现等待超时,则退出并返回传输的字节数。
(c) 重复执行(a)~(c)步骤直至全部数据传输完毕时,转(d)步骤执行。
(d) 强制向usb主机发送最后的零字节包或短包用来结束传输过程。
(5) 如果是控制端口,等待来自usb主机的零字节包,完成控制状态步骤。
(6) 释放端口信号量。
(7) 返回传输的字节数或错误信息。
6、usb_ioctl()-- 对usb设备进行i/o控制操作
usb_ioctl函数设置端口状态寄存器并执行i/o端口控制功能。
usb应用程序根据控制对象不同分别调用提供应用程序控制usb接口的能力的controlioctl()和epioctl()函数。controlioctl()函数执行usb控制器整体i/o出控制功能。epioctl()函数执行个别usb端口的i/o控制功能。。
1) controlioctl( ) -- 控制器控制函数
controlioctl()函数对usb控制器进行控制操作。执行i/o功能之前获取usb控制器信号量,避免多次调用影响正在传输数据的端口。完成i/o操作后释放信号量。
usb控制器应支持的控制功能包括:
·支持远程唤醒功能。
·设置usb端口进入/退出挂起状态。
·复位usb端口。
·设置usb控制器消息队列等待超时。
·为dma选择端口fifo。
·允许/禁止可选中断。
·读取帧时间戳起始位。
·进行枚举测试。
·返回接口、备用接口和当前usb端口配置状态。
2) epioctl() -- 端口控制函数
epioctl()函数对端口进行控制操作。执行i/o功能之前获取usb控制器信号量,避免多次调用影响正在传输数据的端口。完成i/o操作后释放信号量。
端口应支持的控制功能包括:
(1) 获得usb端口状态。
(2) 设置usb端口进入/退出阻塞状态。
(3) 设置usb端口消息队列等待超时。
usb中断服务程序
usb控制器产生单一中断,多个端口共享。每个端口产生ack、nack/error中断。输出端口产生接收零字节包或短包中断。控制端口0接收设置包时产生中断。usb控制器产生usb事件中断,如帧起始(sof)、挂起、恢复和复位。
usb中断服务程序执行下列步骤:
(1) 识别发生了usb中断的类型。
(2) 清除中断产生的条件。
(3) 读usb状态寄存器,获取当前配置、接口或帧起始时间戳状态信息。
(4) 向usb控制器消息队列或回调函数的接收消息队列发送一条消息。
usb标准事件处理程序
usb驱动器初始化后,启动usb标准事件处理程序负责处理枚举过程和异步usb事件。
事件处理程序使用控制端口0,直到完成枚举过程。当usb应用程序处于非活动状态时,除控制端口0以外端口均不可访问。事件处理程序在端口0上执行控制操作,响应usb标准请求,并负责通知usb应用程序枚举完成和接口活动状态,usb事件通过回调接口传递到usb外设应用程序。当对usb端口枚举操作完成,usb应用程序就可打开并使用usb端口。
处理一个usb任务的执行过程为:
(1) 读取usb控制器消息队列。
(2) 如果接收到设置包,则调用标准请求处理函数。
(3) 如果接收到事件,则调用usb事件处理函数。
(4) 确定当前状态和有效配置/接口。
(5) 更新usb控制器和端口数据结构。
(6) 重复(1)~(5)步骤。
usb回调接口程序
回调应用程序接口是向应用程序提供反馈信息的一种接口,包括向应用程序通知usb事件的消息,如复位、配置改变、接口改变、挂起、恢复和帧起始。使用usb的应用程序要以下列方式回应这些消息:
(1) 复位 关闭端口,等待枚举测试。
(2) 配置改变 关闭端口,按新配置打开端口。
(3) 接口改变 关闭端口,从新接口打开端口。
(4) 挂起 进入低功耗模式。
(5) 恢复 退出低功耗模式。
(6) 帧起始 执行应用程序规定的处理。
总结
本文提供了进行usb端口bulk模式驱动程序设计的过程,实现在usb接口设备与host主机之间进行高速数据传输,对于嵌入式环境以及windows多线程环境下的usb设备的高速数据传输同样适用。
摘要:在虚拟设备驱动程序(vxd)的设计中,两个尤为关键,且又令人困扰的问题是vxd的虚拟化和vxd与应用程序间的通信机制。下面,对这两个问题作一详细的探讨。 一、vxd的虚拟化 由于windows允许同时运行多个任务,所以出现多个进程试图同时访问同一物理设备的情况时,如果多个应用程序通过同一个dll驱动程序(注意和虚拟设备驱动程序vxd的区别)访问设备,......
摘要: 遥望,当年第一款mmorpg网络游戏《万王之王》风靡中国市场时,玩家热情高涨,激情飞扬的场景还历历在目,至今仍有许多玩家念念不忘当年在《万王》中创造的辉煌。 如今,有数款曾被誉为“2004年最值得期待的3d网络游戏”,由起初的十数万人同时在线的浩大声势,转眼间变成只有不到数万人苦苦支撑的冷清局面。 我们不禁问到,中国网络游戏玩家怎么了? 事实上,在吃着“韩国泡菜”和“美式汉堡”成长起来的中国网......
正文
摘要本文介绍了usb设备bulk模式驱动程序的设计。该设计使用fifo消息队列、信号量机制和定时器中断机制,可在不同的操作系统中实现。文中所用到的程序体系结构对于实现不同usb设备进行bulk模式通讯是通用的。
关键词usb;bulk模式;驱动设计
引言
通用串行总线(usb)是一种串行接口,具有自动配置能力和良好的兼容性,从而简化了计算机与外设的连接,被计算机外设硬件制造商广泛采纳。usb总线标准由1.1版升级到2.0版后,传输率由12mbps增加到了480mbps,更适宜于高速数据传输。usb设备支持打印机、扫描仪、数码相机等外设时,由于这些外设与主机间传输的数据量大,要求驱动程序采用bulk模式进行高速数据传输。
usb设备驱动的整体结构
usb设备驱动的整体结构包括如下五个主要部分:usb应用程序接口、usb设备驱动函数、usb中断服务程序、usb回调接口程序、usb标准事件处理程序。
usb应用程序接口
usb应用程序接口主要功能是对usb驱动器进行软硬件初始化、打开端口、关闭端口、读端口、写端口和端口控制操作。当设备驱动器装入系统设备表时,i/o系统就调用该应用程序接口。
usb应用程序接口的一个例程所包含的函数:
·usb_init( ) -- usb端口驱动函数的安装和初始化、硬件配置。
·usb_open( ) -- 打开usb端口。
·usb_close( ) -- 关闭usb端口。
·usb_read( ) -- 对usb端口进行读操作。
·usb_write( ) -- 对usb端口进行写操作。
·usb_ioctl( ) -- 对usb设备进行i/o控制操作。
usb设备驱动函数
1、usb_init()-- 初始化usb端口
usb_init函数初始化特定usb端口驱动器,进行软硬件配置。
初始化步骤如下:
(1) 将usb设备驱动器安装到i/o系统设备表中。
(2) 获取usb控制器使用的中断号。
(3) 获取各端口所需的系统资源,包括内存、信号量和消息队列。
(4) 初始化usb驱动器数据结构与usb端口状态寄存器。
(5) 启动usb标准事件处理程序。
(6) 启用控制端口0和usb中断最小支持集。
2、usb_open()-- 打开usb端口
usb_open函数允许应用程序打开一个usb端口,选择dma数据传输方式。
执行打开调用的典型步骤如下:
(1) 如果不是默认的控制端口0,要检查端口状态是否为"configured"。
(2) 如果不允许多次打开,要确认端口还没有打开。
(3) 确认端口对当前选择的接口有效。
(4) 选择dma传输,设置dma控制器使用该端口的fifo作为目的地址。
(5) 设置端口为打开状态。
3、usb_close()-- 关闭usb端口
usb_close函数允许usb应用程序关闭一个端口,并关闭dma通道。
执行关闭调用的典型步骤为:
(1) 关闭dma通道,放弃端口对dma控制器的使用。
(2) 设置端口为关闭状态。
4、usb_read()-- 对usb端口进行读操作
usb_read函数允许usb应用程序从输出端口或控制端口读取数据。
调用读函数的典型步骤为:
(1) 设置端口号、类型和方向。
(2) 确认端口处于打开状态。
(3) 设置端口信号量,避免多次调用。
(4) 调用readdma( ) 进行dma写操作。函数内执行步骤为:
(a) 启动dma从端口接收fifo的读操作,将数据从端口传送到内存。
(b) 等待dma完成中断。(dma中断向端口消息队列发送一条消息表示数据传输完成。)
(c) 重复进行(a)~(c)步骤直至接收到全部数据或usb主机结束传输。如果usb控制器检测到短包中断或零字节包,或者出现等待超时,则停止dma传送,并转(d)步骤执行。
(d) 向usb主机发送一个零字节包,完成控制状态步骤。
(5) 释放端口信号量。
(6) 返回接收到的字节数或错误信息。
5、usb_write()-- 对usb端口进行写操作
usb_write函数允许usb应用程序写数据到输入端口或控制端口。
执行写调用的典型步骤为:
(1) 确认端口号、类型和方向。
(2) 确认端口处于打开状态。
(3) 获取端口信号量,避免多次调用。
(4) 调用writedma( )进行dma写操作。函数内执行步骤为:
(a) dma将内存数据传送到目标端口的fifo,并等待dma完成中断。
(b) 若从接收fifo接收到usb主机的一个零字节包,或者出现等待超时,则退出并返回传输的字节数。
(c) 重复执行(a)~(c)步骤直至全部数据传输完毕时,转(d)步骤执行。
(d) 强制向usb主机发送最后的零字节包或短包用来结束传输过程。
(5) 如果是控制端口,等待来自usb主机的零字节包,完成控制状态步骤。
(6) 释放端口信号量。
(7) 返回传输的字节数或错误信息。
6、usb_ioctl()-- 对usb设备进行i/o控制操作
usb_ioctl函数设置端口状态寄存器并执行i/o端口控制功能。
usb应用程序根据控制对象不同分别调用提供应用程序控制usb接口的能力的controlioctl()和epioctl()函数。controlioctl()函数执行usb控制器整体i/o出控制功能。epioctl()函数执行个别usb端口的i/o控制功能。。
1) controlioctl( ) -- 控制器控制函数
controlioctl()函数对usb控制器进行控制操作。执行i/o功能之前获取usb控制器信号量,避免多次调用影响正在传输数据的端口。完成i/o操作后释放信号量。
usb控制器应支持的控制功能包括:
·支持远程唤醒功能。
·设置usb端口进入/退出挂起状态。
·复位usb端口。
·设置usb控制器消息队列等待超时。
·为dma选择端口fifo。
·允许/禁止可选中断。
·读取帧时间戳起始位。
·进行枚举测试。
·返回接口、备用接口和当前usb端口配置状态。
2) epioctl() -- 端口控制函数
epioctl()函数对端口进行控制操作。执行i/o功能之前获取usb控制器信号量,避免多次调用影响正在传输数据的端口。完成i/o操作后释放信号量。
端口应支持的控制功能包括:
(1) 获得usb端口状态。
(2) 设置usb端口进入/退出阻塞状态。
(3) 设置usb端口消息队列等待超时。
usb中断服务程序
usb控制器产生单一中断,多个端口共享。每个端口产生ack、nack/error中断。输出端口产生接收零字节包或短包中断。控制端口0接收设置包时产生中断。usb控制器产生usb事件中断,如帧起始(sof)、挂起、恢复和复位。
usb中断服务程序执行下列步骤:
(1) 识别发生了usb中断的类型。
(2) 清除中断产生的条件。
(3) 读usb状态寄存器,获取当前配置、接口或帧起始时间戳状态信息。
(4) 向usb控制器消息队列或回调函数的接收消息队列发送一条消息。
usb标准事件处理程序
usb驱动器初始化后,启动usb标准事件处理程序负责处理枚举过程和异步usb事件。
事件处理程序使用控制端口0,直到完成枚举过程。当usb应用程序处于非活动状态时,除控制端口0以外端口均不可访问。事件处理程序在端口0上执行控制操作,响应usb标准请求,并负责通知usb应用程序枚举完成和接口活动状态,usb事件通过回调接口传递到usb外设应用程序。当对usb端口枚举操作完成,usb应用程序就可打开并使用usb端口。
处理一个usb任务的执行过程为:
(1) 读取usb控制器消息队列。
(2) 如果接收到设置包,则调用标准请求处理函数。
(3) 如果接收到事件,则调用usb事件处理函数。
(4) 确定当前状态和有效配置/接口。
(5) 更新usb控制器和端口数据结构。
(6) 重复(1)~(5)步骤。
usb回调接口程序
回调应用程序接口是向应用程序提供反馈信息的一种接口,包括向应用程序通知usb事件的消息,如复位、配置改变、接口改变、挂起、恢复和帧起始。使用usb的应用程序要以下列方式回应这些消息:
(1) 复位 关闭端口,等待枚举测试。
(2) 配置改变 关闭端口,按新配置打开端口。
(3) 接口改变 关闭端口,从新接口打开端口。
(4) 挂起 进入低功耗模式。
(5) 恢复 退出低功耗模式。
(6) 帧起始 执行应用程序规定的处理。
总结
本文提供了进行usb端口bulk模式驱动程序设计的过程,实现在usb接口设备与host主机之间进行高速数据传输,对于嵌入式环境以及windows多线程环境下的usb设备的高速数据传输同样适用。