基于USB的虚拟IO桥接器的设计与实现
2023-10-12朱绍英顾云鹭
朱绍英, 顾云鹭
(上海民航职业技术学院,大飞机学院,上海 200232)
0 引言
新型笔记本电脑为了便携性,一方面其主板通过紧凑的设计布局提高集成度,另一方面其屏上也集成各种新传感器及图标实现更方便、更智能的交互式使用。比如普通的触摸、虚拟键盘、摄像头以及自动开关屏幕电源,用户姿态感知,更高安全性的摄像头电子开关等。这些“智能”功能的实现都要求在屏上集成更多的传感器、摄像头、电子开关和微处理器,在传统的系统设计中,主板通过各种IO总线与这些模块直接进行通信,比如I2C、SPI、GPIO,这些IO线从主板穿过转轴Hinge连接屏上的各种传感器,由于转轴的耐用性设计,越来越多的连接线对成本和稳定性带来了极大的挑战,根据OEM提供的信息,每减少1根线就能节省约0.25美元且提高转轴的耐用性。本文通过设计一种通用的IO桥接器解决这个问题,满足原有IO性能的同时,大幅减少转轴连接线的需求,既提高转轴的寿命,又降低系统成本。
1 虚拟IO桥接器
笔记本电脑屏上的传感器等设备采用的接口主要包括I2C、SPI和GPIO等低速数据总线,所以设计中采用通用USB总线作为主板与屏的唯一高速数据通道,主板系统通过USB传输各种IO数据来控制具体传感器等设备。
1.1 硬件架构
综合考虑性能与成本,硬件设计采用Cypress公司CY8C5868控制器,通过可编程控制USB设备、SPI、I2C和GPIO等接口[1-2]。如图1所示,主板上分配1个USB端口,连接4根USB总线穿过转轴,并与屏上的CY8C5868控制器的USB设备端口连接,CY8C5868控制器带有各种可配置的接口,用于连接各种传感器、摄像头和电子开关[3]。
图1 IO桥接器硬件架构
相比传统的硬件设计,本文设计只需要从转轴穿过4根USB总线,节省近12根IO线,并灵活支持数量可变的IO总线设备,降低了成本且提高了稳定性。
1.2 软件架构
在上述硬件设计基础上,需要一步考虑主机驱动、桥接器协议控制软件和驱动的设计,从而提供单转接设备更大的灵活性和性能。
如图2所示,在主机系统(比如Windows)下实现基于USB的虚拟I2C、SPI、GPIO驱动,使得上层软件能以同样的方式操作这类IO接口,底层与IO桥接器之间实现一套命令协议,由IO桥接器上的软件操作实际IO控制器,与具体设备进行通信。
图2 IO桥接器软件架构
2 系统设计与实现
基于该软件架构,主机端各模块有成熟的操作系统和各类驱动,框架可以直接利用,而在桥接器这端,考虑到成本和效率。采用的内存和Flash空间较小,处理器频率也低,所以桥接器接口传输协议的设计与实现是关键。
2.1 接口传输协议
由于采用的USB设备端控制器只支持USB全速模式,根据规范,其bulk传输模式下packet的最大长度为64字节[4],相比简单的GPIO操作,I2C和SPI可能需要支持超过64字节的数据传输,所以接口协议的设计在统一的基础上也要考虑分包的灵活性[5-6]。如表1所示,统一的数据包头用于区分从主机到桥接器的命令与数据,或者反方向的响应数据,具体由cmd_id指定,表示各种IO操作或者管理命令。
表1 USB数据传输格式
USB总线协议是主从模式,所有传输都由主机端发起,IO桥接器端的USB设备从OUT端点接受命令,并将响应数据放到IN端点由主机端读取,如图3所示。底层驱动提供异步读写接口,设计中定义了3个缓存队列,分别为空闲、命令、响应队列。初始化时命令和响应队列为空,从空闲队列分配缓存给USB驱动去从主机端收取数据包,驱动完成后触发USB中断,将数据包加入命令队列,由主线程解析命令,如果不是异步IO,比如GPIO读写,就直接操作响应的GPIO管脚,然后将响应设置到该数据包,加入响应队列,触发USB发送函数。如果是异步IO,为了不阻碍其他命令的处理,由具体IO驱动重新分配缓存,获取响应的数据,加入响应队列并触发USB发送函数。当最终发送完成时,在USB中断例程中释放该缓存并加入空闲队列。
图3 USB数据传输协议
2.1.1 I2C接口实现
基于上面的数据传输协议,为了实现I2C读写接口,设计的I2C主要命令格式如表2所示,由header中的命令ID指定驱动I2C读或写,通过bus_num指定I2C控制器。具体读写的设备和寄存器由slave_addr和reg_addr设置,总包的长度不超过64字节。Windows或Linux主机端基于该命令接口实现一个虚拟USB转I2C驱动,对于超过64字节的传输则通过主机端分包实现,桥接器端通过特殊的flag做出相应处理,底层调用I2C控制器驱动完成实际的读写操作,并将响应结果或数据返回给主机端。
表2 I2C命令数据包
2.1.2 SPI接口实现
相对于400 kHz的快速模式I2C总线,处理器CY8C5868上的SPI控制器最高支持14 MHz,具有更大的带宽用于批量数据传输[7]。在该方案中,上层通信协议使用最大2 kb的SPI数据包,实现更上层的通信数据传输。由于全速模式的USB块传输的最大包的限制,主机端SPI转USB驱动将实际的协议包拆成不定个数的SPI命令数据包,如表3所示,offset用于指定拆包系列号,在桥接器端,当收到offset为0的包时,调用SPI驱动使能片选信号并将数据写入或读出设备,后续SPI数据包的offset依次递增,直接启动SPI DMA进行数据传输,当收到offset为0xFF时,表示这是最后一个SPI命令数据包,要求在数据传输完成时将片选信号置为无效,结束这次总的传输。
表3 SPI命令数据包
设计SPI驱动时,需要将控制器的CS片选设置为GPIO模式,默认是由SPI读写自动执行的,这样就无法实现上述的大数据包的处理,从而要求在桥接器这端先缓存从主机端发来的所有命令数据包,随后再一次性启动SPI读写,这个方案会影响效率且要求更大的内存。
2.1.3 GPIO接口实现
GPIO的读写相对简单,如表4所示。只要标识管脚号和高低电平。为了支持GPIO中断输入,需要主机驱动端轮询USB输入端点,因为USB设备端不能主动发起数据传输,当桥接器端GPIO驱动检测到GPIO中断信号触发,就准备好命令数据包,设置命令的ID为中断类型,number为响应的中断GPIO管脚,value为中断类型,这样主机端读到这个数据包时就知道响应的GPIO发送中断,实现完整的虚拟GPIO设备驱动[8]。
表4 GPIO命令数据包
2.2 watchdog可靠性设计
由于主机端与IO桥接器只有USB总线连接,与直接的IO控制器相比,后者具有更强的出错恢复能力,如直接复位相应的IO控制寄存器,所以IO桥接器需要从可靠性方面进行设计。实现流程以一个硬件watchdog控制器为核心,设计了多个软watchdog的灵活性监控[9],主要实现流程如图4所示。
图4 Watchdog实现流程
利用硬件watchdog两次timeout中断的机制,在第一次timeout中断时检查各个软watchdog的到期时间,当出现非预期的故障导致软watchdog的到期时间没更新时,就直接等待第二次timeout中断,从而触发最终的系统复位。由于多个软watchdog的支持,在设计监控时,可以针对重要的和易出问题的地方选择各自不同的timeout时间来使用软watchdog。
2.3 低功耗管理与实现
笔记本电脑对电源续航时间敏感,IO桥接器的一个重要指标是其功耗,设计中通过使能控制器的低功耗模式使得在空闲状态下的功耗在2 mW以下。软件的主要流程如图5所示,当主机端在一定的时间内没有数据传输请求且USB总线空闲时间超过300 ms,桥接器的USB设备控制器触发suspend中断,然后软件完成必要的控制处理,将定时器、watchdog等暂停,然后进入低功耗模式。一旦主机有新的传输请求或者其他事件中断发生,就会自动唤醒控制器,软件就做恢复响应处理。
图5 系统低功耗管理
3 性能测试
下面分别从IO性能和可靠性两个方面对IO桥接器进行测试和分析。
3.1 IO性能测试
测试中在主机端设计测试用例,分别针对不同长度的IO读写请求重复1000次,统计时间并得到平均速度,如表5所示,结果表明快速模式下的I2C接口和14 MHz频率下的SPI接口的读写性能随着数据包的长度而增加,USB传输和IO桥接器的处理带来了一定的处理开销,符合方案中各设备的数据传输要求。更高性能就需要考虑选用支持高速USB总线和性能更高的控制器。
表5 IO性能
3.2 可靠性测试
根据上述可靠性设计测试IO桥接器在各种错误下的恢复情况,衡量系统的稳定性和可靠性。实际测试用例设计中,针对各种IO操作模拟产生一些错误场景,如使用一些控制开关让响应的读写操作挂死[10]。主要包括:
① USB传输故障导致无法正常收发数据包;
② 系统性故障导致main task无法正常执行;
③ I2C控制器读写故障;
④ SPI控制器读写故障;
⑤ GPIO控制器读写故障。
测试结果显示,当错误发生后,相应的软watchdog能正确侦测并做出正确处理,主机端驱动能从错误中恢复。
4 总结
本文首先分析了IO桥接器的硬件和软件架构,然后具体阐述了软件的系统性设计,包括USB传输协议的设计与实现,I2C、SPI和GPIO接口的实现流程,并基于一个硬件watchdog设计实现了多个灵活的软件watchdog,用于提高各个模块的容错能力,提高整个系统的可靠性,且满足低于2 mW的功耗设计。最后,列出了系统性能测试流程与结果,分析了可靠性测试原理,表明本文设计在各种错误场景均能正常处理。