本章节旨在从更高层次解释OAD主要概念,这些概念将在下一章节进一步扩展。一些概念,例如Boot镜像管理(BIM)在具体实现细节上可能有所不同。但是本章尽可能的覆盖这些概念,下一章节解释它们具体实现细节。
BLE5-Stack只支持片外OAD(off-chip OAD)。下载的镜像文件保存在低功耗的外部flash里面,通过BIM加载到C2640R2F内部flash中。
实现OAD自定义GATT service需要两个BLE设备。OAD数据交换中涉及以下定义:
名称 | 概念 |
---|---|
OAD Target | 该设备固件通过空中传输更新,该设备必须支持TI OAD service |
OAD Downloader | 该设备负责接收镜像文件,然后通过空中传输传送给OAD Target |
OAD Target始终是实现OAD服务GATT服务端的设备。通常它是一个将要进行固件更新的peripheral设备。OAT Target使用boot镜像管理器(BIM)协助应用程序进行新的固件镜像文件升级。当设备复位之后执行BIM,并确定是否进行固件更新,如果没有固件更新,BIM将跳转到主程序运行。
OAD Downloader始终是实现OAD服务GATT客户端的设备。通常它是提供固件更新镜像文件的central设备。下图显示了执行OAD所需的设备。OAD Downloader可以使任何满足BLE的设备(例如智能手机)。
使用OAD传输的所有固件均为二进制格式,并包含一个镜像文件元数据头,该元数据头的信息用于OAD服务确定镜像文件是否可以下载,或在BIM中使用元数据头确定镜像文件应该被加载主程序flash中还是直接运行主程序。为防止该元素头信息被多次计算。所有的TI OAD镜像文件使用一个标准的16位元数据向量。该向量被嵌入到镜像文件开始处,占用应用程序固件代码的前16个字节。
本部分将介绍元数据向量中的各个字段及其含义。
大多数元数据检查通过OADTarget_validateNewImage()
函数完成.
TI提供了一个工具用于生成OAD就绪镜像文件,也就是包含元数据向量的将向文件,参考 Generating Metadata Vector for OAD Image.
下表显示了元数据向量各个字段的描述。
域名 | 大小(byte) | 描述 |
---|---|---|
CRC | 2 | 循环冗余校验 |
CRC Shadow | 2 | CRC影子 |
Version | 2 | 版本 |
Length | 2 | 镜像文件长度(Words) |
UID | 4 | 用户ID |
Start Address | 2 | 镜像文件目标地址(words) |
Image Type | 1 | 下载的镜像文件类型 |
State | 1 | 镜像文件状态 |
这些格式使用的是32-bit words。举个例子,如果镜像文件长度为0x100。实际就是256*32/8=1024 byte。OAD word 大小使用宏EFL_OAD_ADDR_RESOLUTION
定义。
循环冗余校验(CRC)是检查镜像文件完整性的手段。这必须分两步进行。首先,当从工具生成镜像文件时,必须计算CRC,这将被存储在元数据向量中的CRC字段中。
该初始CRC将通过OAD服务(见OAD服务(0xFFC0)部分)通过空中发送 。
一旦目标已经收到OAD图像,就会计算CRC Shadow,以确定镜像文件在传输过程中是否已损坏。并将计算结果存储在元数据向量的CRC Shadow字段中。
如果CRC和CRC Shadow相当,则目标可以假设镜像文件在空中传输时没有被破坏。
选择用于CRC计算的算法是CRC-16-CCITT,它是16位CRC计算,在最坏的情况下具有99.9984%的错误检测率。除了该CRC之外,BLE中的所有数据传输均由链路层上的CRC进行保护,从而进一步降低了未检测到的数据损坏风险。
镜像版本字段用于跟踪镜像的修订版本,并确保升级兼容性。客户可以实现自己的版本控制方案; 然而,TI OAD配置文件还附加了一些检查。请参考函数OADTarget_validateNewImage()在oad_target_external_flash.c 看到这些版本检查是如何在片外OAD完成。
长度字段是镜像文件以world为单位的长度,其中world的大小由片外OAD EFL_OAD_ADDR_RESOLUTION定义。用户使用不同外部flash可能需要修改 EFL_OAD_ADDR_RESOLUTION匹配的world的大小。
该字段未被TI OAD配置文件使用,但是客户可以添加自己的基于UID验证镜像文件是否正确加载。
默认情况下,片外镜像文件使用“E”,“E”,“E”,“E”。
Start Address是镜像文件存储在内部flash中的第一个地址。类似于长度字段,这是用world计算的。片外OAD解决方案基于镜像文件类型对起始地址进行限制(下一节更详细地介绍)。
在具有外部flash的片外OAD系统中,可以升级多种类型的镜像文件。这些镜像文件类型包括:
注意:虽然使用片外OAD可以进行Stack升级,但用户必须确保当前固件映像和建议的OAD映像之间的App/Stack边界RAM和flash地址没有更改。由于App/Stack边界上没有运行时检查,所以只有OAD才能覆盖应用程序,如果边界已经增长。使用此选项时,用户应该小心。TI建议在使用片外OAD方法时执>行应用+堆栈升级。
如果需要边界地址更改(即Stack正在增长或缩小),则需要用户执行合并更新(App+Stack),以确保OAD映像已准备好运行。
支持的镜像类型如下所示:
镜像类型 | 值 | 描述 |
---|---|---|
EFL_OAD_IMG_TYPE_APP | 1 | 应用程序或应用程序+Stack合并更新 |
EFL_OAD_IMG_TYPE_STACK | 2 | 只更新Stack |
EFL_OAD_IMG_TYPE_NP | 3 | 网络处理器更新。这仅适用于SimpleAP + SimpleNP演示 |
EFL_OAD_IMG_TYPE_FACTORY | 4 | 工厂永久镜像文件,在任何OTA升级之前就运行在设备上 |
镜像状态是一个单字节数据字段仅用于片外OAD升级方案。状态通知BIM该镜像是否准备好运行或已经运行。这可以防止BIM在每次启动时将相同的图像从外部flash复制到内部flash。
OAD服务目的是为客户提供简单的和可定制的实现。在其最基本的形式中,该服务负责接收/拒绝基于镜像文件头标准的OAD交互,将镜像存储在其适当位置,并且如果下载成功则导致设备重置,以便下载的应用程序映像由BIM加载到主程序区并运行。
OAD服务一个基础的服务,拥有4个特征值。OAD服务的characteristic,UUID和描述如图上图所示。
注意
characteristic使用格式为F000XXXX-0451-4000-B000-000000000000的128位TI基本UUID,其中XXXX是其缩短的16位UUID。为简洁起见,本文将以16位的简短UUID表示该characteristic。
UUID | 名字 | 描述 |
---|---|---|
0xFFC0 | OAD Service | OAD服务声明 |
0xFFC1 | 镜像标识 | 用于发送镜像元数据,以便OAD Target设备可以确定是否接受或拒绝该镜像 |
0xFFC2 | 镜像块 | 镜像数据的实际块以及所占整个镜像的偏移。 |
0xFFC3 | 镜像计数 | 当前下载的完整的镜像个数 |
0xFFC4 | 镜像状态 | 当前OAD下载状态 |
将数据从OAD Downloader发送到OAD Target的主要方式是GATT写入,没有响应消息。GATT通知是用于将状态数据从Target发送到Downloader的主要方法。选择该通信方案以防止Target设备必须包括为了从Downloader接收通知所需的GATT client代码。该OAD Downloader使用寄存器CCCD接收任何特征的通知 (通过写01:00到CCCD)。
注意:GATT通知和没有响应的GATT写入都是不可靠的的消息通讯。为了确保可靠性,建议每个连接事件将OAD有效载荷传输限制为一个步骤。
镜像标识特征值用于在OAD Downloader和OAD Target之间交换镜像元数据。当OAD Downloader将OAD镜像的16字节元数据发送到Target时,OAD进程开始 。一旦接收到升级镜像的元数据,target将进行一些计算,以确定是否应该下载当前镜像。(有可能会拒绝下载,如果当前运行的镜像和要下载的镜像一样)“01:00”应写入该特性的CCCD,以便启用通知。
注意:请参阅oad_target_external_flash.c 中 OADTarget_validateNewImage()函数,该函数具体实现了拒绝下载镜像文件。
如果Target接受镜像,它将通过发送一个请求第一个镜像块的通知以继续OAD进程。否则Target将通过发送当前运行镜像的元数据的一部分来拒绝该镜像。拒绝元数据包含镜像版本和用户ID字段。
下面是使用抓包器抓出的用于拒绝下载OAD镜像的数据。请注意,拒绝通知中只包含映像版本,长度和用户ID。
OAD镜像块特征用于请求和传送OAD图像块。“01:00”应写入该特性的CCCD,以便能够通知块请求。Target发送下一个镜像块的块号的通知给OAD Downloader。该OADDownloader将响应(GATT写无响应)与所述块号和一个16字节的OAD的镜像块。该镜像块包含来自OAD镜像偏移的实际二进制数据块号。 下图显示了一个块请求/响应嗅探器捕获。
OAD图像计数特性用于设置要下载的OAD图像的数量。这仅用于片外OAD,特征值的默认值为1。
OAD图像状态特性用于报告OAD过程中可能发生的各种故障。该OAD Downloader可以使用该信息来确定OAD为什么失败,所以它可以纠正错误,然后再试一次。要使这个特征的通知“01:00”应写入该特性的CCCD。默认情况下定义了四个OAD状态消息。OAD状态代码列在下表中:
OAD状态码 | 值 | 描述 |
---|---|---|
OAD_SUCCESS | 0 | OAD成功 |
OAD_CRC_ERR | 1 | 下载的镜像的CRC与元数据中预期的CRC不匹配 |
OAD_FLASH_ERR | 2 | 外部flash无法打开 |
OAD_BUFFER_OFL | 3 | 接收到的数据包的块号与请求的数据块不匹配。发生溢出。 |
客户可以根据需要扩展这些值,并使用该 OAD_sendStatus()函数将更新发送到OAD Downloader。
此配置文件旨在为客户提供一个简单的可定制的OAD配置文件。在其最基本的形式中,该配置文件负责接受基于镜像头(header)标准的OAD交互,将镜像存储到flash上,并且如果下载成功则导致设备复位,以便下载的应用程序映像由BIM运行。在OAD Downloader和OAD Target分别执行客户端角色和服务端角色。
建立新连接后,更新连接间隔到更快的连接间隔,使能Target的OAD镜像标识和OAD镜像块通知,OAD Downloader将写入镜像标识特征值到OAD Target,消息数据 升级OAD Target的OAD映像标识和OAD映像块特性的更快OAD的连接间隔, OAD Downloader将写入OAD Target的映像标识特性 。在接收到镜像表示特征的写入请求后,OAD Target将可用于OAD升级的镜像与其自己的运行镜像进行比较。OADTarget_validateNewImage()函数在OAD配置文件中负责确定新的镜像时候接受。
如果Target接受镜像,它将通过发送一个请求第一个镜像块的通知以继续OAD进程。否则Target将通过发送当前运行镜像的元数据的一部分来拒绝该镜像。拒绝元数据包含镜像版本和用户ID字段。在这种情况下,OAD过程将立即结束,如图83所示。
镜像块传输特性值允许两个设备请求和响应OAD镜像,一次一个块。镜像块的大小被定义为16个字节-见OAD_BLOCK_SIZE在 oad.h中。OAD Target从OAD Downloader 请求一个镜像块,通过块序号发送通知给OAD Downloader。然后OAD Downloader将通过写入OAD镜像块特性进行响应。消息的数据格式是所请求的块的索引,后跟镜像的对应的16字节。每当OAD Target准备好接收OAD镜像的下一个块时,它将通过所需镜像块的索引来通知图像块传输特性值。
当OAD Target 接收到最后一个镜像块时,对接收的所有镜像进行校验来验证这次传输时候正确的接收了并存储所有镜像块。
当校验通过之后,OAD Target将复位,以便BIM进行验证和加载当前接收的镜像块。最后,OAD Downloader将失去连接,它将重新开始扫描,然后建立连接,连接后对新镜像进行校验,是否是新的镜像在运行。
为了确保可靠性,在OAD传输过程中发生的任何错误或故障都要求OAD Downloader从一开始重新启动OAD传输过程。如果启用通知,可能会通过OAD镜像状态(image state)特征值报告错误。
由于运行的映像无法更新OAD,必须使用引导映像管理器(BIM)。该BIM是被设计为每次复位后运行,检查新下载镜像的正确性,如果正确,新的镜像将加载到内部flash。
注意:从BLE5-Stack 1.00.00 BIM总是链接到内部flash的第31页,并将始终链接CCFG部分。因此,OAD应用程序不需要自己的CCFG。
一般来说,链接器命令文件必须支持TI OAD Profile,TI Tools和TI BIM(TI OAD Ecosystem)的一些基本要求:
这些要求至关重要; 不仅仅是在TI OAD系统中需要得到支持,而且在前面部分讨论过的应用程序的稳定性。
SimpleLink CC2640R2 SDK提供cc26xx_app_oad.cmd(CCS)和cc26xx_app_oad.icf(IAR)链接器命令文件,以显示与TI OAD生态系统兼容性的这些要求。修改一个现有的连接器命令文件为一个OAD off-chip库文件参考: sec-generating-library-oad-linker-file。
通常,TI Image Tool将处理OAD镜像的页面对齐,不需要链接器干预。但是如果需要,可以进行一些堆栈的更改,使堆栈进入点页面对齐,参见OAD项目的堆栈更改。
文章所有代码、工具、文档开源。加入我们QQ群 591679055获取更多支持,共同研究CC2640R2F&BLE5.0。