-
USB
学习小记
-HID
类键盘的报告描述符的理解
前言
断断续续的学习了将近三个月,才
把
USB
的
HID
类搞明白,速度真是够慢的。利用晚上
+
周末的时间学习自
己的东西
确实是必要的,不过效率是有点低,以后要更专注一些才行,希望自己能做到吧
。
在学
习过程中
,
刚开始主要参考了周立功编写的一本《
PDIUSBD12 USB
固件编程与驱动开发》,后面的学习主要参考
电脑圈圈的资料包,包括里面的
HID
类的英文协议文档,还有一位台湾前辈几年前写的几篇文章,还有网络下有下得到的
一些
例程。在此感谢各位大虾前辈的分享。
一、学习流程
1
,先大致看下
USB1.1
中文版的协议(就是网上能找到的翻译版),先了解一下
USB1.1
的工作流程(可能此时的你
会对其中很
多内容都很含糊,不过没关系,请坚持!);
2
,选择一款最常用的
USB
芯片,比如我选择的
NXP
< br>的
PDIUSBD12.
有很多使用该芯片的源码可以在
上网搜索得到,
而且周立功公司为其写了一本书,前面的章节对
USB
的工作流程作了一个简单而又清晰的讲解,而不致让人陷入协议的海
洋里;
3
,
有了对
USB1.1<
/p>
协议的大致了解,
选好了开发的平台
(我
刚好手上有一块周立功公司的
EASEARM2200
的开发板
,
上面有
D12
)之后,先跑一下附带
的例程(此开发板配套的例程是基于
UCOS2
系统的,刚开始
用它来参考肯定晕)。没有
能跑的例程,那就上网找一下经验证的例程,比如电脑圈圈在
EDNCHINA
建立的
USB
学习小组里有很好的几个例程,而
且都是基于
51+D12
的,所以极具参考价值。我是参考周立功公司出的那本书来学习的,电脑圈
圈的例程与此书的例子书
写风格较相似,所以可以互相参考。如果也没有开发板,那可购
买一套电脑圈圈他们搞活动的套件或者直接用
51+D12
自<
/p>
己搭一下,这样就可以直接用电脑圈圈写的例程了,可以避免走很多弯路。
4
,有了例程的直观印象后,此时可以上
BUS HOUND5.0
< br>了。此软件可以观察到
USB
设备与主机(
PC
)之间的通讯
数据,特别那
11
个标准请求的理解,通过此软件的观察,可以更好理解其相互之间是如何完成这
个握手枚举过程的。
5
,好了,有了之前的准备工作,是否打算自己做一个设备了呢?嗯,如果
学习是从易到难,那效率是事半功倍。
USB
分为好几个大类,
最简单的类是
HID
类,即人机接口类,那可以从此入手。最常
见的人机接口类设备就是鼠标键盘了。所
以我们可以动手制作一个鼠标或键盘作为第一个
实践例子。
6
,在真正动手写程序之前,还需要加深对
USB
枚举过程的理解和熟悉,特别是其流程。而其中最重要的就是对
11
p>
个
标准请求的理解了。枚举的过程就是设备对主机发过来的这些请求
进行正确响应,告诉主机,
“
我
”
p>
是一个什么样的设备,各
种属性均是什么,完成枚举后,主机才能根
据
“
我
”
的属
性,对
“
我
”
发送过去的数据进行正确的解释。
7
,
OK
,那
开始写程序了,我们选择做一个键盘作为第一个例子。用
D12
的朋友,在阅读过
D12
的数据手册后,参考
< br>电脑圈圈的例子,看其最底层的驱动是如何写的,先把这部分的驱动完成,再谈协议的实现。
《
1
》
USB
器件最底层的驱动编写;
《
2
》
11
个标准请求函数的编写;
《
3
》
6
个
p>
HID
类请求函数的编写;(此
6
个函数很简单)
《
4
》
USB
中断部分的编写,可用查询
或中断法,根据
D12
的中断寄存器的值,去调用
11
个标准请求函数;
《
5
》编写描述符;键盘要用到的描述符包括:
1
,设备描述符,
2
,配置描
述符,
3
,接口描述符,
4
,
HID
描述符,
5
p>
,端
点描述符,
6
,报告描述符,
7
,字符串描述符。其中
4
,
6
为
H
ID
类专有的描述符,
7
是可选的。<
/p>
当完成上
面
5
个部分的函数编写后,如果编写正确,如果你对枚举流程理
解正确,如果描述符没错(可直接使用网上的
例子的),那么此时应该能够枚举成功了,
如果不正确,请分部检查以上
5
个部分的函数。
8
,完成第
7
步后,能枚举成功,可以说是成功一大半了。此
时就考虑如何发数据发出去即可。对于
HID
类设备,特别
p>
是鼠标键盘这类的,只需你能按照报告描述符所描述的格式,把数据发送过去,那么
PC
端即会对你所发送的数据进行响应
了,也就
是你的键盘能输入数据了。
p>
整个
HID
类的,对于键盘鼠标这类设备的
开发即可算是结束了。虽然步骤就是那么多,不过想最后成功,需要参考大
量的资料,最
重要是是英文的
HID
协议,里面有对描述符的详细讲解,还有
例子。还有周立功公司的那本书,虽然后面的
看不懂也暂时用不上,不过前面的结合
p>
D12
这个芯片还是很有参考价值的。其它的书可以先不看吧,觉得
没看也没什么。
二、键盘的报告描述符的理解
在参考别人的例程实现了键盘跑起来的时候,你这时候应该会
想问的是,为什么描述符要这样写呢?
好的,我当初也有同样的疑问,那下面来简单说说键盘的报告
描述符的含义。其它的描述符含义很明显,这里就不作详
细讲解。
报告描述符是
HID
类设备最重要的描述符,其实它相当于一个大的设备属性表,在
主机端会有一个叫做
Parser
的东
西,对在枚举阶段接收到的报告描述符进行解释,以完成对该
HID
p>
设备的属性的了解。
由于电脑圈圈前辈已经对这部分有过较详细的讲解了,我这只
作为补充,供各位参考。
键盘的报告描述符:
const
uint8
KeyBoardReportDescriptor[
63
]
=
{
0x05
,
0x01
,
// USAGE_PAGE (Generic
Desktop)
0x09
,
0x06
,
// USAGE (Keyboard)
0xa1
,
0x01
,
// COLLECTION
(Application)
0x05
,
0x07
,
// USAGE_PAGE (Keyboard)
//
(
1
)
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,Var,Abs)
//
(
2
)
0x95
,
0x01
,
// REPORT_COUNT (1)
0x75
,
0x08
,
// REPORT_SIZE (8)
0x81
,
0x03
,
// INPUT (Cnst,Var,Abs)
//
(
3
)
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,Var,Abs)
//
(
4
)
0x95
,
0x01
,
// REPORT_COUNT (1)
0x75
,
0x03
,
// REPORT_SIZE (3)
0x91
,
0x03
,
//
OUTPUT
(Cnst,Var,Abs)
//
(
5
)
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)
0xc0
,
// END_COLLECTION
}
;
在这为了容易表达,把上面键盘的
报告描述符除开头与尾分成五部分
(
1
)这部分实际上为键盘的八个控制
键,包括:
左
/
右
CTL
,在
/
右
< br>ALT
,在
/
右
SHIFT
,左
/
右
WIN
键盘
,所以
其范
围为如下所示(
HID Usage
从
54
页开始,展示了所有的
keyborad
page
)
1>
0x19
,
0xe0
,
// USAGE_MINIMUM (Keyboard
LeftControl)
0x29
,
0xe7
,
// USAGE_MAXIMUM (Keyboard Right
GUI)
2>
八个键一个键对应于一个位所以:
0x75
,
0x01
,
// REPORT_SIZE (1)
0x95
,
0x08
,
// REPORT_COUNT (8)
report size
单位为
bit
,
re
port count
为
8
,所以
p>
1*8
共占用一个字节;
3>
由于按键的值要么为
1
(按下),要么为
0
(松开),所以逻辑最大值为
1
,最小值为
0
0x15
,
0x00
,
// LOGICAL_MINIMUM (0)
-
-
-
-
-
-
-
-
-
上一篇:定语从句中介词加关系代词的用法
下一篇:不定代词用法精讲精练