LoRa开发3:终端驱动设计

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jiangjunjie_2005/article/details/52798757

终端驱动设计

1 引言

从表面看,终端驱动就是MCU通过读写SX1278的寄存器,实现射频收发功能。然而,一个优秀的驱动设计,至少满足以下设计目标;最具挑战的是,有些目标是相互抵触的。

提供机制:区分策略和机制,驱动仅提供机制,由用户进程实现策略;

接口简单:接口越简单,驱动越好使用,另外,更好实现“高内聚、低耦合”;

提高效率:最大化硬件设备性能,是驱动的重要使命;

节能内存:内存复用和指针传递等方法可以节省MCU宝贵的内存;

易于移植:能在不同的MCU之间低成本移植,该驱动就越优异;

稳定可靠:驱动是硬件和系统软件的黏合层,不能有任何差错。

2 系统层次结构

如图2-1所示,除contiki系统外,应用层也需要调用sx1278 driver,一个典型实例见图2,contiki协议栈依赖radio实现对应功能,应用层也需要设置radio参数和获得RSSI与SNR值。


图2-1  radio相关的系统层次

图2-2 分层系统调用实例

3 接口设计

MCU与LoRa硬件接口如图3-1所示:MCU通过SPI总线与LoRa进行通信,包括设置参数和读写FIFO;当LoRa有异步事件发生时,它通过6根连接线DIO0~DIO5中断MCU;MCU为判断接收和发送数据包是否超时需要设置TIMER,该资源LoRa不需要,仅被MCU所用。

图3-1  MCU与LoRa硬件接口

细化图3-1的设计可以得到图3-2所示驱动:DIO除初始化函数化,还需要DIO0~DIO5对应中断服务函数;SPI需要初始化和输入输出函数;TIMER需要初始化、启动和停止函数。

为方便移植LoRa到不同的MCU,特地将驱动设计成2部分:sx127x_src.c和sx127x_ports.c,前者为LoRa操作函数,后者提供图3-2所示接口。

图3-2  MCU需要提供的硬件驱动

Radio driver为尽可能好地实现功能,它提供如图3-3所示的回调函数接口,当事件(如接收数据包)发生时立即调用对应的方法。

 

图3-3  radio回调函数


radio一般都有自己的参数,LoRa也不例外,因此提供了图3-4所示的设参接口。

图3-4  LoRa参数设置

4 数据结构

1.  发送数据包

如图4-1所示,发送数据包不用另外开辟内存,直接从tx_process拷贝数据到LoRa FIFO之中。即使本次发送失败(如返回发送超时),也可以实现重传(FIFO和寄存器值仍得以保留)。

图4-1 发送数据包

2.  接收数据包

为节省宝贵的内存,驱动程序通过图4-2的回调函数GetBufPtr()从用户进程获取缓存区指针,然后将接收数据包复制到该缓存;再执行回调函数RxDone(),让用户进程执行所需的逻辑(如:通知其他进程解析该数据包)。

图4-2 接收数据包

5 时序逻辑

为了高效实现radiodriver,引入了中断和定时器机制来实现发送和接收数据包。因为LoRa是半双工通信,只需要使用1个定时器即可用于检测发送和接收是否超时;另外,根据LoRa芯片特性,当事件发生时会产生引脚的电平翻转信号,MCU需要捕捉该中断。

图5-1~图5-7显示了发送、接收和CAD时7种时序。

#1:停止定时器;

#2:使SX1278进行休眠状态,节省电能;

#3:执行回调函数TxDone(),让用户进程执行所需逻辑;

图5-1 发送成功

 

#1:使SX1278进行休眠状态,节省电能;

#2:执行回调函数TxTimeout (),让用户进程执行所需逻辑(定时器已经关闭);

图5-2 发送超时

 

#1:清除SX1278的中断标志位CRC_ERROR;

#2:关闭定时器;

#3:执行回调函数RxError(),让用户进程执行所需逻辑;

图5-3 接收错误数据包

 

#1:计算SNR(信噪比)和RSSI(接收信号场强值);

#2:从SX1278的硬件FIFO复制数据包到用户进程的RAM缓冲区;

#3:关闭定时器;

#4:执行回调函数RxDone(),让用户进程执行所需逻辑;

图5-4 接收正确数据包

 

#1:执行回调函数RxTimeout (),让用户进程执行所需逻辑(定时器已经关闭);

图5-5 接收超时


#1:关闭定时器;

#2:获取CAD侦听结果(信道干净与否);

#3:使SX1278进行休眠状态,节省电能;

#4:执行回调函数CADDone(),让用户进程执行所需逻辑;


图5-6 CAD侦听结束

 

#1:使SX1278进行休眠状态,节省电能;

#2:执行回调函数CADTimeout (),让用户进程执行所需逻辑(定时器已经关闭);

图5-7 CAD超时


没有更多推荐了,返回首页