Thread 中讨论的其他部件:、 CC2540、 CC2650
我正在尝试使用 CC2640实现片上 OAD。 我遵循了 cc2640 BLE OAD 用户指南、当我将 SimpleBLEPeripheral 图像添加到 BLE Device Monitor 时、我收到一条消息"在图像中找不到有效的 OAD 标头。 使用生成的标头"。
当我 对项目不做任何更改时、为什么会获得此结果?
谢谢
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
我正在尝试使用 CC2640实现片上 OAD。 我遵循了 cc2640 BLE OAD 用户指南、当我将 SimpleBLEPeripheral 图像添加到 BLE Device Monitor 时、我收到一条消息"在图像中找不到有效的 OAD 标头。 使用生成的标头"。
当我 对项目不做任何更改时、为什么会获得此结果?
谢谢
是的、我可以附加文件。 我只需要弄清楚如何实现它。 我尝试连接、但它不允许我附加 bin 文件。 因此、我将扩展名更改为.txt。
默认示例不起作用、这是我看到 bin 文件图像元数据有问题的地方。
谢谢
您好 Mario、通过查看前16个字节可以看到:
4ff6 0000 0100 0028 4242 4242 FFFF FFFF
基本上、由于错误放置元数据的原因、应用程序起始地址以及图像类型。 (FF 状态良好)
例如、 在我的计算机上构建 onchip img_b 会导致:
5768 FFFF 0100 001e 4242 4242 001C 01ff
我的最佳猜测是、使用 OAD_IMAGE_TOOL (或忘记添加标记)的编译后步骤不正确。
您也可以在 BTool 中修改标题、单击"删除元数据"按钮、然后单击"添加元数据"、然后填写所需的数据。 (将会出现一条警告、指出存在现有的元数据。 覆盖它。) 然后单击 Write image file (写入映像文件)以输出新的 bin。
无论如何、请注意指向程序启动的正确位置:按照 SDK 中的命令操作、您的操作是什么?
"$TOOLS_BLE$\OAD_IMAGE_TOOL.exe""$PROJ_DIR$\FlashOnly"-simple_peripheral_cc2640r2lp_app.hex"-t onchip-i 应用程序--imgVer 0-usrbb-peripheral "$PROJ_DIR_0x7000-simple_cc67000-ine_inb-imgVer--imbb-inb-inb-inb-inb-inb-inb-0x7000-0x7000-inb-inb-inb-inb-inb-inb-inb
我强烈建议先让示例工作、如果需要、请重新安装 SDK。 开箱即用的片上负载示例应该起作用。
此致、
反叛分子
你好,Rebel,
它看起来是代码和 IAR。
我在 IAR 中未检查校验和、并注释掉了"oad_target_internal_flash.c"中图像头文件的代码。
之后、我的十六进制文件开始如下所示:
:109010005844002025130100A50B0100A50B0100F9
:10902000A50B0100A50B0100A50B0100A50B0100A50B01007C
:10903000A50B0100A50B0100A50B0100A50B0100A50B01006C
:0C904000A50B0100A50B0100710B010045
:10905000FEE7DFF87408007D7047DFF86C28117DAB
那么、我使用此命令来运行 OAD 映像工具:
OAD_IMAGE_TOOL simple_peripheral_cc2650lp_app.hex -t onchip -i app--imgVer 0 --usrId BBBB -ob app_oad.bin -t onchip -m 0x9000 -r 0x13000
显然、OAD 映像创建成功。 因此、我启动了 BTool 并下载了映像、但失败了。
BTool 中的图像标题如下所示:
为什么此更新现在不起作用?
我还将附加由 OAD 映像工具创建的.bin 文件。 *我将扩展名更改为.txt,以便上传。
您好、Mario、
实际上、整个连接参数请求内容/更新内容是可以的。 这可能是因为您的器件不支持该功能。
更重要的是、您的图片看起来被拒绝了-请查看 http://software-dl.ti.com/lprf/simplelink_cc2640r2_sdk/1.00.00.22/exports/docs/blestack/html/oad/oad.html#oad-image-identify-0xffc1
并将其与您的日志进行比较。
看起来 BTool 正确启动-它执行 ATT_WRITE、如指南中所示。
但是、当您的设备获得该图像时、它不喜欢该图像并拒绝该图像、然后发回包含驻留图像信息的通知数据包。 在 OAD 配置文件中设置一些断点、并尝试对此进行调试-并找出拒绝映像的原因。
希望这对您有所帮助、
反叛分子
你好,Rebel,
是、图像被拒绝。 尝试进行 OAD 更新时、我在 A 映像上运行了调试器。 看起来它未通过图像标题版本测试。
(OAD_IMG_ID (ImgHdr->ver)!= OAD_IMG_ID (rxHdr.ver)
首先,让我询问在运行 OAD_IMAGE_TOOLT 时应该输入什么"imgVer"?
--imgVer 0和--imgVer 1有何不同?
OAD_IMAGE_TOOL simple_peripheral_cc2650lp_app.hex -t onchip -i app --imgVer 0 --usrId BBBB -ob app_oad.bin -t onchip -m 0x9000 -r 0x13000
我忘记提到的另一点是、在"图像识别"过程中、我注意到当前图像标题的内容全部为"0xFF"。
这是正常的吗?
因此,当我转到此行代码: (OAD_IMG_ID(ImgHdr->ver)!= OAD_IMG_ID(rxHdr.ver)时 ,我看到:
imgHdr->ver = 0xFFFF。
因此、为了传递这一点、我需要让我的元数据 imgVer 成为一个没有 LSB = 1的数字、否则图像将被拒绝。
谢谢、
Mario
下面是一些更多信息
当我想使用不同的图像版本创建元数据矢量时、似乎无法生成我想要的每个版本。 每个映像版本都必须以 LSB=1结尾、OAD 映像工具会自动将其转换为 LSB=1的数字。
例如、假设我希望 imgVer = 2 (此实例中的 LSB 将为0)。
命令如下:
OAD_IMAGE_TOOL simple_peripheral_cc2650lp_app.hex -t onchip -i app --imgVer 2 -usrId BBBB -ob app_oad.bin -t onchip -m 0x9000 -r 0x13000
运行后、OAD 映像工具会自动将 imgVer 转换为3。
图像版本检查代码
OAD_IMG_ID (ImgHdr->ver)!= OAD_IMG_ID (rxHdr.ver)
由于 OAD_IMG_ID (ImgHdr->ver)始终为0x01、因此始终会导致 false、因为默认情况下、ImgHdr->ver = 0xff (我之前的文章提到了这一点)。
因此、这就是我的图像始终被拒绝的原因。
我有2个问题:
1.工具为何更改图像版本的 LSB?
2.为什么默认(OAD 目标映像)映像头全为0xff?
谢谢、
Mario
当 OAD 映像已传输到目标器件、并且目标器件已执行 CRC 检查以确保其未损坏时、会发生 OAD 成功。 这是您获得 OAD 成功的唯一情况、此时、ImgA 将使自身失效、并通过 BIM 将控制权移交给 ImgB。
BTool 只报告它看到的内容、如果它看到 OAD 下载失败、则 ImgB 将永远不会运行、因为目标设备在 CRC 期间确定它是无效映像-或另一个阻止 OAD 成功发生的问题。
检查监听器捕获以查看导致其失败的原因-或者 BTool 日志可能显示原因。 (OAD 不是一件简单的事情! 保留)
此致、
反叛分子
您好、Mario、
您能否连接监听器捕获?
如果 IMAGE_STATUS 不成功-因为 BTool 正在报告、并且它在监听器上显示、则这里还有另一个问题。
它的读数是0x9014? 您可以在此处粘贴代码吗?
如果代码有效、则应跳转到 IMGB 的复位矢量
此致、
反叛分子
你好,Rebel,
这是监听器捕获。 您会看到最后一个字节正在发送、之后什么也不会发生、原因是从器件复位。
以下是执行系统复位的代码部分:
//检查 OAD 映像是否已完成。
if (oadBlkNum=oadBlkTot)(如果(oadBlkNum =oadBlkTot))
{
#if FITY_OAD_ONCHIP
//在 BIM 中处理 CRC 校验。
OADTarget_systemReset();
#else //!feature_OAD_ONCHIP
因此、一旦最后一个块被传输、BTOOL 就会失去连接。
下面是跳转到 IMG B 的代码:
if (((CRC[0]!= 0xFFFF)&&(CRC[0]!= 0x0000))
{
if (CRC[0]== CRC[1]|| crcCheck (BIM_IMG_B_PAGE、BIM_IMG_B_OSET、CRC))
{
//从固定位置加载标签__IAR_program_start 的地址
//图像的复位矢量、
asm (" MOV R0、#0x9010 ");
asm (" LDR R1、[R0、#0x4]");
//重置堆栈指针,
asm (" LDR SP、[R0、#0x0]");
//和 Jump。
asm (" BX r1 ");
OADTarget_systemReset();//不应在此处获取。
}
}
谢谢、
Mario
您好、Mario、
我认为我对您尝试做的事情没有很好的理解。
您如何实现 OAD? 它是从 IMG_B 到 IMG_B 吗? 还是 IMG_A (OAD_TARGET_APP)到 IMG_B?
请注意、我之前的建议是针对您在 OAD 事务期间作为目标运行的任何固件。 NOT BIM - BIM 永远不会运行 OAD 代码。
无论采用哪种方式、如果您在传输后未达到 OAD_sendStatus (connHandle、OAD_Success);在 OAD.c 中、都存在实际问题。 这最终称为复位。
您之前提到过、您看到 BTool 提示 OAD 失败的问题、这是否仍然存在?
你好,Rebel,
我将 IMG_A (OAD_TARGET_APP)实现为 IMG_B
如果我理解正确、BIM 将确定复位后 IMG_A 还是 IMG_B 将运行。 是这样吗?
我不确定如果 systemReset()前面有 OAD_sendStatus (connHandle、OAD_Success)如何执行。
这里是代码。 这似乎是不可能的。
//检查 OAD 映像是否已完成。
if (oadBlkNum=oadBlkTot)(如果(oadBlkNum =oadBlkTot))
{
#if FITY_OAD_ONCHIP
//在 BIM 中处理 CRC 校验。
OADTarget_systemReset ();<------ 复位
#else //!feature_OAD_ONCHIP
//对新映像运行 CRC 校验。
if (checkDL())
{
//在重新启动之前指示下载成功和 CRC
OAD_sendStatus (connHandle、OAD_Success);<------------ 它永远不会达到这一点
//存储已下载映像的标志。
flagRecord |= getImageFlag();
//存储图像信息。
saveImageInfo();
.
是 BTool 仍显示"OAD Download not successful (OAD 下载不成功)"。
谢谢、
Mario
OAD_sendStatus (connHandle、OAD_Success);发送通知以指示成功。 也许可以在复位前添加此代码。
(* oadTargetWriteCB)(OAD_IMAGE_COMPLETE、connHandle、NULL);最终将应用程序复位。
正确的 BIM 决定了复位后运行哪个程序。
那么、当前的问题是 IMG_B 的复位矢量不正确? 0x9014没有指向正确的点?
我使用较新的代码作为参考(如下所示)
/********* *@fn OAD_imgBlockWrite * *@简要处理映像块写入。 * **@param connHandle -在 *@param pValue -指向要写入的数据的指针 * *@返回无 */ void OAD_imgBlockWrite (uint16_t connHandle、uint8_t * pValue) { // N.B.这必须保持易失性。 volatile uint16_t blkNum = build_uint16 (pValue[0]、pValue[1]); //检查这是否为预期的块编号。 if (oadBlkNum = blkNum) { //将一个16字节块写入闪存。 OADTarget_writeFlash (imagePage、(blkNum * OAD_BLOCK_SIZE)、pValue+2、 OAD_BLOCK_SIZE); //递增接收到的块计数。 oadBlkNum++; } 否则 { //溢出,中止 OAD oadBlkNum = 0; #ifndef feature_OAD_ONCHIP 标志记录= 0; #endif //关闭目标器件 OADTarget_Close(); //发送状态 OAD_sendStatus (connHandle、OAD_buffer_OFL); return; } //检查 OAD 映像是否已完成。 if (oadBlkNum = oadBlkTot) { #if feature_OAD_ONCHIP //表示下载成功 OAD_sendStatus (connHandle、OAD_Success); //通知应用程序,应用程序处理重新启动 if (oadTargetWriteCB!=空) { (* oadTargetWriteCB)(OAD_IMAGE_COMPLETE、connHandle、NULL); } #else //!feature_OAD_ONCHIP //对新映像运行 CRC 校验。 if (checkDL()) { //在重新启动之前指示下载成功和 CRC OAD_sendStatus (connHandle、OAD_Success); //存储已下载映像的标志。 flagRecord |= getImageFlag(); //存储图像信息。 saveImageInfo(); //检查是否已下载所有预期的图像。 if (CheckImageDownloadCount()) { //如果一个映像是网络处理器映像,请立即通知应用程序 //以便它可以对该图像执行操作。 //注意:此回调不是从的上下文发送的 //中断。 可以在此处执行任何操作。 IF (标志记录和 OAD_IMG_NP_FLAG) { (* oadTargetWriteCB)(OAD_IMAGE_COMPLETE、connHandle、NULL); } //如果一个映像是应用程序映像或堆栈映像,则执行重置 //此处。 IF (标志记录和(OAD_IMG_APP_FLAG|OAD_IMG_STACK_FLAG)) { OADTarget_systemReset(); } 标志记录= 0; } } 其他 { // CRC 错误 OAD_sendStatus (connHandle、OAD_CRC_ERR); } 标志记录= 0; #endif //feature_OAD_ONCHIP OADTarget_Close(); oadBlkNum = 0; } 否则 { //请求下一个 OAD 映像块。 OAD_getNextBlockReq (connHandle、oadBlkNum); }