在之前的分享中,我们聊了PX4的通信框架和任务调度框架,现在我们讲一下PX4的设备驱动。
PX4支持很多种设备,根据通信方式的不同大致分为:SPI/IIC设备、串口设备、IO设备、CAN设备。这一篇讲一下PX4的SPI/IIC设备。
PX4每个版本中设备驱动都有一些明显的变化,我们以PX4-1.11.3版本为例,l3gd20陀螺仪设备类的继承关系图如图所示:
对于IIC设备与其类似,以磁罗盘ist8310为例
可以发现,SPI和IIC设备都继承了I2CSPIDriver这个类,而这个类继承自两个类
一个是ScheduledWorkItem,这个类封装了设备任务调度需要的接口,这个部分上一篇分享 PX4的任务调度中讲过了,这里不再分析。
另外一个是I2CSPIInstance类,这个类主要定义了SPI和IIC设备参数的定义,如:总线地址、速度、操作等
我们主要讲一下device::SPI和device::IIC类,SPI和IIC这两个类结构类似,我们以SPI类为例,它定义了SPI总线的接口,用于操作SPI总线进行数据读写。SPI类的继承图如图所示:
device::SPI继承了两个类,一个是cdev::CDev,另外一个是device::Device
device::Device主要是总线信息的描述信息,从接口函数可以知道,主要是定义了总线id、类型、地址以及总线的读写接口。
cdev::CDev是PX4封装的字符设备接口类,提供了字符设备注册、open、close、read、write等操作的C++接口。在PX4早期的版本中spi/iic等字符设备使用cdev::CDev提供了字符设备的驱动接口,即实现了cdev::CDev的open、close、read、write等接口,应用层可以通过设备地址/dev/xxx进行open、close、read、write等操作,目前的版本去掉了这些接口的实现,仅有uORB的数据输出方式。
说完SPI设备的类的继承关系,我们来看一下SPI设备的运行时序是怎么样的。
l3gd20设备的运行时序如图所示:
上图简化了任务调度部分的时序,仅体现会定时队列任务,内部有比较复杂的调度时序,参考上一篇 PX4的任务调度 分享中的任务队列时序图。
简单而言SPI设备的时序分为启动和运行,启动部分是驱动任务的初始化,SPI的初始化和设备本身的初始化,运行部分则使用PX4的任务队列功能进行周期性数据更新。
PX4如何处理传感器驱动更新的原始数据,在融合算法应用和控制应用中使用,我们在后面的分享中再讨论。
IIC设备的时序与SPI设备类似,这里不再单独分析,感兴趣的同学可以自己研究绘制一下它的时序图。
–
我的微信公众号,文章同步更新,欢迎关注。