关于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 |
|
由上面可知,当处于CALSS_C模式的时候,传输完成便立马打开了RX2,接收超时时间是0,也就是持续处于接收状态,然后设定了定时器延时RECEIVE_DELAY1。当该定时器超时后跳转到OnRxWindow1TimerEvent函数
1 |
|
这里先判断如果是C模式则要将射频从RX2切换为待机模式,然后再打开RX1。该处的RX1是有超时时间的,也就是前文提到的接收前导码的时间,频率和上行频率相关。其实单单看RX1窗口,和CLASS_A是完全一样的,CLASS_C只是将RX1以外的所有空闲时隙都变成了RX2。
代码到这里分为两条路,其一当在RX1接收到数据后,进入OnRadioRxDone,当处理完接收后,通用是通过判断模式来开启RX2。其二是当RX1未接收到数据则进入OnRadioRxTimeout,在该函数中直接判断模式等于C则开启RX2,否则射频进入休眠。
到了这里回头看看时隙图就完全对的上了。这里补充一下关于两种模式的入网其实是完全一样的。都是在RX1窗口接收到入网应答。