基于LoRaWan协议1.1的ClassB状态机深度解读

小编觉得网上关于LoRaWAN ClassB的解读大多停留在科普阶段,再往下深入的就比较少了。所以小编从看协议到对照代码,自己有一些整理和理解,分享给大家,也欢迎同行交流指正。这篇文章需要有一些LoRaWAN ClassB的基础,如果没有到话,可以参阅小编的另一篇翻译博文《LoRaWan协议1.1 ClassB部分学习笔记》。

先修博文:《LoRaWan协议1.1 ClassB部分学习笔记》https://blog.csdn.net/yanwumuxi/article/details/107133511
协议文档参考:《lorawantm_specification_-v1.1》
开源代码:https://github.com/Lora-net/LoRaMac-node

小编默认大家已经完成了“先修博文”的学习,对于ClassB类型的LoRa设备来说,在MAC层的源代码中有三个非常重要的过程:

  • LoRaMacClassBProcessBeacon();
  • LoRaMacClassBProcessPingSlot();
  • LoRaMacClassBProcessMulticastSlot();

这篇博文重点关注第一个process,也就是关于beacon的过程。当应用层跑到DEVICE_STATE_BEACON_ACQUISITION的状态中时,mac层需要向网络服务器发两个MAC命令进行时间同步和beacon搜索,此时也将mac层状态切换到了MLME_BEACON_ACQUISITION。具体的beacon算法就在MLME_BEACON_ACQUISITION的状态中。
我们知道ClassB中有一些默认的参数,在协议里也有定义。这些参数十分的重要,因为它们决定了ClassB接收窗口时间的计算,是ClassB能够正常运行的基础。这些参数值一般不可以更改,只需要理解。

CLASSB_BEACON_RESERVED      2120

CLASSB_BEACON_GUARD         3000

CLASSB_BEACON_WINDOW	   122880

CLASSB_BEACON_INTERVAL	   128000

LoRaMacClassBProcessBeacon();
在这个process中就描述了关于beacon各个状态的处理。

Beacon在mac层的状态机运行过程概括

beacon的处理过程主要活动于mac层,当射频模块(物理层)搜索到beacon前导码后,mac层对设备状态进行处理,然后通知应用层。

  • MAC层beacon的状态机初始状态为BEACON_STATE_ACQUISITION;
  • 收到beacon,状态为BEACON_STATE_LOCKED;超过时间没收到beacon,状态为BEACON_STATE_TIMEOUT;
  • 没收到beacon要重新接收,状态为BEACON_STATE_REACQUISITION;如果收到了,状态为BEACON_STATE_LOCKED;
  • mac层收到了beacon时间,状态为BEACON_STATE_ACQUISITION_BY_TIME;

注:在这里,区分两个处理方法:
LoRaMacClassBIsAcquisitionInProgress();//获得同步时间,即置态BEACON_STATE_ACQUISITION_BY_TIME
LoRaMacClassBIsAcquisitionPending();//搜索beacon

  • 如果beacon丢失的时间超过了2个小时,需要切换class,状态为BEACON_STATE_LOST;
  • 如果进程被优先级更高的任务打断,状态为BEACON_STATE_HALT;
  • 如果beacon因为有上行数据包发送而丢失了,状态为BEACON_STATE_BEACON_MISSED;

注:初始化的时候把beacon的状态置为BEACON_STATE_ACQUISITION,后来收到beacon后,就不用这个初始状态了,转为BEACON_STATE_ACQUISITION_BY_TIME,其实也是回到了初始状态,只不过这个初始状态是接收到过beacon,获取同步时间后新一轮周期的初始状态。

Beacon状态机详述

BEACON_STATE_ACQUISITION

最初状态。置该状态。

//若发现正在搜索beacon:
if(Ctx.BeaconCtx.Ctrl.AcquisitionPending == 1)
  Radio.Sleep();//射频进入休眠模式。
	置态-BEACON_STATE_LOST;
//若没有搜索beacon
else
    ResetWindowTimeout();//设置beacon,pingslot的超时量和beacon窗口偏移量,单位为symbol。
    将beacon搜索位置1;//beaconctx.ctrl.acquisitionpending=1;
    RxBeaconSetup();
//若mac收到了beacon,置态BEACON_STATE_LOCKED,若没有找到,就会停留在这个状态。

BEACON_STATE_ACQUISITION_BY_TIME

收到beacon后mac层成功收到一个beacon的参考时间(即下一个beacon的下发时间),置该状态。否则停留在BEACON_STATE_ACQUISITION状态。
LoRaMacClassBIsAcquisitionPending表示正在搜索beacon的过程中(置1),如果beacon_state_locked则会置0。

