口碑好网站建设报价,网站搜索排名和什么有关系,网站建设要懂哪些技术,网站开发的评论界面模板蓝牙Mesh专有DFU Mesh专有DFU协议介绍特征DFU模式和类型角色并发传输混合设备的网络传输速率后台操作传输分区内存映射安全DFU固件IDApplication firmware IDSoftDevice firmware IDBootloader firmware ID 设备页面格式内容 Mesh专有DFU协议介绍
设备固件更新(Device Firmwar… 蓝牙Mesh专有DFU Mesh专有DFU协议介绍特征DFU模式和类型角色并发传输混合设备的网络传输速率后台操作传输分区内存映射安全DFU固件IDApplication firmware IDSoftDevice firmware IDBootloader firmware ID 设备页面格式内容 Mesh专有DFU协议介绍
设备固件更新(Device Firmware Update, DFU)是对蓝牙mesh设备的固件进行更新的过程。
Nordic的mesh DFU协议采用了专有的nRF OpenMesh项目并在专有的OpenMesh协议上运行。OpenMesh协议是一种基于广播的协议类似于蓝牙mesh但它不支持寻址、确认消息传递或加密。
特征
专有的mesh DFU协议优化为尽可能有效地更新网络中的所有设备。尽管它与nRF5 SDK Bootloader和DFU模块共享一些工具和代码模块但在协议和操作方面存在一些差异以便尽可能轻松地更新大量设备。
DFU模式和类型
Mesh网络支持两种DFU类型一种是后台模式新固件在应用运行过程中通过后台传输同时在传输完成的时候会通知应用程序应用程序可以在新固件准备好之后改写flash。另一种是Bootloader模式用于应用程序无法运行时使用BootLoader进行传输此模式主要用于在应用程序出现故障时的回退机制。
在每一种DFU模式下都可以分别对BootLoaderApplication和SoftDevice进行DFU传输。这三种固件都必须单独传输并且每个都有自己的标识符每个都在内存映射中有自己的区域。用于Mesh SoftDevice和Bootloader的nRF5 SDK可以独立更新。如果想在Bootloader程序中进行小的更改这可以节省时间和内存。
角色
当设备作为DFU传输的发起者时使用源角色。源设备控制发送报文的时间间隔。它还响应DFU数据请求包。源角色由nRF Util工具控制。 目的角色用于设备升级时使用。专有Mesh DFU模块接收新固件并在传输完成时通知应用程序。在这个角色中专有的Mesh DFU模块也重传它接收到的DFU数据包。 中继角色用于重传从其他设备接收到的DFU数据包。在此角色下设备不将接收到的报文保存到flash中。
并发传输
与nRF5 SDK DFU相反整个蓝牙mesh网络可以通过并发传输同时更新。 蓝牙Mesh网络可以包含数百个设备逐个更新所有设备需要花费大量时间。为了解决这个问题专有的mesh DFU协议允许mesh网络设备将它们接收到的数据转发给它们的邻居。被动mesh设备和接收传输的设备都将转发所有数据包从而确保DFU传输到网络中的所有设备。这种方法比将整个DFU传输单独传递到每个设备要快得多。
接收到DFU传输的设备将对它接收到的每条数据报文执行以下步骤: 1、验证数据包尚未被接收。 2、在flash中以传输数据的适当偏移量存储数据包的有效载荷。 3、标记接收到的数据包。 4、以指数间隔重新传输数据包的预定次数。 对传输内容不直接感兴趣的设备将只执行步骤1、3和4以确保网络中更远的目标设备仍然接收到数据包。
混合设备的网络
通常蓝牙mesh网络包含具有多个不同角色和固件的设备。在执行DFU传输时能够区分这些设备是很重要的。如果灯开关设备的固件更新到灯泡上很可能灯泡停止工作。这对于一对一DFU传输是不同的就像nRF5 SDK DFU协议所执行的那样发送方能够识别目标设备并向其发送正确的固件。
专有mesh DFU协议通过允许每种设备类型除了应用程序版本号外还拥有自己的应用程序ID来处理混合设备网络。当设备收到即将到来的DFU传输的通知时它可以将传输的应用程序ID与自己固件的应用程序ID进行比较。如果应用id匹配并且传入的传输版本较高则设备通常接受该传输。如果一个设备收到即将到来的DFU传输通知与自己的应用程序ID不同它可以选择作为该传输的中继设备或者忽略它。
传输速率
与nRF5 SDK DFU协议相比专有mesh DFU传输速度相当慢。例如传输100 kB的固件映像需要大约一个小时。专有的mesh DFU协议依赖于冗余来确保可靠的通信因此与nRF5 SDK DFU相比传播相同数量的数据需要更长的时间。DFU数据以16字节的块定期发送每个包都有一些冗余传输以确保所有设备都能接收到它。报文间隔由传输源设备控制。默认情况下蓝牙mesh DFU工具每500毫秒发出一个新数据包(使传输速率为16 B/500 ms 32 B/s)但该数字应根据蓝牙mesh网络属性进行调整。 需要考虑的一些网络特性有: 网络密度在彼此radio范围内的设备数量对数据包接收速率有很大影响。在彼此radio距离内的设备数量越多会导致更多的数据包冲突从而降低总吞吐量。 网络跨度网络中的每一跳都有一定的丢包风险并造成流量的延迟。网络中的跳数越高某些设备错过传输的风险就越高。 网络拓扑结构虽然高节点密度可能会对传输成功率产生负面影响但到达目标节点的路径太少可能会导致数据包丢失。目标节点越是依赖于多个中继设备才能成功传输那么在传输过程中的某个时刻丢失目标节点的可能性就越高。 外部噪音当部署在嘈杂的环境中时专有的mesh DFU性能更差(像所有无线技术一样)。
因为这些特征对于所有的部署都是不同的所以不可能制定一个适用于所有网络的通用规则。为了最大限度地提高DFU性能: ① 调优单个部署; ② 如果可能的话将DFU转移安排在预期的低流量期间噪音最少。
后台操作
由于专有mesh DFU协议的传输速率相对较慢传输最终可能需要一个多小时这对于许多应用程序来说是不可接受的停机时间。为了解决这个问题专有的网格DFU实现了一个后台模式。
后台模式允许应用程序在DFU传输过程中继续正常运行。后台模式是默认的操作模式除非设备上没有有效的应用程序在这种情况下它会回落到引导加载程序(BootLoader)。
传输分区
接收后台DFU传输的设备必须将传入的包存储在flash区域中未使用的分区以避免在运行时覆盖自己。在此过程中DFU传输数据被存储在分区中一旦完成应用程序可以告诉引导加载程序将分区内容复制到应用程序区域从而有效地完成更新。尽管引导加载程序会尽快通知应用程序完成传输但应用程序可以在任何时候自由地复制分区甚至根本不复制。同一时间每种传输类型只能有一个分区并且分区不能重叠。完成分区DFU传输后将删除同一传输类型的现有扇区。
分区必须放置在一个flash区域中该区域必须足够大以便在传输过程中容纳整个传入的应用程序并且不能与新应用程序或旧应用程序重叠。为了确保最大的空间来接收传输无论是作为分区还是作为完整的应用程序通常建议将分区的开始位置放在设备应用程序部分的正中间。如果在传输完成后传输内容不能用于分区或应用程序则设备必须回到引导加载程序并在引导加载程序模式下执行传输。
内存映射
专有mesh DFU协议使用与nRF5 SDK的Bootloader和DFU模块相同的闪存映射仅有细微差别。与将MBR参数存储放在Bootloader和Bootloader设置(在专有mesh DFU中称为设备页面)之间不同专有mesh DFU协议中的MBR参数存储放在Bootloader和应用程序区之间。
内存映射图 内存映射包含以下主要固件元素: SoftDevice Application Bootloader
这些与前面提到的传输类型相对应。每个固件元素都可以通过DFU传输单独更新。应用程序使用引导加载程序来执行接收和中继算法步骤即使在后台模式下工作也是如此。在初始化蓝牙mesh框架时DFU模块初始化引导加载程序中的命令处理程序模块该模块与应用程序一起运行。
为了能够与应用程序一起运行BootLoader程序保留设备上最后768字节的RAM。在所有蓝牙mesh项目文件和链接器脚本中都会考虑到这个保留的RAM。未能保留这些字节将导致应用程序启动时BootLoader程序出现意外行为。
安全
与nRF5 SDK类似专有mesh DFU不加密DFU传输的数据。
在蓝牙mesh的情况下这是一个从OpenMesh协议继承的限制这意味着在任何情况下都不应该将安全敏感数据(如密钥)作为DFU传输的一部分发送。然而专有mesh DFU确实具有椭圆曲线数字签名(ECDSA)用于验证传输。虽然签名是可选的但强烈建议对所有传输签名。在创建DFU传输时使用私有签名密钥执行签名并且可以使用匹配的公共签名密钥对所有蓝牙mesh设备进行预编程以对固件进行身份验证。如果蓝牙mesh设备具有公共签名密钥则在完成传输之前它将始终要求签名通过。签名算法通过创建传输元数据和固件的SHA256哈希来执行。
哈希分解 固件ID (F)的大小取决于传输的类型。
ECDSA使用NIST P-256曲线(secp256r1)创建签名
signature ecc_sign(curveP-256, private_key, hash)在目标设备上使用匹配的公钥验证签名
authenticated ecc_verify(curveP-256, public_key, hash, signature)由于哈希需要整个固件数据所以直到整个传输完成后才会检查签名。这种设计为目标设备上的拒绝服务攻击创造了可能性因为攻击者可能会发起错误的传输。这种错误的传输可能与正常的传输难以区分直到最后的签名检查此时目标设备可能已经花费了大量资源来接收传输。然而这个攻击向量不允许攻击者在目标设备上执行任何代码因为当签名检查失败时目标设备将删除所有关于传输的信息。
DFU固件ID
所有专有mesh DFU传输都由固件ID标识。固件ID的结构取决于传输类型 Application firmware ID SoftDevice firmware ID Bootloader firmware ID 为了决定是否接受传入的传输所有蓝牙mesh设备都在其设备页面中携带其当前固件id。
Application firmware ID
应用程序固件ID标识应用程序。
每个应用程序都有一个ID和版本号。通常设备应该接受DFU应用程序传输与自己的固件相同应用程序ID并且版本号更高。版本号为32位数字版本方案由用户自定义。
当处于引导加载程序模式时预构建的引导加载程序强制执行严格递增的版本号。这可以防止恶意设备将固件降级到以前的版本这种攻击可以用来重新引入固件中的旧弱点。当处于后台模式时不强制执行此规则但强烈建议使用此规则因为没有其他原生方法可以防止恶意降级。
要为每个应用程序创建唯一的固件ID应用程序ID包含一个32位的Company ID字段用于标识设备供应商。公司ID字段可以包含: ①蓝牙SIG分配的公司ID (0xFFFF或更低)或 ②随机选择的大于0xFFFF的标识符。 随机选择的标识符不能保证唯一但它允许没有分配公司ID的供应商保持高概率的唯一性。
SoftDevice firmware ID
Nordic为每个SoftDevice版本分配一个唯一的16位SoftDevice标识符可以从固件中读出。
设备上的SoftDevice固件ID意味着匹配这个数字(尽管这不是正确操作所明确要求的)。由于SoftDevice id代表的是发布id而不是不断增加的版本号因此是否接受传入SoftDevice DFU传输的策略是用户可定义的。
当处于引导加载模式时如果它收到一个FWID信标其中的应用程序ID代表当前应用程序的更高版本但具有不同的SoftDevice固件ID则引导加载程序开始请求SoftDevice更新。在后台模式下升级策略由用户自定义。 由于引导加载程序实现的限制只有当新的SoftDevice能够适应定义的SoftDevice区域时才能接受SoftDevice DFU传输。
Bootloader firmware ID
Bootloader程序固件ID由一个8位的引导程序ID字段和一个8位的引导程序版本字段组成。就像应用程序一样引导加载程序可以有不同的配置每种配置都可以有不同的版本。
在引导加载程序模式下当引导加载程序ID字段与其当前引导加载程序ID相同并且引导加载程序版本字段大于当前引导加载程序版本时引导加载程序接受传入的引导加载程序DFU传输。
在后台模式下升级策略由用户自定义。
设备页面
所有运行专有mesh DFU Bootloader程序的设备都需要在flash中保存设备页面。设备页定义设备配置并充当Bootloader程序的操作参数。
设备页面必须在主机上生成并在部署前在每个设备上闪现。生成设备页面的device_page_generator.py脚本可以在tools/dfu/中找到。
格式
设备页面是设备最后一个flash页面的单页flash管理区域。
内容
设备页包含引导加载程序参与DFU传输所需的所有信息 ① Flash区域每种传输类型(SoftDevice、bootloader和application)在flash中都有一个指定的区域。这些区域在设备页面中定义并且必须能够包含其类型中最大可能的固件块。
② 固件ID每种传输类型(SoftDevice、bootloader和application)都有一个指定的固件ID。这些固件id用于决定是否接受传入的DFU传输并在每次DFU传输完成后更新。
③ 公共签名密钥用于验证DFU传输签名。
④ 状态标志指示每个固件块(SoftDevice、bootloader和application)有效性的标志。
⑤ 分区传输设备上的每个分区传输都有一个专门的结构来描述它。此条目类型是在每次分区传输成功后由引导加载程序生成的。每种传输类型只能有一个分区。
⑥ 固件签名每个固件的签名(如果存在)。
下表列出了可能的条目包括必需的和可选的。
签名公钥用于签名验证的公钥。 固件ID当前固件ID。固件ID条目是三个不同的专有mesh固件ID的连接。 标志每个固件的当前状态。 SoftDevice 区域SoftDevice 固件可以写入的Flash区域。 Bootloader 区域Bootloader 固件可以写入的Flash区域。 Application 区域Application 固件可以写入的Flash区域。 SoftDevice 签名当前SoftDevice的签名。 Bootloader 签名当前Bootloader的签名。 Application 签名当前Application的签名。 SoftDevice 分区SoftDevice传输分区信息。填充(Padding)是一个固定的数据字段其值始终为0。 Bootloader 分区Bootloader 传输分区信息。填充(Padding)是一个固定的数据字段其值始终为0。 Application 分区Application 传输分区信息。