当前位置:文档之家› HID设备报告描述符详解_划出重点

HID设备报告描述符详解_划出重点

HID设备报告描述符详解_划出重点
HID设备报告描述符详解_划出重点

USB/HID设备报告描述符详解

概述:

报告在这里意思是数据传输(data transfer),而报告描述符是对这些传输的数据作用途(usage)上的说明。

USB通讯协议的规范是以1ms产生一个USB帧(frame),USB设备可以每一个帧中发送和接收一个交换(transaction)。交换是由几个封包(packet)组成,而传输是由一个或几个交换来完成传送一口中有效的数据。在这里,传输和报告的意思相类似。传输方式有四种,初始学一般只要了解控制型传输(control transfer)和中断型传输(interrupt transfer)即可。控制型传输是当需要时才执行传输要求,是最一般的传输方式,组态、命令和状态的通讯都可以使用控制型传输;控制型传输主要用于消息型数据(message-type data)。中断型传输目的在做重复的数据更新(recurring data)传输,精确一点而言,即是在每个有限有周期内(bounded period)作至少一次的小量数据发送或接收;所以适用于流动型数据(stream-type data),注意这里所谓的周期时间就是在端点描述符中的轮询间隔时间。报告有三种:input,output,和Feature.后面将作进一步介绍。中断型输入管线(interrupt in pipe)仅可以传送input报告;中断型输出管线(interrupt out pipe)仅可以传送output报告;但是控制型管线(control pipe)可以传送input,out put和feature报告。端点描述符有声明所使用的端点为何种管线。

数据本身没有任何意义,要赋于用途才能明确其为控制什么(control);例如设备上的按钮指示灯和X与Y轴的位移等都通称控制,数据则为按钮和指示灯的开关状态或X与Y轴的位移量。为了这个目的应运而生报告描述符,其将数据的操控与它的用途作一对一的对应,所以解读报告后就可以知道每个数据作何种操作。所以“传输的数据”和“操作”只是一事件的两种描述方式。用途是以一个32位卷标(称作usage tag)来表示,高16位称作usage page(用途类页),低16位称为usage DI(用途识别名):

Usage(用途)=(usage page:usage ID)

举例说明:二个字节分别为x和y轴的位移数据,因此第一个字节的usage =(generic desktop:X),而第二个字节的usage = (generic desktop:Y),其中

generic desktop为用途的大类别(称作用途类页)之一,x和y轴的操作用途

属于此用途类页。文件universal serial Bus HID Usage Table完整列出所有的usage pages(用途类页)和usage ID(用途识别名),使用者必须遵照文件的规范来

声明操作的用途。该文件的附录A有十多个报告描述符的范例,值得研究下。

表1、报告描述符的标签

主项目全域项目区域项目标签代码标签代码标签代码Input X08?Usage Page0x0?Usage0x0?

Output0x9?Logical Minimum0x1?Usage Minimum0x1?

Feature0x0b?Logical

0x2?Usage Maximum0x2?

Maximum

0x3?Designator Minimum0x3?

Physical

Minimum

Collection0xa1Physical

0x4?Designator Minimum0x4?

Maximum

End

0xc0Unit Exponent0x5?Designator Maximum0x5? Collection

Unit0x6?String0x7?

Report Size0x7?Sreing Minimum0x8?

Report ID0x8?String Maximum0x9?

Report Coumt0x9?Delimiter0xa?

Push0xA?

Pop0xb?

标签:

用途卷标只是报告描述符诸多标签的一个。表1列出所有的卷标,利用这些

卷标取可以清楚完整的描述符操作的用途。报告描述符的语法不同于USB标准

描述符,它是以项目(items)方式排列而成,无一定的长度;项目有一个前辍(p refix),然后跟着一个括号,内为该项目的数据:item = prefix(data)。

项目分成三种类别:主项目,全局项目,区域项目。

主项目

主项目中的input,ouput,feature三个卷标用来表示报告中数据的种类,这些是报告描述符中最主要的项目,其他项目都是用来修饰这三种项目。主要项目中其他二个卷标后面再作详细的介绍。

●Input 项:表示设备操作输入到主机的数据模式。这个数据格式就形成一个输入报告,虽然输入报告可以用控制型管线以get report(input)来传输,但是通常用中断型输入管线来传输以确保在每一固定周期内都能将更新的输入

报告传给主机。

●Output项:表示由主机输出到装置操作的数据格式。这个数据格式就形成一个输出报告。输出报告通常不适用轮询的方式来传送给设备,而是由应用软件依实际需求以传令方式要求送出输出报告,所以大多用控制型管线以set repo rt(output)指令来将报告送到设备。当然也可以选择用中断型输出管线来传送,只是通常不建议这样用。

●Feature项:表示由主机送到设备的组态所需数据的数据格式。这个数据模式就形成一个特征报告。特征报告只能用控制型管线以get report(feature)和set report(feature)指令分别来取得和设定设备的特征值。

范例:考虑一个2X16字的显示装置,它的列数、行数、字宽、和字高为固定值属于feature报告;显示状态例如“就绪”和“输入字错误”则属于input

报告;光标位置和显示的字需可读写,所以属于另一个feature报告;更新显示的字则为output报告。为了区别两个features,要用到全局项目中的report ID,每个feature报告有一个不同的report ID,因而主机请求指令要加上report ID的值:get report(feature,report ID)和Set report(feature,report ID)。

主项目用来定义报告中数据的种类和格式,而说明主项目的意义和用途的为全局项目和区域项目(Local Item)。顾名思义,区域项目(Local Item)只能适用于列于其下的第一个主项目,不适用于其他主项目,若一个主项目之上有几个不

同的卷标的区域性项目,则这些区域性项目皆适用于描述该主项目。相反,全局性项目适用于其下方的所有主项目,除非另一个相同卷标的全局性项目出现。为了清楚说明报告描述符,将使用“项目状态表”(item state table)用来表示在某位址处适用的全局性项目的组合。图1显示全局性项目和区域性项目与所描述的主项目之对应关系。

区域性项目(Local Item)卷标:

简单地说,区域性项目(见表1)只是说明用途而已。Designator是要搭配实体描述符使用的,这里不对实体描述符进行介绍,所以略过这些designator标签。

标签Usage 实际上应该称作Usage ID,它搭配全域项目的Usage Page 卷标才形成前文所定义的用途{usage};但是报告描述符允许在区域项目的Usage 卷标直接用32位的方式来指定用途,这种方式称作扩充式用途指定法(extended usage)以示区别。例如:Usage(Generic Desktop:Mouse),Usage Minimum(Keyb oard:0),和Usage Maximum(Keyboard:101)。很明显的,扩充式用途指定法会取代『项目状态表』中的Usage Page。还有,使用扩充式用途指定法时,数据的高16 个位为用途类页Usage Page,低16 个位则为用途识别名Usage ID。往往一个报告数据会对应到几个操作,因而会有几个用途,例如101 按键的键盘利用不同代码代表不同的键,每一个键是一个操作,有自己的用途,要将所有Usage ID 列出不太现实,所以就需要Usage Minimum 和Usage Maximum二个标签。以键盘为例,主项目之上只要二个区域项目:Usage Minimum (0), Us age Maximum (101)。如此一来,则无键按下(Usage ID 为0)和101 键中任一键被按下(Usage ID 为1 至101)的用途都被赋于到一个报告数据上,后面会有一个范例进一步解说。

卷标String Index 类似卷标Usage,而卷标String Minimum 和String Ma ximum 则类似标签Usage Minimum 和Usage Maximum。如果希望某个操作对应到一个字串,则用String Index 来描述该操控的报告数据,这个字符串在字符串描述符中,StringIndex (data)项目中的data 是这个字符串在字符串描述符中的位置索引。如果需要用到几个字符串,则可以使用String Minimum 来指向

字符串描述符中被用到字符串的最先位置索引,和String Maximum 来指向最后位置索引。

标签Delimiter 很少用到,请参考Universal Serial Bus HID Usage Tables 文件中Appendix B 的范例详细说明。

全局项目卷标

全局项目的卷标事实上只要Usage Page,Logical Minimum,Logical Max imum,Report Size,Report ID,Report Count就足够了。表2 列了二个音量操作的例子(音量增减键和音量旋钮)将用来辅助说明这些卷标,不过主项目括号内的数据会在后文中再做说明。

表2、音量操作举例

音量减键音量旋钮

Usage Page(consumer) Usage Page(Consumer)

Usage(Volume) Usage(Volume)

