关于lorawan

本文最后更新于 2024年6月25日 早上

上一次弄涉及到lorawan的设备还是2年前咯,时间过得真快,由于最近要重新找工作,简历上写了这东西,但是又基本忘光光了,于是来复习一下。

1 什么是LoRaWan

  • Lora仅是一种无线通信的调制方式,lorawan是无线通信协议和系统架构
  • 低功耗
  • 长距离
  • 低数据速率
  • 星形拓扑,单个节点数据可由多个网关接收,单个网关可接收多个节点数据,网关透明传输不做数据处理,仅将数据抛给网络服务器。
  • 官网

1.1 什么是lora

lora和FSK一样都是一种无线调制方式,但原理是完全不同的,lora通过发射信号的频率变化率来承载数据,而FSK则是通过不同频点来实现。前者使得实际传输信息所需要的带宽远大于信息本身的带宽,提高了抗干扰能力,使其传输距离变得更长。
可以通过四个参数去lora进行优化:带宽(BW)、扩频因子(SF)、编码率(CR)、低数据速率优化(LDRO)

  • spreading factor :扩频调制后的信号与扩频调制前的信号带宽之比。数据传输时,将每一位用多位来表示,能够降低误码率,但是传输数据速率也降低了。
  • 编码率:数据流中有用部分的比例。如果编码率是k/n,则对每k位有用信息,编码器总共产生n位的数据,其中n-k是多余的,LoRa采用循环纠错编码进行前向错误检测与纠错,使用该方式会产生传输开销
  • 带宽: 限定允许通过该信道的信号下限频率和上限频率,增加BW,可以提高有效数据速率以缩短传输时间,但是会降低接收灵敏度
  • 参数之间的关系: 符号速率Rs=BW/(2^SF),数据速率DR= SF*( BW/2^SF)*CR

2 LoRaWan 通信数据帧

2.1 Radio PHY layer

前导码 物理头 头校验 物理层负载 CRC
Preamble PHDR PHDR_CRC PHYPayload CRC

该层除了负载部分,其余均是硬件生成,注意的是最后的CRC只有在上行链路的时候才存在,下行是没有的

2.2 MAC层

2.2.1 帧格式

MAC层帧头 MAC层负载 4字节校验
MHDR MACPayload MIC
MHDR Join-Request MIC
MHDR Join-Response MIC

2.2.2 MAC层帧头(MHDR)

MHDR只有一个字节大小

MHDR MType RFU Major
Bit位 7~5 4~2 1~0
  • MType

表示消息类型,入网、入网应答、无需应答的数据上行、无需应答的数据下行、需要应答的数据上行、需要应答的数据下行

MType 描述
000 join Request
001 join Accept
010 Unconfirmed Data Up
011 Unconfirmed Data Down
100 Confirmed Data Up
101 Confirmed Data Down
110 RFU(保留)
111 私有
  • Major

数据消息的版本

Major 描述
00 LoraWan R1
其他 RFU

2.2.3 MAC层负载

帧格式:

负载头 端口 帧负载
FHDR FPort FRMPayload
  • FHDR

MAC负载帧头组成由终端短地址(DevAddr)、帧控制字节FCtrl、帧计数器(FCnt)、MAC命令配置字段(FOpts),其中FOpts最多15个字节

FHDR: DevAddr FCtrl FCnt FOpts
byte字节 4 1 2 0~15
  • 帧控制字节FCtrl

下行时:

FCtrl ADR RFU ACK FPending FOptsLen
Bit位 7 6 5 4 3~0
上行时:
FCtrl ADR ADRACKReq ACK RFU FOptsLen
Bit位 7 6 5 4 3~0

速率自适应控制(ADR, ADRACKReq):
如果置位为true,则服务器会对该节点进行速率和功率的修改。
消息确认位(ACK):
当收到confirmed类型的消息时,进行应答
帧挂起位(FPending):
只在下行交互中使用,表示网关还有数据挂起等待下发。此时要求终端尽快发送上行消息来再打开接收窗口。
帧配置长度:
帧配置长度(FOptsLen)字段位于帧的 FCtrl 部分,表示FOpts的实际长度

  • 计数器 (FCnt)
    上行链路计数器(FCntUp),由终端产生并维护,记录发往服务器的帧数量;下行链路计数器(FCntDown),由服务器产生并维护,记录服务器发往终端的帧数量。

  • MAC命令配置(FOpts)
    一帧数据中可以包含任何MAC命令,MAC命令既可以放在FOpts中,也可以放在FRMPayload中,但不能同时在两个字段携带MAC命令。MAC命令放在FRMPayload时,FPort = 0。
    放在FOpts的命令不加密(原因:加密Payload,对整个数据签名),也不能超过15个字节(2^4 - 1)。
    放在FRMPayload的MAC命令长度不能超过FRMPayload的最大值。
    不想被别人截获的命令要放到FRMPayload,并单独发送该数据帧
    一条mac命令由一个命令ID(CID,一个字节),和特定的命令序列组成,命令序列可以是空。