//状态为收到beacon,但是:
if(Ctx.BeaconCtx.Ctrl.AcquisitionPending == 1)
 	置态-BEACON_STATE_LOST;
//若不在搜索beacon的状态
else
 	ResetWindowTimeout();//重置接收beacon的窗口时间windowtime,单位为symbol
 	if(BeaconDelaySet == 1)//接收到beacon,获得了下一个beacon的时间。
 		if(BeaconTimingDelay>0)//delay for next beacon
 			rtc时间校准温度补偿。
 		else
 			RxBeaconSetup(CLASSB_BEACON_RESERVED,false);//在CLASSB_BEACON_RESERVED的时间内持续接收beacon。
 	else//没有获得beacon的时间 
 		置态-BEACON_STATE_ACQUISITION//状态仍然停留在BEACON_STATE_ACQUISITION

BEACON_STATE_TIMEOUT

beacon接收超时了。beacon接收失败,置该状态。

更新beacon时间;//虽然收不到beacon,时间还是要更新,向后加一个beacon周期(128s)。
EnlargeWindowTimeout();//加长接收beacon的窗口时间。
置态BEACON_STATE_REACQUISITION;//即再次接收beacon的状态。

BEACON_STATE_REACQUISITION

beacon重新接收的机制。

将beaconacquired位置0.//表示不再收到beacon,即上个beacon丢失了。
if(当前时间和最后一个接收到beacon的时间差>2小时)
	置态-BEACON_STATE_LOST
else
  //处理beacon丢失
	rtc时间校准温度补偿;
	启动PingslotTimer和MulticastSlotTimer定时器;//按自己的时间来打开接收窗口。
	通知状态给上层-LORAMAC_EVENT_INFO_STATUS_BEACON_LOST;
	设置beacon保护时间CLASSB_BEACON_GUARD;//在beacon_guard时间内没有pingslot打开,以避免接收冲突,确保beacon的接收。
	置态-BEACON_STATE_IDLE;

BEACON_STATE_LOCKED

表示收到beacon:

Ctx.BeaconCtx.Ctrl.AcquisitionPending = 0;//将搜索beacon位置0;
更新beacon事件状态-LORAMAC_EVENT_INFO_STATUS_BEACON_LOCKED//处理beacon接收事件。
if(Ctx.LoRaMacClassBParams.LoRaMacFlags->Bits.MlmeReq == 1)//有mac命令发送
    if( LoRaMacConfirmQueueIsCmdActive( MLME_BEACON_ACQUISITION ) == true )//mac命令发送成功
		LoRaMacConfirmQueueSetStatus( 		
        				LORAMAC_EVENT_INFO_STATUS_OK,MLME_BEACON_ACQUISITION );
置态-BEACON_STATE_IDLE;

BEACON_STATE_IDLE

TimerGetCurrentTime();//获取rtc时间
if(Ctx.LoRaMacClassBParams.LoRaMacFlags->Bits.MlmeReq == 1)
    定义beaconeventtime为下一次接收beacon的时间-设备唤醒所需要的时间。
    定义currenttime为当前时间。
    if(beaconeventtime>currenttime)//接收beacon时间在现时间之后(若在现时间之前就会发生异常,重新接收beacon)
        置态-BEACON_STATE_GUARD;//在此时间区间没有pingslot打开。
        算出beaconEventTime;//现在时间到接收beacon的时间间隔。
		rtc时间校准温度补偿。
    else//接收时间在现时间之前
        置态-BEACON_STATE_REACQUISITION;//重新接收beacon

BEACON_STATE_GUARD

置态-BEACON_STATE_RX;
LoRaMacClassBStopRxSlots();//停止rxslot接收;
RxBeaconSetup(CLASSB_BEACON_RESERVED,false);//在CLASSB_BEACON_RESERVED时间持续接收beacon。

BEACON_STATE_LOST

if(Ctx.LoRaMacClassBParams.LoRaMacFlags->Bits.MlmeReq == 1)
    if( LoRaMacConfirmQueueIsCmdActive( MLME_BEACON_ACQUISITION ) == true )
		LoRaMacConfirmQueueSetStatus( 		
        				LORAMAC_EVENT_INFO_STATUS_BEACON_NOT_FOUND,MLME_BEACON_ACQUISITION );//更新beacon事件状态。
LoRaMacClassBStopRxSlots();//停止rxslot接收;
InitClassBDefaults();//恢复classB默认设置。

小结:开源代码中的封装还是条理清晰的,从应用层的设备状态机到MAC层的MLME状态机,再到BEACON状态机。每一层都保证了上一层的一部分功能能够正常运行。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值