Logical Minimum(-1) Logical Minimum(0)

Logical Maximum(1) Logical Maximum(100)

Report Size(2) Report Size(7)

Report Count(1) Report Count(1)

Input(Data,Variable,Relative) Input(Data,Variable,Absolute,No

Wrap,Linear,No Relative)

查阅Universal Serial Bus HID Usage Tables 文档,这两个例子的用途需要令为(Consumer: Volume)。Usage Page 前面已经介绍过了。Report Size 用来设定主项目(Input,Output,Feature)的报告字段大小,它的单位是位。主项目会对每个操作产生一个报告字段,字段大小则由Report Size 决定。而Report Count 用来设定主项目的报告字段的数目,其等于操作的数目。音量增减键的例子中ReportCount (1)表示主项目Input 只产生一个字段,所以可知只有一个音量增减键;而Report Size (2)表示这个字段为2 位。另一个音量旋钮例子也是只有一

个旋钮,所以用Report Count (1);但是因为Report Size (7),所以该旋钮的数据字段为7位,可以表示0到127之数值。再举一例,如果是鼠标的三个按键,每个按键占用一个一位的字段,则Report Size (1), Report Count (3);那么这个报告长度为三个位,可以同时呈现出三个按键的状态(原状或被按下)。

Logical Minimum 和Logical Maximum在说明每个报告字段的数值范围,这是纯数值所以称s为逻辑数值(logical value)。音量增减键的例子中Logical M inimum (-1),Logical Maximum (1)表示只会出现-1, 0, 1 三种数值,所以用到二位(即ReportSize(2)),0b11 代表-1,0b00 代表0,0b01 代表1。在音量旋钮例子中,虽然用7 位作一字段,但是旋钮仅会产生0 到100 的数值,因为Log ical Minimum (0)和Logical Maximum (100)。假如实体程序错误产生超出逻辑数值的范围,则主机将会忽略该数值,这种数值称作null value。

当要将同一种报告分成数个部分,则每一个部分要给予一个识别值,这时就需用到卷标Report ID,其数据值必须从1起算,不可使用0。没有赋予Report ID 标签的报告,主机有可能会将其Report ID 视为0,所以Report ID (0)被要求不能使用。这个标签对控制型管线才有意义,因为它可以在请求报告时指定R eport ID的值。对于中断型管线,其为周期性传输报告,所以每次都会将所属报告传完,没有仅传输部分之必要,所以Report ID 标签就无意义。

其它的全局项目卷标可分为辅助工具(Push 和Pop)和物理量说明(Physic al Minimum,Physical Maximum,Unit Exponent,和Unit)。Push 卷标将『项目状态表』存放到缓存器(stack),而Pop 卷标反过来将缓存器最顶层的『项目状态表』取回来取代目前之状态表。这二个标签对很长的报告描述符才有用处,因为其可以节省多列一些全局项目。读者当要使用到时,参考Universal Serial Bu s HIDUsage Tables 文件的Appendix A.7 节中范例则可获得正确使用方式。

不同厂家的鼠标有不同的分辨率,若要让主机知道鼠标的分辨率,就必须用到物理量的标签。不使用也不会影响到鼠标的功能,只是使用者无法由主机的驱动程式得知分辨率而已。但是量测装置(例如温度计)的应用程序必须知道物理量,则这些标签就必备了。分辨率r 的算法如下

r = ((lM-lm)/(PM-Pm))X10i Unit