命令ID 命令 终端发送 网关发送 简介
0x02 LinkCheckReq x 用于终端验证网络连接
0x02 LinkCheckAns x 回应验证请求, 同时包含终端接收质量相关的估算的信号功率
0x03 LinkADRReq x 请求终端改变数据率、传输功率、接收率或者信道
0x03 LinkADRAns x LinkRateReq的应答
0x04 DutyCycleReq x 设置设备的最大总发射占空比
0x04 DutyCycleAns x DutyCycleReq的应答
0x05 RXParamSetupReq x 设置接收时隙相关参数
0x05 RXParamSetupAns x RXSetupReq的应答
0x06 DevStatusReq x 请求终端状态
0x06 DevStatusAns x 返回终端装填,即电量和解调情况
0x07 NewChannelReq x 创建或修改无线电信道
0x07 NewChannelAns x NewChannelReq的应答
0x08 RXTimingSetupReq x 设置接收时隙的时间
0x08 RXTimingSetupAns x RXTimingSetupReq的应答
0x80~0xff Proprietary x x 保留命令
详细MAC命令单独开文说明。
  • 端口FPort
    帧负载数据(FRMPayload)不为空的时候端口号也不能是空。此时FPort=0表示FRMPayload中只有MAC命令

  • 帧负载FRMPayload
    如果帧数据中包含payload,要先对FRMPayload进行加密,再计算消息的一致性校验码(MIC)。
    加密方案使用基于IEEE 802.15.4/2006 Annex B [IEEE802154] 的AES加密,秘钥长度128位。
    使用哪种加密秘钥K取决于消息的FPort:

FPort K 备注
0 NwkSKey 网络密匙
1~255 AppSkey 应用密匙

2.2.4 消息一致性脚环MIC

对整个消息的所有字段进行计算(AES签名算法CMAC)得到消息一致性校验码(MIC)。

2.2.5 Join-request

size 8 8 2
Join Request AppEUI DevEUI DevNonce

2.2.6 Join-accept

size 3 3 4 1 1 (16)Optional
Accpet AppNonce NetID DevAddr DLSettings RXDelay CFList

3 lorawan的下行模式

3.1 class A

接收时隙图

其中Transmait表示一帧上行包的发送时间
RX1表示下行窗口1
R2表示下行窗口2
RECEIVE_DELAY1表示定时器1的定时时长
RECEIVE_DELAY2表示定时器1的定时时长

3.1.1 下行流程说明

当上行数据发送完毕之后将会打开两个定时器,其一被设定为定时RECEIVE_DELAY1,当定时器超时后打开下行数据接收窗口RX1,RX1的接收频率和上行频率相关,对应关系被表述在了地区规范的文档中,下列将简述一下。默认第一窗口的速率是和最后一次上行的速率相同。

在470~510Mhz的通讯频率中,上行被分为了0~95共96个通道,从470.3Mhz间隔200KHz增加到489.3Khz。下行被分为了0到47共48个信道,从500.3Mhz间隔200KHz增加到509.7KHz。上行的通道0和下行的通道0对于,例如上行频率是470.3则下行频率是500.3,

定时器2被设定延时RECEIVE_DELAY2,它是和定时器1同时打开的。在地区规范中被定义为RECEIVE_DELAY1+1s。它的频率与速率都是固定的,可以通过MAC命令修改,默认遵循地区规范(505.3KHz - DR0)

RX1和RX2打开的窗口时间在规范中被要求至少能接受到前导码。该时长在每次打开窗口时都会根据带宽速率计算一次。大概也就百多毫秒。当RX1接受到正确数据后,RX2将不会被打开。

3.2 class C

时隙图

CLASS_C是遵循CLASS_A的基础上衍生出的具备持续下行接收的模式。在CLASS_C下,窗口2将被一直打开。

3.3 class B

该模式实际上就是A和C的折中,定时接收网关的时间同步,然后周期打开下行窗口来接收数据。

3.3 官方代码的实现方式

当数据发送完毕后OnRadioTxDone函数被调用,方便理解,下列用伪代码表述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*首先判断如果是C模组,则当即打开RX2窗口*/
if(mode != class_c)
{
radio.sleep();
}
else
{
RxWindowTimer2.stop();
Rx2Window.open();
}
/*配置定时器*/
RxWindowTimer1.start(RECEIVE_DELAY1);
if(mode != class_c)
{
RxWindowTimer2.start(RECEIVE_DELAY2);
}

由上面可知,当处于CALSS_C模式的时候,传输完成便立马打开了RX2,接收超时时间是0,也就是持续处于接收状态,然后设定了定时器延时RECEIVE_DELAY1。当该定时器超时后跳转到OnRxWindow1TimerEvent函数

1
2
3
4
5
6
7
8
9
static void OnRxWindow1TimerEvent( void )
{
RxWindowTimer1.stop();
if(mode == class_c)
{
Radio.Standby( );
}
Rx1Window.open();
}

这里先判断如果是C模式则要将射频从RX2切换为待机模式,然后再打开RX1。该处的RX1是有超时时间的,也就是前文提到的接收前导码的时间,频率和上行频率相关。其实单单看RX1窗口,和CLASS_A是完全一样的,CLASS_C只是将RX1以外的所有空闲时隙都变成了RX2。
代码到这里分为两条路,其一当在RX1接收到数据后,进入OnRadioRxDone,当处理完接收后,通用是通过判断模式来开启RX2。其二是当RX1未接收到数据则进入OnRadioRxTimeout,在该函数中直接判断模式等于C则开启RX2,否则射频进入休眠。
到了这里回头看看时隙图就完全对的上了。这里补充一下关于两种模式的入网其实是完全一样的。都是在RX1窗口接收到入网应答。

链接

LoraMac API文档


关于lorawan
https://blog.kala.love/posts/1553aaf1/
作者
久远·卡拉
发布于
2021年4月18日
许可协议