[原创] 【新版CH554评测】---4.1、USB HID例程学习及验证--描述符

yang_alex   2018-5-3 12:17 楼主
USB有很多种插头、插座,也有很多种外设。这篇文章里,主要围绕着CH554评估板所带的USB HID例程展开。在这里CH554评估板做为从设备。 USB HID类设备属于人机交互设备,如USB鼠标、USB键盘、USB游戏操作杆、USB触摸板、USB轨迹球等等设备。使用HID设备的一个好处是操作系统已经集成了HID类的驱动程序。使用USB HID类设备,开发人员无需开发设备的驱动程序,直接调用API即可完成通信,用户也不用安装USB驱动程序,插入即可识别。所以有很多简单的USB设备喜欢枚举成HID设备,这样就可以不用安装驱动而直接使用。 我们知道,USB是支持即插即用的。所以,在从设备插入主设备(这里主要是PC)时,主从设备之间是有个交互的,主要内容是从设备告诉主设备:我是谁、我需要什么、我能干什么。但是怎么来说这3件事,是有标准格式要求的,这就是USB技术规范里的“描述符”。 标准的USB描述符具体又分为设备描述符、配置描述符、接口描述符、端点描述符和字符串描述符这5种描述符。除此之外,还有一些特殊的描述符,例如我们下面会讲到的HID描述符。 在USB主机访问USB设备的描述符时,USB设备依照设备描述符、配置描述符、接口描述符、端点描述符、字符串描述符顺序将所有描述符传给主机。一个从设备发给主机的内容至少要包含设备描述符、配置描述符和接口描述符,如果USB设备没有端点描述符,则它仅仅用默认管道与主机进行数据传输。 这些描述符之间的关系如下: 一个USB设备只有一个设备描述符,这个设备描述符确定这个设备有多少种配置,每种配置对应一个配置描述符。配置描述符确定这个配置有多少个接口,每个接口对应一个接口描述符。接口描述符确定这个接口有多少个端点,每个端点对应一个端点描述符。端点描述符定义端点的大小和类型。 沁恒的代码不是很规整,也不是很完善,看起来有些别扭。建议参考一下Microchip的代码,MCU是软硬结合的产品,好的硬件要和好的软件结合起来才是好产品。 下面结合CH554评估板所带的USB HID例程展开分析。 设备描述符:(14 个字段,18 Byte)
  1. /*设备描述符*/
  2. UINT8C DevDesc[18] = {0x12,0x01,0x10,0x01,0x00,0x00,0x00,THIS_ENDP0_SIZE,
  3. 0x31,0x51,0x07,0x20,0x00,0x00,0x00,0x00,
  4. 0x00,0x01
  5. };
设备描述符.PNG 配置描述符:(8 个字段,9Byte)
  1. UINT8C CfgDesc[41] =
  2. {
  3. 0x09,0x02,0x29,0x00,0x01,0x01,0x04,0xA0,0x23, //配置描述符
  4. };
沁恒的代码中把后面几个描述符统一放在了CfgDesc[41],这里为了描述方便,分开显示了 配置描述符.PNG 接口描述符:(9 个字段,9Byte)
  1. UINT8C CfgDesc[41] =
  2. {
  3. 0x09,0x04,0x00,0x00,0x02,0x03,0x00,0x00,0x05, //接口描述符
  4. };
注意第5个字节0x02,结合下表可知,这个接口下有2个端点 接口描述符.PNG 端点描述符: (6 个字段,7Byte)
  1. UINT8C CfgDesc[41] =
  2. {
  3. 0x07,0x05,0x82,0x03,THIS_ENDP0_SIZE,0x00,0x18, //端点描述符
  4. 0x07,0x05,0x02,0x03,THIS_ENDP0_SIZE,0x00,0x18, //端点描述符
  5. };
结合上面接口描述符中的描述,这个接口下有2个端点 端点描述符.PNG 字符串描述符:(3 个字段,长度没有限制) 本例中没有使用字符串描述符 字符串描述符.PNG HID描述符:(10 个字段,12Byte)
  1. UINT8C CfgDesc[41] =
  2. {
  3. 0x09,0x21,0x00,0x01,0x00,0x01,0x22,0x22,0x00, //HID类描述符
  4. };
注意第6个字节0x01,第7个字节0x22,第8、9个字节0x22,0x00,结合下表可知,HID描述符附加一个报告描述符,报告描述符的长度是0x0022,即34个字节。这部分有点疑问:标准中说10个字段,12字节。但沁恒的代码中是9个字节,感觉是把最后面2个字段,3个字节省掉了。 (补充:后来突然明白了,表格里说的很明白,最后面2个字段,3个字节是在超出1个附加报告描述符时才会有,本例中只有1个附加报告描述符,所以就省掉了HID描述符.PNG 附加报告描述符: 报告描述符: HID设备的报告描述符比较复杂也比较难理解。它以item形式排列组合而成,无固定长度,用户可以自定义长度以及每一bit的含义。HID报告描述符已经不是简简单单地描述某个值对应某个固定意义了,它能够组合出很多种情况,并且需要PC上的HID驱动程序提供parser解释器来对描述的设备情形进行重新解释,从而组合生成出本HID硬件设备独特的数据流格式。USB协会提供了一个HID描述符编辑工具HIDDescrioptor Tool,用它可以方便生成报告描述符。
  1. /*HID类报表描述符*/
  2. UINT8C HIDRepDesc[ ] =
  3. {
  4. 0x06, 0x00,0xff,
  5. 0x09, 0x01,
  6. 0xa1, 0x01, //集合开始
  7. 0x09, 0x02, //Usage Page 用法
  8. 0x15, 0x00, //Logical Minimun
  9. 0x26, 0x00,0xff, //Logical Maximun
  10. 0x75, 0x08, //Report Size
  11. 0x95, THIS_ENDP0_SIZE, //Report Counet
  12. 0x81, 0x06, //Input
  13. 0x09, 0x02, //Usage Page 用法
  14. 0x15, 0x00, //Logical Minimun
  15. 0x26, 0x00,0xff, //Logical Maximun
  16. 0x75, 0x08, //Report Size
  17. 0x95, THIS_ENDP0_SIZE, //Report Counet
  18. 0x91, 0x06, //Output
  19. 0xC0
  20. };
从代码中可以看出,这个报告描述符像前面HID描述符中所说,有34个字节的内容。 到此,描述符分析完。下面一贴分析USB程序框架。 此内容由EEWORLD论坛网友yang_alex原创,如需转载或用于商业用途需征得作者同意并注明出处 本帖最后由 yang_alex 于 2018-5-3 12:22 编辑

回复评论 (3)

用字符数组来写描述符,省事,就是比用 struct 描述容易出错。
点赞  2018-5-3 12:24
引用: cruelfox 发表于 2018-5-3 12:24
用字符数组来写描述符,省事,就是比用 struct 描述容易出错。

对。

不过即使用数组来写描述符只要格式清晰,描述准确也可以接受。沁恒用一个 CfgDesc[41]的方式就有些别扭了。
点赞  2018-5-3 13:14
存储芯片/MCU/SRAM/PSRAM/DDR/FLASH/MRAM。web.www.sramsun.com  QQ3161422826 TEL:13751192923
点赞  2018-5-3 15:50
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复