一. 总述
相对而言,usb从设备驱动比较好写,只要在中断服务程序中对端点数据进行相应的处理就可以。
对于U-BOOT而言,由于禁止中断,所以使用轮询的方式查询中断寄存器,查看中断是否发生。由于主设备(如PC HUB)在发送请求包的时候最多发送三次,所以应该在这三次之间调用usb的伪中断函数。在U-BOOT中,一般将从设备枚举成usbtty,而调用USB伪中断函数的过程就在控制台重定向后,调用控制台的输入输出函数(关于控制台部分见U-BOOT之stage2的devlist部分)
二.Usbtty的枚举过程
在讲usbtty从设备驱动前先讲清楚枚举过程。
(1)第一个请求包当然是get device descriptor(set address已经结束,BUS bound无法截取)
返回的设备描述符:
bDeviceClass 被定义为 02
需要设定设备为通信类设备(0x02),否则在下面的接口描述符中会误认为有两个接口
其余的类似
厂商字符串索引为01 产品字符串索引为02 设备的序列号字符串索引为03
只有一种配置
(2)get configuration descriptor length=0x0109(这里和HID鼠标有区别)
Usb转串口的实现通过的使用CDC类中的抽象控制模型子类的通用命令AT命令协议
由于使用AT命令的设备软件通常是通过串口通信的,所以也就会打开串口设备
端点描述符 09 02 43 00 02 02 05 c0 01(配置描述符)
CDC接口描述符 09 04 00 00 01 02 02 01 06(编号为0 CDC接口的接口描述符)
这里只是用一个端点,中断端点,接口所使用的类是CDC类(0x02),并且接口使用的子类是Abstract control model(抽象控制模型子类,编号为0x02,要实现USB转串口这是必须的),使用的通信协议为common AT Commands (0x01),该接口使用的字符串索引值为06
CDC功能描述符(类似于HID描述符)
05 24 00 10 01 header functional descriptor
功能描述符第一字节为 length
第二字节为描述符类型 0x24 (CS_INTERFACE的编码)
第三字节bDescriptorSubtype 具体的功能描述符 包括
0x00 header functional descriptor
01 call management functional descriptor
02 abstract control management functional descriptror
06 union functional descriptor
对于功能描述符,第一个描述符必须为header functinal descriptor,
0110为USB通信版本 1.1
05 24 01 10 00 01 call management functional descriptor
前三字节与header functional descriptor 一致
第四字节00 表示设备的能力,这里为0,表示自己不处理调用管理
第五字节比较奇怪,既然我们不处理调用管理,01表示的是调用管理数据类接口的编号,就没什么意义,本来该设置为0的
04 24 02 00 abstract control management functional descriptror
该描述有4字节,前三字节与上一致,第四字节描述设备的能力(1表示支持)
D7~D4 保留
D3 network_connection
D2 send break
D1 set_line_coding set_control_line_state get_line_coding serial_state
D0 set_comm_feature clear_comm_feature get_comm_feature
这里应该设置为02(支持get line coding),设置00 应该是错了,为啥还能保持正常通信需要看主设备驱动中的实现)
05 24 06 00 01 union functional descriptor
表示主接口和从接口 这里00表示前面标号为0的CDC接口,01表示编号为1的数据类接口
07 05 81 03 40 00 ff (接口0的端点描述符)
Bendpointaddress D7表示传输方向 1为输入 使用的端点为端点1 所以为0x81
03中断端点
0x0040 64字节 端点的最大包长
0xff 中断端点查询的时间
09 04 01 00 02 0a 00 00 07(接口描述符1,接口0为CDC接口 接口1为数据类接口)
这里02表示非0端点的数目,一对批量端点,设置为2
数据类接口设置0a
子类为0 使用的协议为0 接口字符串索引为0
07 05 02 02 40 00 ff(接口1的端点描述符 批量输出端点2)
07 05 83 02 40 00 ff(接口1的端点描述符 批量输入端点3)
至此,配置符的获取结束
(3)设置配置
(4)get line coding
A1 21 00 00 00 00 07 00
A1 发送到接口的类输入请求
21 get_line_coding
0000 wValue
0000 发送到接口0
0007 返回长度
(5) 返回串口属性(line_coding)
00 c2 01 00 00 00 08
0001c200 波特率 115200
00 停止位1位停止位
00 无奇偶校验
08 数据位为8bit
(6) set ctrl line state
21 22 00 00 00 00 00 00
22 set ctrl line state
后面均为00