USB标准请求,在什么情况下,主机会发Clear featureworks命令命令给设备

您所在的位置: &
16.一个都不能少(3)
16.一个都不能少(3)
任桥伟/肖季东/肖林甫
电子工业出版社
《Linux那些事儿之我是USB(第2版)》本书基于2.6.22内核,对USB子系统的大部分源代码逐行进行分析,系统地阐释了Linux内核中USB子系统是如何运转的,子系统内部的各个模块之间是如何互相协作、配合的。本节为大家介绍一个都不能少。
16.一个都不能少(3)
这都是这两个变量对应的宏,spec里面对这些宏的意义说得很清楚。USB_PORT_STAT_ CONNECTION的意思的确是表示是否有设备连接在这个端口上,我们不妨假设有,那么portstatus和它相与的结果就是1,在spec里面,我们会看到connect_change被设置成了1。
而接下来,USB_PORT_STAT_C_CONNECTION则是表示这个端口的Current Connect Status位是否有变化,如果有变化,那么portchange和USB_PORT_STAT_C_CONNECTION相与的结果就是1,对于这种情况,我们需要发送另一个请求以清除这个flag,并且将connect_change也设置为1。这个请求叫做Clear Port Feature。这个请求也是Hub的标准请求,它的作用就是reset hub端口的某种feature。clear_port_feature()定义于drivers/usb/core/hub.c:162&/* &163&&*&USB&2.0&spec&Section&11.24.2.2 &164&&*/ &165&static&int&clear_port_feature(struct&usb_device&*hdev,&int&port1,&int&feature) &166&{ &167&&&&&return&usb_control_&msg(hdev,&usb_sndctrlpipe(hdev,&0), &168&&&&&&&&&&&&&USB_REQ_CLEAR_FEATURE,&USB_RT_PORT,&feature,&port1, &169&&&&&&&&&&&&&&&&&NULL,&0,&1000); &170&} &
USB_REQ_CLEAR_FEATURE和spec中的CLEAR_FEATURE请求是对应的,那么一共有哪些feature呢?在drivers/usb/core/hub.h中是这样定义的。 38&/* &39&&*&Port&feature&numbers &40&&*&See&USB&2.0&spec&Table&11-17 &41&&*/ &42&#define&USB_PORT_FEAT_CONNECTION&&&&&&&&0 &43&#define&USB_PORT_FEAT_ENABLE&&&&&&&&&&&&1 &44&#define&USB_PORT_FEAT_SUSPEND&&&&&&&&&&&2 &45&#define&USB_PORT_FEAT_OVER_CURRENT&&&&&&3 &46&#define&USB_PORT_FEAT_RESET&&&&&&&&&&&&&4 &47&#define&USB_PORT_FEAT_POWER&&&&&&&&&&&&&8 &48&#define&USB_PORT_FEAT_LOWSPEED&&&&&&&&&&9 &49&#define&USB_PORT_FEAT_HIGHSPEED&&&&&&&&&10 &50&#define&USB_PORT_FEAT_C_CONNECTION&&&&&&16 &51&#define&USB_PORT_FEAT_C_ENABLE&&&&&&&&&&17 &52&#define&USB_PORT_FEAT_C_SUSPEND&&&&&&&&&18 &53&#define&USB_PORT_FEAT_C_OVER_CURRENT&&&&19 &54&#define&USB_PORT_FEAT_C_RESET&&&&&&&&&&&20 &55&#define&USB_PORT_FEAT_TEST&&&&&&&&&&&&&&21 &56&#define&USB_PORT_FEAT_INDICATOR&&&&&&&&&22 &
而在spec中,Table 11-17与之相对应定义了许多的feature,我们清除的正是C_PORT_CONNECTION这一个feature。
spec里面说了,清除一个状态改变的feature就等于承认这么一个feature。(clearing that status change acknowledges the change)理由很简单,每次你检测到一个flag被设置之后,你都应该清除掉它,以便下次别人设置你就知道是有人设置了,否则你不知道在你下次判断是不是又有人设置了。同理,接下来的每个与portchange相关的判断语句都要这么做。所以如果portchange与上USB_PORT_STAT_C_CONNECTION确实为1,那么我们就要清除这个feature。同时我们当然也要记录connect_change为1。
继续,每个端口都有一个开关,这叫做enable或者disable一个端口。portchange和USB_PORT_STAT_C_ENABLE相与结果如果为1的话,说明端口开关有变化。和刚才一样,首先我们要做的是,清除掉这个变化的feature。但是这里需要注意,spec里对这个feature是这样规定的,如果portchange和USB_PORT_STAT_C_ENABLE为1,说明这个端口是从enable状态进入了disable状态。
为什么呢?因为在spec规定了,Hub的端口是不可以直接设置成enable的。通常让Hub端口设置成enable的方法是"reset hub port",用spec的话说,这叫做发送另一个请求,名为SET_FEATURE。SET_FEATURE和CLEAR_FEATURE是对应的,一个用于设置一个用于清除。 对于PORT_ENABLE,用spec里的话说:"This bit may be set only as a result of a SetPortFeature(PORT_RESET) request."PORT_RESET是为Hub定义的众多feature中的一种。
最后提醒一点,2711行至2715行这段if语句仅仅是为了打印调试信息的,也就是说如果端口enable改变了,但是端口连接没有改变,那么就打印信息来通知调试者,不要把clear_port_feature这一行也纳入到if语句里去了。因为端口enable的改变有多种可能,其中一种可能就是由于检测到了disconnection,这种情况,就是我们下面要处理的。
下面这段代码就比较复杂了,电磁干扰都给扯进来了。EMI也就是电磁干扰。就是说有时Hub端口的enable变成disable有可能是由于电磁干扰造成的。这个if条件判断的是:端口被disable了,但是连接没有变化,并且hdev-&children[i]还有值,这就说明明明有子设备连接在端口上,可是端口却被disable了,基本上这种情况就是电磁干扰造成的,否则Hub端口不会有这种举动。那么这种情况就设置connect_change为1。因为接下来我们会看到对于connect_change为1的情况,会专门进行处理,而直白的说法就是,hub_events()其实最重要的任务就是对于端口连接有变化的情况进行处理,或者说进行响应。
再往下,portchange和USB_PORT_STAT_C_SUSPEND相与结果如果为1,表明连在该端口的设备的suspend状态有变化,并且是从suspended状态出来,也就是说resume完成。(别问我为什么,spec就这么规定的,没什么理由)那么首先我们就调用clear_port_feature清掉这个feature。总之这里做的就是对于该端口连了子设备的情况就把子设备唤醒,否则如果端口没有连接子设备,那么就把端口disable掉。
2754行,portchange如果和USB_PORT_STAT_C_OVERCURRENT相与结果为1的话,说明这个端口可能曾经存在电流过大的情况,而现在这种情况不存在了,或者本来不存在而现在存在了。对此我们能做的就是首先清除这个feature。有一种比较特别的情况,如果其他端口电流过大,那么将会导致本端口断电,即Hub上一个端口出现over-current条件将有可能引起Hub上其他端口陷入powered off的状态。不管怎么说,对于over-current的情况我们都把Hub重新上电,执行hub_power_on()。
【责任编辑: TEL:(010)】&&&&&&
关于&&&&的更多文章
日晚7点整,微软公司如约发布了Windows 8.1正式版的
本书描述了黑客用默默无闻的行动为数字世界照亮了一条道路的故事。
克劳德?香农的信息论不仅催生了信息革命,也深刻地改
《项目管理实战:Microsoft Project 精髓与方法》是权
一个深受用户喜爱的好产品和一个让人觉得凑合用的一般
去年11月至今年8月间,香港学生组织大学师生监察无良企业行动(以下简称SACOM)通过调查发现,戴尔公司位于东莞的三家代工厂严重
51CTO旗下网站 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
【精品】标准的USB设备请求命令
下载积分:700
内容提示:【精品】标准的USB设备请求命令
文档格式:PPT|
浏览次数:4|
上传日期: 04:16:56|
文档星级:
该用户还上传了这些文档
【精品】标准的USB设备请求命令
官方公共微信采用PDIUSBD12的USB系统固件程序设计
&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&
& 今天是:&&& 欢迎您光临[3edu教育网]!本站资源完全免费,无须注册,您最希望得到的,正是我们最乐于献上的。
◆您现在的位置:&&>>&&>>&&>>&&>>&&>>&论文正文
采用PDIUSBD12的USB系统固件程序设计
采用PDIUSBD12的USB系统固件程序设计
&&&&将本站加入收藏,以便日后访问。&&&&
采用PDIUSBD12的USB系统固件程序设计
摘要:在设计USB系统的过程中,固件程序的编写是非常重要的一个环节,它直接影响到开发产品的数据传输速度。以Phillips公司的USB控制芯睡PDIUSBD12为例,介绍了在设计开发USB外设中。固件的作用以及固件程序的编写流程,并给出了相应程序。
&&& 关键词:USB 固件程序 PDIUSBD12 端点 单片机
USB(Universal Serial Bus)即通用串行总线,是现在非常流行的一种快速、双向、廉价、可以进行热插拨的接口,在现在的每一台PC机上都可以找到一对USB接口。在遵循USB1.1规范的基础上,USB接口最高传输速度可达12Mb/s:而在最新的USB2.0规范下,更可以达到480Mb/s.同时它可以连接127个USB设备,而且连接的方式也十分灵活,既可以使用串行连接,也可以使用集线器(Hub)把多个设备连接在一起,再同PC机的USB接口相连.此外,它还可以从系统中直接汲取电流,无需单独的供电系统.USB的这些特点使它获得了广泛的应用.但是使用上的方便则意味着开发上的复杂,主要是编程的复杂性大大的增加了.
在设计开发一个USB外设的时候,开发者主要需要编写三部分的程序: ①固件程序;②USB驱动程序;③客户应用程序.本文主要阐述固件程序的编写.
1 固件要完成的主要工作
固件是FIREWARE的对应中文词,它实际上是单片机的程序文件,其编写语言可以采用C语言或是汇编语言.它的操作方式与硬件联系紧密,包括USB设备的连接USB协议、中断处理等,它不是单纯的软件,而是软件和硬件的结合,开发者需要对端口、中断和硬件结构非常熟悉。固件程序一般放入MCU中,当把设备连接到主机上(USB连接线插入插孔)时,上位机可以发现新设备,然后建立连接。因此。编写固件程序的一个最主要的目的就时让Windows可以检测和识别设备。
2 PDIUSBD12芯片特点
PDIUSBD12是一个性能优化的USB器件,通常用于基于微控制器的系统,并通过高速通用并行接口与微控制器进行通信,而且支持本地DMA传输。该器件采用模块化的方法实现一个USB接口,允许在众多可用的微控制器中选择最合适的作为系统微控制器,允许使用现存的体系结构使固件投资减到最小。这种灵活性减少了开发时间、风险和成本。该器件使开发成本低且高效的USB外围设备的一种有效途径。PDIUSDB12完全符合USB1.1规范,也能适应大多数设备类规范的设计,如成像类、大容量存储类、通信类、打印类和人工输入设备等。因此,PDIUSBD12非常适合做很多外围设备,如打印机、扫描仪、外部大容量存储器(Zip驱动器)和数码相机等。现在很多用SCSI实现的很多设备如果用USB来实现可以直接降低成本。
PDIUSBD12还集成了SoftConnect、GoodLink、可编程时钟输出、低频晶振和终端电阻等特性。所有这些特性都能在系统实现时节省成本,同时在外围设备上很容易实现更高级的USB功能。
3 PDIUSBD12固件程序的编写
USB设备启动流程如下:
(1) USB设备接入USB口,发出连接USB命令;
(2) 主机发出读设备描述符两次;
(3) 主机根据设备描述符――厂商ID、产品ID,启动相应设备驱动程序;
(4) 设备驱动程序初始化USB设备;
①读设备描述符;
②读配置描述符;
③选择接口、端点(管道),确定传输方式。图1 PDIUSBD12测试电路连接图&&& 图1是PDIUSBD12的电路连接图。
USB固件程序程序由三部分组成:①初始化单片机和所有的外围电路(包括PDIUSBD12);②主循环部分,其任务是可以中断的;③中断服务程序,其任务是对时间敏感的,必须马上执行。根据USB协议,任何传输都是由主机(Host)开始的。单片机作它的前台工作,等待中断。主机首先要发令牌包给USB设备(这里是PDIUSBD12),PDIUSBD12接收到令牌包后就给单片机发中断。单片机进入中断服务程序,首先读PDIUSBD12的中断寄存器,判断USB令牌包的类型,然后执行相应的操作。在USB单片机程序中,要完成对各种令牌包的响应,其中比较难处理的是SETUP包,主要是端口0的编程。
单片机与PDIUSBD12的通信主要是靠单片机给PDIUSBD12发命令和数据来实现的。PDIUSBD12的命令字分为三种:初始化命令字、数据流命令字和通用命令字。PDIUSBD12数据手册给出了各种命令的代码和地址。单片机先给PDIUSBD12的命令地址发命令,根据不同命令的要求再发送或读出不同的数据。因此,可以将每种命令做成函数,用函数实现各个命令,以后直接调用函数即可。
下面的程序是处理主机的标准控制请求的一个模板:
unsigned char ENDPOINT_A0_FIFO[8];
//判断输入的是SETUP请求,并将其读入缓冲区ENDPOINT_A0_FIFO
if((ENDPOINT_A0_FIFO[0] & 0b)==0x00)
if(ENDPOINT_A0_FIFO[1]&=0C)
(*StandardFunctionTable[ENDPOINT_A0_FIFO[1]])();
const void (*StandardFunctionTable[])(void)=
GetSatus,ClearFeature,USB_Reserved,SetFeature,
USB_Reserved,SetAddress,GetDescriptor,SetDescriptor,
GetConfiguration,SetConfiguration,GetInterface,
SetInterface,SynchFrame
USB设备在正常使用以前,必须由主机配置设备。主机一般会从USB设备获取配置信息后再确定此设备有哪些功能。
作为配置操作的一部分,主机会设备设备的配置值,如果必要的话会选择合适的接口备选设备。其初始化函数为:
void D12_int()
{ XmtBuff.pNum=16;
D12_COMMAND=0xf4;//读中断寄存器
ist=D12_DATA;
ist=D12_DATA;
if(ist & 0x01) //ENDP0_OUT
{XmtBuff.out=0;
XmtBuff.in=1;
D12_COMMAND=0x40; //读OUT最后状态
ist=D12_DATA;
if(ist & 0x20)//收到SETUP包
{ Setup_read();
Setup_control();
{ Setup_read();
else if(ist & 0x02)//ENDP0_IN
{ XmtBuff.in=1;
D12_COMMAND=0x41;//读in最后状态
ist=D12_DATA;
USB_submit();
else if(ist & 0x04)//ENDP1_OUT
{ XmtBuff.out=2;
XmtBuff.in=3;
D12_COMMAND=0x42;//读out最后状态
ist=D12_DATA;
read_out();
else if(ist & 0x08)//ENDP1_IN
{ XmtBuff.in=3;
D12_COMMAND=0x43;//读in最后状态
ist=D12_DATA;
XmtBuff.b[0]=5;
XmtBuff.wrLength=1;
XmtBuff.p=XmtBuff.b;
USB_submit();
在发出连接USB命令后,主机先读取设备描述符,然后发出设置USB地址SETUP包,设置USB地址后,进行主机客户驱动与设备初始化。其余端点(ENDPOINT)依此类推。
在其头文件里需定义USB规范中的各种描述符格式,包括设备描述表、配置描述表、接口描述表、端点描述表、字符串描述表以及描述表类型。这样,在发送配置[,接口(1),端点(1),接口(2),端点(2),…,类,厂商等]联合描述表时,主机USBD可以根据描述类型标识区分各种分描述表。
下面是固件程序的主循环部分:
#include&reg51.h&
//指向外部D12访问地址
#define D12_COMMAND(*(unsigned char xdata *)0xff01)
#define D12_DATA (*(unsigned char xdata *)0x7f02)
extern void D12_int();
sbit D12_suspend=P1^0;
sbit D12_int_n=P1^1;
sbit D12_eot_n=P1^2;
sbit D12_DMAck_n=P1^3;
sbit D12_DMAreq=P1^4;
void main(void)
D12_COMMAND=0xf3;
D12_DATA=0x06;//设置模式0
D12_DATA=0x03;//初始化频率12MHz
D12_COMMAND=0xd0;
D12_DATA=0x80;//设置地址0使能
D12_COMMAND=0xf3;//连接主机
D12_DATA=0x16;
{ if(!D12_int_n)
D12_int();
在编写USB的固件程序时,需要注意:
①单片机的中断应设置为电平触发;中断后一定要读上次传输状态寄存器(命令40~45H),以清除中断寄存器中的中断标志。这样,PDIUSBD12的中断输出才能变回高电平,这一点非常重要。
②在接收到Setup包后,一定要调用D8命令重新使能端口0。
③在向IN端写完数据后,一定调用命令FAH,指明缓冲区中的数据有效,可以发送到主机。
④读写数据后,一定调用命令F2H,以保证可以接收新的包。
⑤可以通过调用命令FDH,检查PDIUSBD12是否工作。该命令要读两个字节数据。
固件程序的编程是整个USB外设开发中非常重要的一环,它直接影响到设计开发的产品的数据传输速度。例如,采用不同的传输类型、设置不同的分组大小、是否采用DMA方式、传输缓冲区的大小等都会使得传输速率发生很大的变化。还有在高速情况下的超时处理等,也包含了很多的内容。
总之,在USB技术应用越来越广泛的今天,只有掌握了固件程序的编写,才可能开发出一个好的USB产品。
《采用PDIUSBD12的USB系统固件程序设计》一文由3edu教育网www.3edu.net摘录,版权归作者所有,转载请注明出处!
【温馨提示】3edu教育网所有资源完全免费,仅供学习和研究使用,版权和著作权归原作者所有,如损害了您的权益,请与站长联系修正。
上一篇论文: 下一篇论文:

我要回帖

更多关于 linux clear命令 的文章

 

随机推荐