其中l m = Logical Minimum ,l M = Logical Maximum , p m = Physical Minimum ,p M = Physical Maximum , i = Unit Exponent 。以400-dpi 的鼠标为例如表3。 表3:解析度的范例 Logical Minimum(-127) R = ((127-(-127))/(3175-(-3175))X10-4 = 400counts per inch

Logical Minimum(127) Physical Minimum(-3175) Physical Minimum(3175) 给定Logical 值,计算出physical 值: ((PM-Pm )/2)

/10i =((127-(-127))/400)/2=0.3173 |PM|=|Pm|=3175,i=4

Unit Exponent(-4) Unit(inch)

注意,若是Unit Exponent 未定义,则视为i = 0;若是Physical Minimum 和Physical Maximum 有一个以上未定义,则视为P M =l M 和p m =l m 。所以标签Ph ysical Minimum 和Physical Maximum 一定要同时定义,否则无意义。这些卷标的括号内数字为有符号的整数,可以是一个字节或二至四个字节,字节数目会在卷标代码的最低二位定义,详情后文会叙述。卷标Unit 的括号内数据比较复杂,总共用了7 个四位(nibbles)来描述,各个四位之意义如表4,其中第8 个四位 未被使用到。

表4:标签Unit 的信息格式 Nibbe 7 6 5

4

3

2

1

Luminous Intensity

Current Temperature Time Mass Length System

HID 共享了四种单位系统,最低的四位就是决定使用的单位系统(System),不同的系统中当然物理量的单位也不一样。单位和系统间的对应关系如表5。

表5:物理量的单位之编码法 None SI Linear SI Rotation English Linear English Rotation System 0x0 0x1 0x2 0x3 0x4 Length

None

公分

径度

英寸

角度

Mass None 公克公克Slug Slug Time None 秒秒秒秒

Temperature None 凯氏(绝对

温度)

凯氏(绝对

温度)

华氏华氏

Current None 安培安培安培安培Luminous

intensity

None Candela Candela Candela Candela 除了最低四位的值用来选择单位系统外,其余每个四位皆表示该单位的幂次方,每个四位(nibble)都是有符号的整数,可表示的范围为-8 至+7:

-8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7

08 h 09

h

0a

h

0b

h

0c

h

0d

h

0e

h

0f

h

00

h

01

h

02

h

03

h

04

h

05

h

06

h

07

h

因此长度的单位若为公分则Unit (data)中data 的码为0x11,若为英吋则为0x13,这二者中Length 的四位值皆为1 表示幕次方为1,即cm1 或in1 。质量单位为公克之码为0x0101,加速度单位为公分除以平方秒之码为0xE011,其中E 代表-2。所以力量单位为质量(公克)乘于加速度(公分/平方秒)的码为0xE111。能量单位焦尔为力量乘于长度之码为0xE121,其等义于s?2g cm2 和单位系统为SI Linear。

主项目

主项目中产生报告数据格式的三个卷标(Input,Output,和Feature)具有共通的数据定义,这些数据和其代码列于表6中。目前用到9个位来表示这些数据。如果第九位(bit 8)为0,则仅需用一个字节来表示该数据,即忽略第九位。如果第九位为1,就需用到二个字节来表示该数据。

表6:主项目的信息代码

Bi

t

8 7 6 5 4 3 2 1 0

Bit

Field

Non

Volati

le

No

Null

Positi

Prefer

red

State

Line

ar

No

Wra

p

Absolu

te

Array Data

on

1 Buffer

ed

Bytes

Volati

le

Null

State

No

Prefer

red

Non

Line

ar

Wra

p

Relati

ve

Variab

le

Consta

nt Data/Constant:主项目的数据为可变值(设为Data),或为固定不可变值(设

为Constant)。Constant 都用于Feature 的报告,或是用于填充位(padding),使报告长度以字节为单位。

Array/Variable:主项目之数据的每个字段可以表示几个不同的操作的其中一个被触发(设为Array),或是每个字段仅表示一个操作(设为Variable)。如果是Variable,则Report Count 的数据值等于报告数据的字段数。若是Array,则Report Count 的数据值表示可以同时被触发的最多操作数目。后文中键盘之例会解说Array 的用法。

Absolute/Relative:主项目的数据是以相对于固定的基准点方式提供绝对数值(设为Absolute),或是提供相对于前次报告的相对值(设为Relative)。

【范例说明】前文中的音量操控范例,因为都是Data 和Variable,二者的操作值皆为变化值,且一个字段仅表示一个操作。但是音量增减键的例子为Rel ative,所以若报告值由0 变成+1,则音量增大一个刻度,反之由0 变作-1 则音量减小一个刻度,因而音量大小因输入值而作相对的变化。然而音量旋钮的例子为Absolute,当输入值为最小值0 时,为静音,而输入值为最大值100 时,为最大音量,其余值作百分比的音量调整,输入值和音量成绝对关系。

No Wrap/Wrap:主项目的数据值达到极值后会转为极低值,反之亦同,称作卷绕(设为Wrap)。例如一个转钮可以做360°旋转,输出值从0 至10,若设定为Wrap,则值达10 后,在同方向旋转则值变为0,反之若达到0,再转就得到10。

Linear/Nonlinear:主项目的数据与操作刻度为线性关系(设为Linear),或为非线性(设为Nonlinear)。

Preferred State/No Preferred:主项目对应的操作再不被触发时会自动恢复到初始状态(设为Preferred State),或是不会恢复原状(设为No Preferred)。例如键盘的按键和会自动置中(self-centering)的游戏杆,皆为Preferred State。

【范例说明】再以音量操作为例,音量增减键的例子都没标注No Wrap,L inear,Preferred State,但是没有标注即认定其属于默认值,所以等同于是这些设定,只是这些设定对此例的操作无意义,所以不标出。音量旋钮的例子明确指出其为No Wrap,Linear,No Preferred,可见旋钮不是循环旋转,输出值与旋转角呈线性关系,旋钮释放开时会停留在释放前位置(因为No Preferred)。

No Null Position/Null State:主项目对应的操和有一个状态,其不会送出有意义的数据,即数据将不在Logical Minimum 和Logical Maximum 之间,这种操控要标注Null State,否则为No Null Position。例如几个按键,而无键被按下的用途没有声明在Usage 之列,则可以在主项目的数据中设Null State,将无键被按下的状态排除在Logical Minimum 和Logical Maximum区间之外,进一步请参看Universal Serial Bus HID Usage Tables 文件的Appendix A.3 节中范例。

Non Volatile/Volatile:主项目Feature 的数据不允许被主机改变(设为Non Volatile),或是允许被主机改变(设为Volatile)。注意主项目Input 和Outpu t,此标注设定无意义,所以bit 7 的代码必须为0。

Bit Field/Buffered Bytes:主项目的数据格式要以字节为单位,不足构成字节时自动填充成字节则设Buffered Bytes。

Collection 和End Collection

最后来谈谈主项目的其它2个卷标:Collection 和End Collection。以鼠标而言,在实体上是一个指针(pointer),只是应用为计算机鼠标;而这个指针含有三个按键和二个平移轴X 和Y。所以指针的报告是由不同格式的数据所构成,因而需要用到Collection 和End Collection 将几个Input 项目集结成一组,其用途为指针,再用Collection 和End Collection 将指针括起来说明其应用为鼠标。

卷标End Collection 没有跟随任何资料。但是卷标Collection 跟随一个字节的数据,例如指针的数据名为Physical,而鼠标的为Application。所有Collectio n的数据名称与代码如表7:

表7:报告集合的名称与代码

Physica

l Applicatio

n

Logica

l

Repor

t

Named

Arrar

y

Usage

Modifie

r

Usage

Switc

h

Reserved

Vendor-defin

ed

码0x000x010x020x030x040x050x06

0x07-0x7

f

0x80-0xff

CP CA CL Nary US UM

Collection 的数据名称很难有一个准则来给定,Universal Serial Bus HID

Usage Tables文档中将各种用途的用途种类(usage type)列出,使用者必须依据

用途种类来指定Collection 的数据名称,例如鼠标,键盘和游戏杆的用途种类

为CA,所以要用Collection (Application),而指针为CP,所以用Collection (P hysical)。

编码

报告描述符的项目编码有二种:短项目和长项目。长项目仅是保留给未来使

用,所以不作介绍。短项目的编码形式如下:

Bits 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3

2 1 0

[data] [data] bTag bType bSize Bytes 2 1 0

最低字节分别标注项目大小(bSize),项目类别(bType),和项目卷标(bTag);

其中bTag 占4个位,其余二者各占2个位。BSize 用来指出项目的数据所

需字节的数目,该数目仅可以为0(当bSize=0),1(当bSize=1),2(当bSi

ze=2),和4(当bSize=3);注意不可以为3个字节。大部分的卷标仅需一个

字节的数据;全局项目的卷标Unit 比较特殊有可能最多用到4 个字节来表示其资料。

标签代码bTag 已经于前章的表1 中描述,例如Input 的标签代码『0x8?』中8即为bTag 之值;再如标签Feature 之bTag=11,而Unit 之bTag=6。主项目之bType=0,全局项目之bType=1,而区域项目之bType= 2。所以在前章的表1

中的主项目卷标代码中的『?』可以改为『00nnB』,全局项目的可以改为『01n nB』,而区域项目的可以改为『10nnB』,其中nn 代表bSize。

实际范例

这里举一个Device Class Definition for Human Interface Device 文件的附录E 中的整合鼠标的键盘装置的范例。这个装置只有一个组态描述符,但是这个组态具有二个接口,一个为键盘接口(接口编号为0x00),另一个为鼠标接口(接口编号为0x01)。每一个接口都有一个自己的中断型输入端点,输出则都靠内定的控制型端点0。这个整合鼠标的键盘装置的标准描述符,请参考附件中的『U SB 标准描述符之技巧』文件。在该文中所使用的范例即为整合鼠标的键盘装置,只是仅列出一个接口描述符(即编号为0x00 的键盘接口),另一个编号为0x0 1 的鼠标接口在该文中没有列出,读者可以自行参考本文所附的描述符程序代码descriptor.asm(即在标记为interface_descriptor01,hid_descriptor01,和endpoint _descriptor01 处)。

表8:范例的输入报告格式

键盘(输入报告)鼠标(输入报告)

Byte 7 6 5 4 3 2 1 0 Byte 7 6 5 4 3 2 1 0

0 Modifier keys 0 Pad Buttons

1 Reserved 1 X displacement

2 Keycode 1 2 Y displacement

3 Keycode 2

4 Keycode 3

5 Keycode 4

6 Keycode 5

7 Keycode 6

表9:范例的输出报告格式

键盘输出报告

Byte 7 6 5 4 3 2 1 0

0 Pad LED’s

这个范例有输入报告和输出报告,其中输入报告有二组,一组属于键盘接口,另一组属于鼠标接口。表8 列出输入报告的数据格式。而输出报告只有键盘接口需要,表9 为输出报告的数据格式。因为有二个接口,所以有二个报告描述符,分属于不同的界面,二个报告描述元都列于表10 中。键盘的报告描述元中整个报告集合的用途为(Generic Desktop: Keyboard),由于键盘用途属于应用性,所以标签Collection 的资料名为Application。由于单独键本身的用途类页不再是Generic Destop,而是Keyboard(注意Keyboard 也可为用途类页),所以在项目Collection(Application)下重新声明用途页Usage Page (Keyboard)。根据Unive rsal Serial Bus HID Usage Tables 文件,鼠标是指针的一种,只是应用为计算机的鼠标,所以报告的内层集合的用途为(Generic Desktop: Pointer),外层的应用性集合的用途为(Generic Desktop: Mouse)。注意鼠标的按钮和位移轴又分属不同的用途类页,所以在内层集合中还要重新声明用途类页。按钮的用途类业为Buttons,而二个位移轴(X、Y)所属的用途类业为Generic Desktop。

表10:报告描述符范例

键盘鼠标

项目编码项目编码

Usage Page (Generic

Desktop),0x0105

Usage Page (Generic

Desktop),

0x0105

Usage (Keyboard),0x0609Usage (Mouse),0x0209 Collection (Application),0x01A1Collection (Application),0x01A1 Usage Page (Keyboard),0x0705Usage (Pointer),0x0109 Usage Minimum (224),0xE019Collection (Physical),0x00A1 Usage Maximum (231),0xE729Usage Page (Buttons),0x0905

Logical Minimum (0),0x0015Usage Minimum (1),0x0119 Logical Maximum (1),0x0125Usage Maximum (3),0x0329 Report Size (1),0x0175Logical Minimum (0),0x0015 Report Count (8),0x0895Logical Maximum (1),0x0125 Input (Data, Variable,

Absolute),

0x0281Report Size (1),0x0175 Report Size (8),0x0875Report Count (3),0x0395

Report Count (1),0x0195Input (Data, Variable,

bsolute),

0x0281

Input (Constant),0x0181Report Size (5),0x0575 Usage Minimum (0),0x0019Report Count (1),0x0195 Usage Maximum (101),0x6529Input (Constant),0x0181

Logical Minimum (0),0x0015Usage Page (Generic

Desktop),

0x0105

Logical Maximum (101),0x6525Usage (X),0x3009 Report Size (8),0x0875Usage (Y),0x3109 Report Count (6),0x0695Logical Minimum (-127),0x8115 Input (Data, Array),0x0081Logical Maximum (127),0x7F25 Usage Page (LEDs),0x0805Report Size (8),0x0875 Usage Minimum (1),0x0119Report Count (2),0x0295 Usage Maximum (5),0x0529Input (Data, Var, rel),0x0681 Logical Minimum (0),0x0015End Collection,0xC0 Logical Maximum (1),0x0125End Collection0xC0 Report Size (1),0x0175

Report Count (5),0x0595

Output (Data,

Variable,Absolute),

0x0291

Report Size (3),0x0375

Report Count (1),0x0195

Output (Constant),0x0191

End Collection0xC0

从表8 看出,键盘的输入报告中最低的8位分别代表键盘上的8个修饰键(亦即左和右边的Control 键、Shift 键、Alt 键、和Windows 键),平常每位的值为0,当对应的修饰键被压下时则位值为1。键盘报告描述符中第一个Inpu t 项目必须声明这8位的格式。这8个修饰键为用途类页Key Codes 中的第22 4 个键到第231 键,所以用Usage Minimum (224)和Usage Maximum (231)来声明。每一个按键的逻辑值不是0 就是1,所以用Logical Minimum(0)和Logic al Maximum (1)来声明。很显然的,每一个键占用一个数据位,而共需8个位,因此ReportSize ( 1),而Report Count (8)。请特别注意,最低位对应到Usage Minimum 的声明,而最高位所对应的为Usage Maximum 的数据内容。这8 个位值是可变的数据,每一个位是独立的变量,提供的值不须与前次的值有相对关系。总结而言,该8位的主项目必须为Input (Data, Variable, Absolute)。

键盘的输入报告中次高的字节被保留,该字节的值无意义,也不需更新,所以用Input (Constant)来填充(padding)。而最高的6 个字节则是最近同时被压下的6 个按键之代码。这个键盘装置有101 个键,而报告格式的最高的6 个位组中任何一个字节都可以代表101 个键之任一键,所以这101 键再加上无键被压下状态(代码为0x00)构成一组操作数组,这个装置允许同时压下6个键。

键盘报告描述符中Input (Data, Array)即在声明这6个字节的数据格式,注意这个数据格式的逻辑值声明和用途代码声明具有相同的数据值(即0 和101)。

键盘有一个输出报告,长度为1个字节,但是只用到最低5个位来代表五个LED 的操控,所以最高的3个位需要用Output (Constant)项目来填充。输出报告的用途类页不再是Key Codes,而是Page of LEDs,所以要重新声明Usage Page,而主项目为Output (Data, Variable, Absolute)。这个项目的数据内容如同输入报告的最低8位所声明的主项目之数据内容,不再作说明。因为键盘接口的端点描述符只有声明一个中断型输入端点,所以输出报告需要依赖内定控制型端

点0来传送。输入报告由声明的输入端点作中断型输入传输,当然也可以依需要用内定控制型端点0来作控制型读入传输。

鼠标的报告描述符的输入数据格式中最低的一个字节只有最低3个位有意义,其分别对应到鼠标上的三个按钮,用途类页为Buttons。其它二个字节的用途为(Generic Desktop: X)和(Generic Desktop: X),分别对应到鼠标X 轴和Y 轴的位移操控。这二个位移值得逻辑范围为-127 到127,即一个字节可以表示最大范围。位移的数值是相对值,所以主项目为Input (Data, Variable, Relative)。

HID 描述符编辑工具

USB 协会提供了一个HID 描述符编辑工具称作HID Descriptor Tool,其执行程序为DT.exe。这个工具软件可以在USB 网站上取得。虽然称作HID 描述符工具,事实上,仅提供编撰报告描述符之用。执行DT.exe 后会出现如图2

之窗口,小内窗口HID Items 列出所有报告描述符的标签。以前面所举的实际范例中键盘的报告描述符为例,首先点选[USAGE_PAGE],后会出现一个次窗口列出所有的Usage Page 的选项,这个例子要选[Generic Desktop],按[OK]后则次窗口消失,DT 的主窗口中的右边小内窗口Report Descriptor 就出现Usage Page(Generic Desktop)并跟随着该项目的编码05 01(低字节在左边),也就是这个工具可以帮助作自动编码的工作。程序员只要输入项目的卷标和内容,则可以由这个工具软件提供报告描述符的程序代码。接着,当点选第二个项目[USA GE]时,DT 软件会根据前面的编签Usage Page 的内容Generic Desktop,而产生一个次窗口列出Generic Desktop 包含的所有Usage 选项。同样道理,当选完Usage Page

(Keyboard),再要编撰Usage Minimum 和Usage Maximum 时,所出现的次窗口则为Usage Page (Keyboard)所包含的全部Usage 选项,选第224 个为Left Control键当用途范围的最小者,再选第231 个为Right GUI 键当用途范围的最大者。其他项目的编撰以此类推。

在主窗口下,点选下拉选项[File]中的[Info],则会出现讯息窗口,告知编撰的描述符中项目的个数和描述符长度所需字节的数目。编撰报告描述符完成后,

还要做语法检验,这时点选下拉选项[Parse Descriptor],则DT 软件会告知检查的结果,并提供错误原因与更改的建议。

总结

最后一个问题是如何将报告描述符加入微控器的汇编程序。对于任何一种描述符,都是以汇编语言中的一个标记来分辨,例如第一个接口的报告描述符的标记就称作hid_report_descriptor00;同样的,第二个界面的就称作hid_report_desc riptor01。记得在报告描述符结束处也加上一个标记,如end_hid_report_descripto r00 和end_ hid_report_descriptor01。这个结束标记除了有助于阅读程序外,其最主要的用处是可以用来计算描述符的长度(即字节数)。例如使用dwl end_ hid_report_descriptor00 - hid_report_descriptor00组译器就会自动算出第一个报告描述符的长度,这个长度以二个字节来记载。“dwl”为汇编语言的指示,在于储存二个字节的数据,储存的方式为little Endian。所谓little Endian 方法,就是将低字节的值存于低地址值的内存空间,高字节之值存于高地址值处。

附件:USB 标准描述符之技巧.rar descriptor.asm

HID 报告描述符终极解析

USB HID Report终极解析 HID的报告描述符巨难懂,关键是数据格式与每一位代表的意思。经过三天的研究,终于将HID Report的每一个数据位的含义弄清楚了,现将数据解析如下,最后附上了一个HID 通信的Report例子。以一个键盘的HID Report为例: 键盘的HID报告描述符: code char KeyBoardReportDescriptor[63] = { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x06, // USAGE (Keyboard) 0xa1, 0x01, // COLLECTION (Application) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x08, // REPORT_COUNT (8) 0x81, 0x02, // INPUT (Data,V ar,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,V ar,Abs) 0x95, 0x05, // REPORT_COUNT (5) 0x75, 0x01, // REPORT_SIZE (1) 0x05, 0x08, // USAGE_PAGE (LEDs) 0x19, 0x01, // USAGE_MINIMUM (Num Lock) 0x29, 0x05, // USAGE_MAXIMUM (Kana) 0x91, 0x02, // OUTPUT (Data,V ar,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x03, // REPORT_SIZE (3) 0x91, 0x03, // OUTPUT (Cnst,V ar,Abs) 0x95, 0x06, // REPORT_COUNT (6) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0xFF, // LOGICAL_MAXIMUM (255) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 0x81, 0x00, // INPUT (Data,Ary,Abs)

MDL(内存描述符表) 详解

MDL(内存描述符表)详解 分类:初学驱动2013-01-25 18:07 308人阅读评论(0) 收藏举报mdl 以下的虚拟内存可以理解成逻辑内存,因为我觉得只有这样才能讲通下面所有的东西。以下的“未分页”指没有为页进行编码。 以下为MDL结构体(我很郁闷,我在MSDN上没有找到这个结构体) typedef struct _MDL { struct _MDL *Next; //下一个MDL CSHORT Size; //大小 CSHORT MdlFlags; //标志,保护属性等 struct _EPROCESS *Process;// PVOID MappedSystemVa; PVOID StartVa; ULONG ByteCount; ULONG ByteOffset; } MDL, *PMDL; 如何使用MDL: 一个连续的虚拟内存地址范围可能是由多个分布(spread over)在不相邻的物理页所组成的。系统使用MDL(内存描述符表)结构体来表明虚拟内存缓冲区的物理页面布局。我们应该避免直接访问MDL。我们可以使用MS-Windows提供的宏,他们提供了对这个结构体基本的访问。 ·MmGetMdlVirtualAddress 获取缓冲区的虚拟内存地址 ·MmGetMdlByteCount 获取缓冲区的大小(字节数) ·MmGetMdlByteOffset 获取缓冲区开端的物理页的大小(字节数)·MmGetMdlPfnArray 获取记录物理页码的一个数组指针。 我们可以用IoAllocateMdl函数来分配一个MDL。如果要取消分配,可是使用IoFreeMdl 函数。或者,可以使用MmInitializeMdl来把一个之前定义的缓冲区定制成一个MDL。但是以上两种方式都不能初始化物理页码数组。 对于在未分页池中分配的缓冲区,可以用MmBuidlMdlForNonpagedPool函数来初始化页码数组。对于可分页的内存,虚拟内存和物理内存之间的联系是暂时的,所以MDL的页码数组只在特定的环境和时间段有效,因为很可能其他的程序对它们进行重新分配,为了使其

USB HID设备报告描述符详解

USB HID设备报告描述符详解 概述: 报告在这里意思是数据传输(data transfer),而报告描述符是对这些传输的数据作用途(usage)上的说明。 USB通讯协议的规范是以1ms产生一个USB帧(frame),USB设备可以每一个帧中发送和接收一个交换(transaction)。交换是由几个封包(packet)组成,而传输是由一个或几个交换来完成传送一口中有效的数据。在这里,传输和报告的意思相类似。传输方式有四种,初始学一般只要了解控制型传输(control transfer)和中断型传输(interrupt transfer)即可。控制型传输是当需要时才执行传输要求,是最一般的传输方式,组态、命令和状态的通讯都可以使用控制型传输;控制型传输主要用于消息型数据(message-type data)。中断型传输目的在做重复的数据更新(recurring data)传输,精确一点而言,即是在每个有限有周期内(bounded period)作至少一次的小量数据发送或接收;所以适用于流动型数据(stream-type data),注意这里所谓的周期时间就是在端点描述符中的轮询间隔时间。报告有三种:input,output,和Feature.后面将作进一步介绍。中断型输入管线(interrupt in pipe)仅可以传送input报告;中断型输出管线(interrupt out pipe)仅可以传送output报告;但是控制型管线(control pipe)可以传送input,out put和feature报告。端点描述符有声明所使用的端点为何种管线。 数据本身没有任何意义,要赋于用途才能明确其为控制什么(control);例如设备上的按钮指示灯和X与Y轴的位移等都通称控制,数据则为按钮和指示灯的开关状态或X与Y轴的位移量。为了这个目的应运而生报告描述符,其将数据的操控与它的用途作一对一的对应,所以解读报告后就可以知道每个数据作何种操作。所以“传输的数据”和“操作”只是一事件的两种描述方式。用途是以一个32位卷标(称作usage tag)来表示,高16位称作usage page(用途类页),低16位称为usage DI(用途识别名): Usage = (usage page:usage ID) 举例说明:二个字节分别为x和y轴的位移数据,因此第一个字节的usage =(generic desktop:X),而第二个字节的usage = (generic desktop:Y),其中gen

USB HID报告描述符详解

USB 之人性化接口装置的报告描述元(1) 作者: 林锡宽 e-mail: sklin@https://www.doczj.com/doc/7b3183958.html,.tw (原文刊于e 科技杂志vol. 30,2003 年6 月号) 关于USB 的标准描述元已经在 e 科技杂志的第24 和25 期中作了完整的介绍。有些读者来函希望能早日刊出报告描述元的介绍。人性化接口装置HID 的类别 特定描述元有三种,其中HID 描述元因为需要连接在接口描述元(标准描述元 之一)之后,所以也已经在前文介绍了。其他二个HID 类别特定描述元为报告 描述元和实体描述元。实体描述元几乎很少使用到,所以不拟介绍,虽然它不会 很复杂。本文仅专注介绍报告描述元。相对来说,报告描述元最复杂,也不容易 理解,可是却最重要,因为HID 装置与主机间的经常性数据传输都由报告描述 元来规范。因为报告描述元的复杂和难理解,使得此文的编撰花了不少时间,因 此无法在上次刊完USB 标准描述元后,接着刊出。 由于内容篇幅颇长,所以仅能分为三篇陆续刊出。本期的第一篇中仅介绍到区域 性项目,下期的第二篇再继续介绍全局性项目和主项目。这三类项目构成一个报 告描述元。最后仍需要以一个实际的范例来解说使用方法,所以第三篇文章将提 供一个实际的范例:整合鼠标的键盘装置。此外,也会将该范例的韧体程序代码提 供给有兴趣的读者。这个韧体程序代码不只是该范例的报告描述元,也含括了它的 标准描述元。 概述 报告(report)在这里意指数据传输(data transfer),而报告描述元则是对这些传输的 数据作用途(usage)的说明。 USB 通讯协议的规范是以1 毫秒产生一个USB 讯框(frame),USB 装置可以在每 一个讯框中传送和接收一个交易(transaction)。交易是由数个封包(packet)组成, 而传输是由一或数个交易来完成传递一串有意义的数据。在这里,传输和报告的 意义大同小异。传输方式有四种,初学者只要了解控制型传输(control transfer) 和中断型传输(interrupt transfer)即可。控制型传输是当需要时才执行传输要求, 是最一般的传输,组态、命令和状态的通讯都可以使用,主要用于讯息型数据(message-type data)。中断型传输目的在做重复的数据更新(recurring data)传输, 精确一点而言,即是在每个有限的周期内(bounded period)作至少一次的小量数据 传送或接收﹔所以适用于流动型数据(stream-type data),注意这里所谓的周期时

USB的描述符详解总结

USB的描述符与命令请求详解 一、描述符 1.什么是描述符 所谓描述符,就是用于描述设备特性的具有特定格式排列的一种数据组织结构。 2.描述符的作用 描述符的作用在于设备向主机汇报自己的信息、特征,主机根据这些信息从而加载相应的驱动程序。 3.描述符的分类 描述符分为三大类:标准描述符、设备类描述符、厂商描述符。 除字符串描述符可选外,任何设备都必须包含剩下的几种标准描述符。 在USB1.0中规定了5种标准的描述符: 设备描述符 配置描述符 接口描述符 端点描述符 字符串描述符 规定的设备类描述符有:集线器类描述符、人机接口类描述符。 下表是三种描述符的类型值: 4.使用的几种类 设备类DeviceClass 下表是设备类值的含义。

接口类InterfaceClass 下表是接口类值的含义。 类的交叉与独享 在描述符中,只有设备描述符和接口描述符中会有类别之分,即只有设备和接口会分 类使用,不过有些类别的使用只需经过设备或接口的区分就可彻底清楚明白,这说明在设备类别和接口类别的定义上会有共同的类别名称。而有些类别则是设备或接口独享的,下表是与使用设备相关的类别划分交叉或共享情况:

(此表也适用于标准命令Get_Descriptor中wValue域高字节的取值含义) 【说明:】在设备或接口分类上均可彻底分清使用的(Usage = Both),即在任一处描述符中定义即可的分清楚使用的类(Usage = Both)的基本类有: 02h ------------- 通信及CDC控制类; DCh ------------ 诊断设备类; EFh ------------- 混杂设备类; FFh ------------- 厂商定义的设备类。 5.标准描述符 设备描述符

USB_HID设备报告描述符详解

概述 报告在这里意思是数据传输(data transfer),而报告描述符是对这些传输的数据作用途(usage)上的说明。USB通讯协议的规范是以1ms产生一个USB 帧(frame),USB设备可以每一个帧中发送和接收一个交换(transaction)。交换是由几个封包(packet)组成,而传输是由一个或几个交换来完成传送一口中有效的数据。在这里,传输和报告的意思相类似。传输方式有四种,初始学一般只要了解控制型传输(control transfer)和中断型传输(interrupt transfer)即可。控制型传输是当需要时才执行传输要求,是最一般的传输方式,组态、命令和状态的通讯都可以使用控制型传输;控制型传输主要用于消息型数据(message-type data)。中断型传输目的在做重复的数据更新(recurring data)传输,精确一点而言,即是在每个有限有周期内(bounded period)作至少一次的小量数据发送或接收;所以适用于流动型数据(stream-type data),注意这里所谓的周期时间就是在端点描述符中的轮询间隔时间。报告有三种: input,output,和Feature.后面将作进一步介绍。中断型输入管线(interrupt in pipe)仅可以传送input报告;中断型输出管线(interrupt out pipe)仅可以传送output报告;但是控制型管线(control pipe)可以传送input,output和feature报告。端点描述符有声明所使用的端点为何种管线。 数据本身没有任何意义,要赋于用途才能明确其为控制什么(control);例如设备上的按钮指示灯和X与Y轴的位移等都通称控制,数据则为按钮和指示灯的开关状态或X与Y轴的位移量。为了这个目的应运而生报告描述符,其将数据的操控与它的用途作一对一的对应,所以解读报告后就可以知道每个数据作何种操作。所以“传输的数据”和“操作”只是一事件的两种描述方式。用途是以一个32位卷标(称作usage tag)来表示,高16位称作usage page(用途类页),低16位称为usage DI(用途识别名): Usage=(usage page:usage ID) 主项目全域项目区域项目 标签代码标签代码标签代码Input0X8?Usage Page0x0?Usage0x0? 0x1? Output0x9?Logical Minimum0x1?Usage Minimum 0x2? Feature0xb?Logical Maximum0x2?Usage Maximum Physical Minimum0x3?Designator0x3?

socket原理详解

socket原理详解 1、什么是socket 我们知道进程通信的方法有管道、命名管道、信号、消息队列、共享内存、信号量,这些方法都要求通信的两个进程位于同一个主机。但是如果通信双方不在同一个主机又该如何进行通信呢?在计算机网络中我们就学过了tcp/ip协议族,其实使用tcp/ip协议族就能达到我们想要的效果,如下图(图片来源于《tcp/ip协议详解卷一》第一章1.3) 、 图一各协议所处层次 当然,这样做固然是可以的,但是,当我们使用不同的协议进行通信时就得使用不同的接口,还得处理不同协议的各种细节,这就增加了开发的难度,软件也不易于扩展。于是UNIX BSD就发明了socket这种东西,socket屏蔽了各个协议的通信细节,使得程序员无需关注协议本身,直接使用socket提供的接口来进行互联的不同主机间的进程的通信。这就好比操作系统给我们提供了使用底层硬件功能的系统调用,通过系统调用我们可以方便的使用磁盘(文件操作),使用内存,而无需自己去进行磁盘读写,内存管理。socket其实也是一样的东西,就是提供了tcp/ip

协议的抽象,对外提供了一套接口,同过这个接口就可以统一、方便的使用tcp/ip协议的功能了。百说不如一图,看下面这个图就能明白了。 图二 socket所处层次 那么,在BSD UNIX又是如何实现这层抽象的呢?我们知道unix中万物皆文件,没错,bsd在实现上把socket设计成一种文件,然后通过虚拟文件系统的操作接口就可以访问socket,而访问socket时会调用相应的驱动程序,从而也就是使用底层协议进行通信。(vsf也就是unix提供给我们的面向对象编程,如果底层设备是磁盘,就对磁盘读写,如果底层设备是socket就使用底层协议在网中进行通信,而对外的接口都是一致的)。下面再看一下socket的结构是怎样的(图片来源于《tcp/ip协议详解卷二》章节一,1.8描述符),注意:这里的socket是一个实例化之后的socket,也就是说是一个具体的通信过程中的socket,不是指抽象的socket结构,下文还会进行解释。

SIFT算法C语言逐步实现详解

SIFT算法C语言逐步实现详解(上) 引言: 在我写的关于sift算法的前倆篇文章里头,已经对sift算法有了初步的介绍:九、图像特征提取与匹配之SIFT算法,而后在:九(续)、sift算法的编译与实现里,我也简单记录下了如何利用opencv,gsl等库编译运行sift程序。 但据一朋友表示,是否能用c语言实现sift算法,同时,尽量不用到opencv,gsl等第三方库之类的东西。而且,Rob Hess维护的sift 库,也不好懂,有的人根本搞不懂是怎么一回事。 那么本文,就教你如何利用c语言一步一步实现sift算法,同时,你也就能真正明白sift算法到底是怎么一回事了。 ok,先看一下,本程序最终运行的效果图,sift 算法分为五个步骤(下文详述),对应以下第二--第六幅图:

sift算法的步骤 要实现一个算法,首先要完全理解这个算法的原理或思想。咱们先来简单了解下,什么叫sift算法: sift,尺度不变特征转换,是一种电脑视觉的算法用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量,此算法由David Lowe 在1999年所发表,2004年完善总结。 所谓,Sift算法就是用不同尺度(标准差)的高斯函数对图像进行平滑,然后比较平滑后图像的差别, 差别大的像素就是特征明显的点。 以下是sift算法的五个步骤: 一、建立图像尺度空间(或高斯金字塔),并检测极值点 首先建立尺度空间,要使得图像具有尺度空间不变形,就要建立尺度空间,sift算法采用了高斯函数来建立尺度空间,高斯函数公式为:

上述公式G(x,y,e),即为尺度可变高斯函数。 而,一个图像的尺度空间L(x,y,e) ,定义为原始图像I(x,y)与上述的一个可变尺度的2维高斯函数G(x,y,e) 卷积运算。 即,原始影像I(x,y)在不同的尺度e下,与高斯函数G(x,y,e)进行卷积,得到L(x,y,e),如下: 以上的(x,y)是空间坐标,e,是尺度坐标,或尺度空间因子,e的大小决定平滑程度,大尺度对应图像的概貌特征,小尺度对应图像的细节特征。大的e值对应粗糙尺度(低分辨率),反之,对应精细尺度(高分辨率)。 尺度,受e这个参数控制的表示。而不同的L(x,y,e)就构成了尺度空间,具体计算的时候,即使连续的高斯函数,都被离散为(一般为奇数大小)(2*k+1) *(2*k+1)矩阵,来和数字图像进行卷积运算。 随着e的变化,建立起不同的尺度空间,或称之为建立起图像的高斯金字塔。 但,像上述L(x,y,e) = G(x,y,e)*I(x,y)的操作,在进行高斯卷积时,整个图像就要遍历所有的像素进行卷积(边界点除外),于此,就造成了时间和空间上的很大浪费。 为了更有效的在尺度空间检测到稳定的关键点,也为了缩小时间和空间复杂度,对上述的操作作了一个改建:即,提出了高斯差分尺度空间(DOG scale-space)。利用不同尺度的高斯差分与原始图像I(x,y)相乘,卷积生成。 DOG算子计算简单,是尺度归一化的LOG算子的近似。 ok,耐心点,咱们再来总结一下上述内容: 1、高斯卷积 在组建一组尺度空间后,再组建下一组尺度空间,对上一组尺度空间的最后一幅图像进行二分之一采样,得到下一组尺度空间的第一幅图像,然后进行像建立第一组尺度空间那样的操作,得到第二组尺度空间,公式定义为 L(x,y,e) = G(x,y,e)*I(x,y)

程序流程图编写规范详解

程序流程图编写规范 一、符号用法 (2) 1.1数据 (2) 1.2处理 (2) 1.3特定处理 (2) 1.4准备 (2) 1.5判断 (3) 1.6循环界限 (3) 1.7连接符 (3) 1.8端点符 (3) 1.9注解符 (3) 1.10流线 (4) 1.11虚线 (4) 1.12省略符 (4) 1.13并行方式 (4) 二、使用约定 (6) 2.1图的布局 (6) 2.2符号的形状 (6) 2.3符号内的说明文字 (6) 2.4符号标识符 (6) 2.5符号描述符 (6) 2.6详细表示 (7) 2.7流线 (7) 2.8多出口判断的两种表示方法 (8) 三、示例 (9)

一、符号用法 程序流程图用于描述程序内部各种问题的解决方法、思路或算法。 图1-1 标准程序流程图符号 1.1数据 平行四边形表示数据,其中可注明数据名、来源、用途或其它的文字说明。此符号并不限定数据的媒体。 1.2处理 矩形表示各种处理功能。例如,执行一个或一组特定的操作,从而使信息的值,信息形式或所在位置发生变化,或是确定对某一流向的选择。矩形内可注明处理名或其简工功能。 1.3特定处理 带有双纵边线的矩形表示已命名的特定处理。该处理为在另外地方已得到详细说明的一个操作或一组操作,便如子例行程序,模块。矩形内可注明特定处理名或其简要功能。 1.4准备 六边形符号表示准备。它表示修改一条指令或一组指令以影响随后的活动。例如,设置开关,修改变址寄存器,初始化例行程序。

1.5判断 菱形表示判断或开关。菱形内可注明判断的条件。它只有一个入口,但可以有若干个可供选择的出口,在对符号内定义各条件求值后,有一个且仅有一个出口被激活,求值结果可在表示出口路径的流线附近写出。 1.6循环界限 循环界限为去上角矩形表示年界限和去下角矩形的下界限成,分别表示循环的开始和循环的结束。一对符号内应注明同一循环标识符。可根据检验终止循环条件在循环的开始还是在循环的末尾,将其条件分别在上界限符内注明(如:当A>B)或在下界限符内注明(如:直到C

STM官方USB例程JoyStick详解

STM官方USB例程JoyStick详解

————————————————————————————————作者:————————————————————————————————日期:

转载:https://www.doczj.com/doc/7b3183958.html,/thread-51423-1-1.html 作者:追风 一、USB的“JoyStickMouse”例程结构分析 1、例程的结构 (1)底层结构 包括5个文件:usb_core.c(USB总线数据处理的核心文件),usb_init.c,usb_int.c(用于端点数据输入输入中断处理),usb_mem.c(用于缓冲区操作),usb_regs.c(用于寄存器操作)。它们都包含了头文件“usb_lib.h”。在这个头文件中,又有以下定义: #include "usb_type.h" #include "usb_regs.h" #include "usb_def.h" #include "usb_core.h" #include "usb_init.h" #include "usb_mem.h" #include "usb_int.h" usb_lib.h中又包含了七个头文件,其中usb_type.h中主要是用typedef为stm32支持的数据类型取一些新的名称。usb_def.h中主要是定义一些相关的数据类型。 还有一个未包含在usb_lib.h中的头文件,usb_conf.h用于USB设备的配置。 (2)上层结构 上层结构总共5个文件:hw_config.c(用于USB硬件配置)、usb_pwr.c(用于USB连接、断开操作)、usb_istr.c(直接处理USB中断)、usb_prop.c(用于上层协议处理,比如HID协议,大容量存储设备协议)、usb_desc.c(具体设备的相关描述符定义和处理)。

Linux中USB描述符详解-wxc-2018-03-31

USB描述符的作用 USB 设备第一次连接到主机时, 要接收主机枚举( Enumera tion) 和配置(Configuration) , 目的是让主机知道设备功能、是哪一类的USB 设备、占用多少资源、使用了哪些传输方式以及传输的数据量等等。只有主机完全确认了这些信息后, 设备才能真正开始工作。这些信息是通过存储在设备中的USB 描述符来体现的。因此, 这种USB 描述符也可以看作是USB 设备的身份证明。 描述符(Descriptor )是一个完整的数据结构, 存储在USB 设备中, 用于描述一个USB 设备的所有属性。USB主机通过一系列命令要求设备发送这些信息。 USB描述符的种类 描述符分为三大类:标准描述符、设备类描述符、厂商描述符。 三种描述符的类型值bDescriptorType: 设备的类别bDeviceClass

接口类别bInterfaceClass Linux中各种描述符的定义 在include/linux/usb/Ch9.h中定义 USB设备描述符: struct usb_device_descripto r { __u8 bLength; //此描述符的字节数 __u8 bDescriptorType; //描述符的类型(此处应为0x01,即设备描述符) __le16 bcdUSB; // USB版本号(BCD 码)

__u8 bDeviceClass; //设备的类别---可查看上表格 __u8 bDeviceSubClass; //设备子类码:这些码值的具体含义根据bDeviceClass 域来看。 __u8 bDeviceProtocol; /*协议码 这些码的值视bDeviceClass 和bDeviceSubClass 的值而定。如果设备支持设备类相关的 协议,此码标志了设备类的值。如果此域的值为零,则此设备不支持设备类相关的协议,然 而,可能它的接口支持设备类相关的协议。如果此域的值为FFH,此设备使用厂商定义的议。*/ __u8 bMaxPacketSize0; //端点0的最大包大小(仅8,16,32,64为合法值) __le16 idVendor; //厂商标志(由USB-IF组织赋值) __le16 idProduct; //产品标志(由厂商赋值) __le16 bcdDevice; //设备版本号(BCD 码) __u8 iManufacturer; //描述厂商信息的字符串描述符的索引值。 __u8 iProduct; //描述产品信息的字串描述符的索引值。 __u8 iSerialNumber; //描述设备序列号信息的字串描述符的索引值。 __u8 bNumConfigurations; //可能的配置描述符数目 } USB配置描述符 配置描述符中包含了配置描述符本身的长度、所有配置信息的总长度、供电方式及远 程唤醒、供电量。 如果主机发出标准命令Get_Descriptor要求获得设备的某个配置描述符时,该配置应用的所有信息都将发给主机,它包括:该标准配置符本身、该配置所包含的所有接口、端点描述符及设备类描述符和厂商描述符。 struct usb_config_descriptor { __u8 bLength; //此描述符的字节数 __u8 bDescriptorType; //配置描述表类型(此处为0x02) __le16 wTotalLength; //此配置信息的总长(包括配置,接口,端点和设备类及厂商定义的描述符),即:将要返回的配置信息总长度。 __u8 bNumInterfaces; //此配置所支持的接口个数 __u8 bConfigurationValue;//在SetConfiguration()请求中用作参数来选定此配置。 __u8 iConfiguration;//描述此配置的字串描述符的索引 __u8 bmAttributes; /* 配置特性:

USB描述符完全解析

USB设备描述符完全解析 //======================================================= ===================== // 文件名: USBDESC.C // 用途: USB描述符 // 作者: shenfei5 // 时间: 2007.2.3 // 版本: V1.10 //======================================================= ===================== #include #include "usb.h" // USB模块 #include "hid.h" // HID设备 #include "usbcfg.h" // 配置USB #include "usbdesc.h" // USB描述符 // // HID报文描述符 // const U8 HID_ReportDescriptor[] = { HID_UsagePageVendor(0x00), // 报告页版本: 0X06 0X00 0XFF HID_Usage(0x01), // 用途页: 0X05 0X01 // 如果是MOUSE,KEY,在这里应该有用法索引 HID_Collection(HID_Application), // 用法集合开始: 0XA1 0X01 HID_UsagePage(HID_USAGE_PAGE_BUTTON), // BUTTON用法页 HID_UsageMin(1), // 用法最小值 HID_UsageMax(3), // 用法最小值 HID_LogicalMin(0), // 逻辑最小值 HID_LogicalMax(1), // 逻辑最大值 HID_ReportCount(3), // 报告计数(3) HID_ReportSize(1), // 报告页大小(1) HID_Input(HID_Data | HID_Variable | HID_Absolute), // 输入(2) HID_ReportCount(1), // 报告计数值 HID_ReportSize(5), // 报告大小 HID_Input(HID_Constant), // 输入1 HID_UsagePage(HID_USAGE_PAGE_LED), // LED用法页 HID_Usage(HID_USAGE_LED_GENERIC_INDICATOR), // 用法页 HID_LogicalMin(0), // 用法最小值

USB协议详解

USB HID介绍 HID是一种USB通信协议,无需安装驱动就能进行交互,在学习HID之前,先来复习一下USB 协议的相关内容。 USB设备描述符-概述 当插入USB设备后,主机会向设备请求各种描述符来识别设备。那什么是设备描述符呢? Descriptor即描述符,是一个完整的数据结构,可以通过C语言等编程实现,并存储在USB 设备中,用于描述一个USB设备的所有属性,USB主机是通过一系列命令来要求设备发送这些信息的。 描述符的作用就是通过命令操作来给主机传递信息,从而让主机知道设备具有什么功能、属于哪一类设备、要占用多少带宽、使用哪类传输方式及数据量的大小,只有主机确定了这些信息之后,设备才能真正开始工作。 USB有那些标准描述符? USB有5种标准描述符:设备描述符、配置描述符、字符描述符、接口描述符、端点描述符。 描述符之间有一定的关系,一个设备只有一个设备描述符,而一个设备描述符可以包含多个配置描述符,而一个配置描述符可以包含多个接口描述符,一个接口使用了几个端点,就有几个端点描述符。由此我们可以看出,USB的描述符之间的关系是一层一层的,最上一层是设备描述符,下面是配置描述符,再下面是接口描述符,再下面是端点描述符。在获取描述符时,先获取设备描述符,然后再获取配置描述符,根据配置描述符中的配置集合长度,一次将配置描述符、接口描述符、端点描述符一起一次读回。其中可能还会有获取设备序列号,厂商字符串,产品字符串等。 设备描述符 struct _DEVICE_DEscriptOR_STRUCT { BYTE bLength; //设备描述符的字节数大小 BYTE bDescriptorType; //描述符类型编号,为0x01 WORD bcdUSB; //USB版本号 BYTE bDeviceClass; //USB分配的设备类代码,0x01~0xfe为标准设备类,0xff为厂商自定义类型,0x00不是在设备描述符中定义的,如HID BYTE bDeviceSubClass; //usb分配的子类代码,同上,值由USB规定和分配的,HID 设备此值为0 BYTE bDeviceProtocl; //USB分配的设备协议代码,同上HID设备此值为0 BYTE bMaxPacketSize0; //端点0的最大包的大小 WORD idVendor; //厂商编号 WORD idProduct; //产品编号 WORD bcdDevice; //设备出厂编号 BYTE iManufacturer; //描述厂商字符串的索引

USBHID设备报告描述符详解

USBHID设备报告描述符详解 概述: 报告在这里意思是数据传输(data transfer),而报告描述符是对这些传输的数据作用途(usage)上的说明。 USB通讯协议的规范是以1ms产生一个USB帧(frame),USB设备可以每一个帧中发送和接收一个交换(transaction)。交换是由几个封包(packet)组成,而传输是由一个或几个交换来完成传送一口中有效的数据。在这里,传输和报告的意思相类似。传输方式有四种,初始学一般只要了解控制型传输(control transfer)和中断型传输(interrupt transfer)即可。控制型传输是当需要时才执行传输要求,是最一般的传输方式,组态、命令和状态的通讯都可以使用控制型传输;控制型传输主要用于消息型数据(message-type data)。中断型传输目的在做重复的数据更新(recurring data)传输,精确一点而言,即是在每个有限有周期内(bounded period)作至少一次的小量数据发送或接收;所以适用于流动型数据(stream-type data),注意这里所谓的周期时间就是在端点描述符中的轮询间隔时间。报告有三种:input,output, 和Feature.后面将作进一步介绍。中断型输入管线(interrupt in pipe)仅可以传送input报告;中断型输出管线(interrupt out pipe)仅可以传送output报告;但是控制型管线(control pipe)

可以传送input,output和feature报告。端点描述符有声明所使用的端点为何种管线。 数据本身没有任何意义,要赋于用途才能明确其为控制什么(control);例如设备上的按钮指示灯和X与Y轴的位移等都通称控制,数据则为按钮和指示灯的开关状态或X与Y 轴的位移量。为了这个目的应运而生报告描述符,其将数据的操控与它的用途作一对一的对应,所以解读报告后就可以知道每个数据作何种操作。所以“传输的数据”和“操作”只是一事件的两种描述方式。用途是以一个32位卷标(称作usage tag)来表示,高16位称作usage page(用途类页),低16位称为usage ID(用途识别名): Usage = (usage page:usage ID) 举例说明:二个字节分别为x和y轴的位移数据,因此第一个字节的usage=(generic desktop:X),而第二个字节的usage = (generic desktop:Y),其中generic desktop为用途的大类别(称作用途类页)之一,x和y轴的操作用途属于此用途类页。文件universal serial Bus HID Usage Table完整列出所有的usage pages(用途类页)和usage ID(用途识别名),使用者必须遵照文件的规范来声明操作的用途。该文件的附录A有十多个报告描述符的范例,值得研究下。 表1、报告描述符的标签 主项目

Visio流程图符号含义以及标准规则

如文档对你有用,请下载支持! 标准程序流程图的符号及使用约定 一、引言 程序流程图(Progran flowchart)作为一种算法表达工具,早已为工国计算机工作者和广大计算机用户十分熟悉和普通使用.然而它的一个明显缺点在于缺乏统一的规范化符号表示和严格的使用规则.最近,国家标准局批准的国家标准(GB1525-89)<<信息处理--数据流程图,程序流程图,系统流程图,程序网络图和系统资源图的文件编制符号及约定>>为我们推荐了一套标准化符号和使用约定,根据这一标准画出的程序流程图我们称为标准流程图. 1.程序流程图表示了程序的操作顺序.它应包括: (1)指明实际处理操作的处理符号,包括根据逻辑条件确定要执行的路径的符号. (2)指明控制流的流线符号. (3)便于读写程序流程图的特殊符号. 表示连接符,用以表明转向流程图的它处,或从流程图它处转入 。

(1)关于流程图符号的使用约定,简要地说明以下几点: 1.图的布局:流程图中所用的符号应该均心地分布,连线保持合理的长度,并尽量少使用长线. 2.符号的形状:流程图中多数符号内的空白供标注说明性文字.使用各种符号应注意符号的外形和各符号大小的统一,避免使符号变形或各符号大小比例不一. 3.符号内的说明文字:应使符号内的说明文字尽可能简明.通常按从左向右和从上向下方式书写,并与流向无关.如果说明文字较多,符号内写不完,可使用注解符.若注解符干扰或影响到图形的流程,应将正文写在另外一页上,并注明引用符号. 4.符号标识符:为符号规定标识符是为了便于其它文件引用该符号.便如,程序清单中引用到流程图中的特定符号.符号标识符一般写在符号的左上角,参看图6(a). 图6 符号标识符和符号描述符 5.符号描述符:为便于进一步理解符号的功能,可标注符号描述符.通常描述符写在符号的右上角,如图6(b)所示. 6.详细表示:在处理符号或数据符号中画一横线,表明该符号在同一文件集中的其它地言有更为详细的表示.横线在符号内靠近项端,详细表示的标识符写在符号内横线之上,见图7(a).端点符用作详细表示的开始符号和结束符号,在此符号中应给出加横线符号中的标识符,见图7(b). 图7 加横线符号及其详细表示 7.流线 (1)标准流向与箭头的使用:流线的标准流向是从左到右和从上到下.沿标准流向的流线可不用箭头指示流向,但沿非标准流向的流线应用箭头指示充向. (2)流线的交叉:应当尽量避免流线的交叉.即使出现流线的交叉,交叉的流线之间也没有任何逻辑关系,并不对流向产生任何影响,如图8(a)所示. (3)流线的汇集:两条或多条进入线可以汇集成一条输出线,此时各连接点应要互错工以提高清晰度,并用箭头表示流向,如图8(b)所示. 图8 汉线的交叉与流线的汇集 (4)符号流线进出:一般情况下,流线应从符号的左边或项端进入,并从右边或底端离开.其进出点均应对准符号的中心. (5)连接符:为避免出现流线交叉和使用长线,或某个流程图能在另一页上延续,可用连接符将流线截断.截断始端的连接符称为出口连接符,载断末端的连接符称为入口连接符.两连接符中用同一标识符.

HID设备报告描述符详解_划出重点

USB/HID设备报告描述符详解 概述: 报告在这里意思是数据传输(data transfer),而报告描述符是对这些传输的数据作用途(usage)上的说明。 USB通讯协议的规范是以1ms产生一个USB帧(frame),USB设备可以每一个帧中发送和接收一个交换(transaction)。交换是由几个封包(packet)组成,而传输是由一个或几个交换来完成传送一口中有效的数据。在这里,传输和报告的意思相类似。传输方式有四种,初始学一般只要了解控制型传输(control transfer)和中断型传输(interrupt transfer)即可。控制型传输是当需要时才执行传输要求,是最一般的传输方式,组态、命令和状态的通讯都可以使用控制型传输;控制型传输主要用于消息型数据(message-type data)。中断型传输目的在做重复的数据更新(recurring data)传输,精确一点而言,即是在每个有限有周期内(bounded period)作至少一次的小量数据发送或接收;所以适用于流动型数据(stream-type data),注意这里所谓的周期时间就是在端点描述符中的轮询间隔时间。报告有三种:input,output,和Feature.后面将作进一步介绍。中断型输入管线(interrupt in pipe)仅可以传送input报告;中断型输出管线(interrupt out pipe)仅可以传送output报告;但是控制型管线(control pipe)可以传送input,out put和feature报告。端点描述符有声明所使用的端点为何种管线。 数据本身没有任何意义,要赋于用途才能明确其为控制什么(control);例如设备上的按钮指示灯和X与Y轴的位移等都通称控制,数据则为按钮和指示灯的开关状态或X与Y轴的位移量。为了这个目的应运而生报告描述符,其将数据的操控与它的用途作一对一的对应,所以解读报告后就可以知道每个数据作何种操作。所以“传输的数据”和“操作”只是一事件的两种描述方式。用途是以一个32位卷标(称作usage tag)来表示,高16位称作usage page(用途类页),低16位称为usage DI(用途识别名): Usage(用途)=(usage page:usage ID) 举例说明:二个字节分别为x和y轴的位移数据,因此第一个字节的usage =(generic desktop:X),而第二个字节的usage = (generic desktop:Y),其中

相关主题
文本预览
相关文档 最新文档