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.

[参考译文] CC2642R-Q1:根据 RAM 代码执行任务期间的运行时 BIM/CCFG 复制

Guru**** 2644745 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1582650/cc2642r-q1-runtime-bim-ccfg-copy-during-task-execution-from-ram-code

器件型号:CC2642R-Q1


 

大家好:

 

我想获得专家的反馈、了解在正常工作条件下(假设没有意外复位或功率损耗)、以下运行时闪存复制方法在**CC26x2**器件系列中是否**安全可靠**。

 

——

 

###**目标**
我们的目标是将更新的**BIM 图像**和**CCFG**区域以及更新的**certificate 块**从闪存中的临时暂存区域 (`0x34000`) 复制到其最终目的地 (`0x54000–0x57FFF`)、并在运行时由** CAN 消息**触发。

 

——

 

###**系统环境**
-器件:** TI CC26x2**(运行 TI-RTOS)
-使用 TI **闪存 API (Driverlib)**执行的闪存操作
-暂存区 (`0x34000–0x35FFF`) 由**OTA update**编写为准备运行的二进制映像。
-结构如下:
 -`0x34000`→证书页  
 -`0x35000`→新的 BIM + CCFG 映像  
-最终目的地:
 -`0x54000`→证书(最终副本)
 -`0x56000`→BIM + CCFG(最终副本)
-在此过程中,BIM/CCFG 区域的写保护为**不*启用。

 

——

 

###**代码概览**

 

此函数在运行时由 CAN 消息触发。  
到目前为止、它已成功运行、没有出现错误或意外行为。

 

```c
uint8_t res = copyBimToFinal (true);

 

__attribute__((section(“.ti_ram_code")“))
Bool copyBimToFinal (bool isTaskRunning)

  uint8_t* src =(uint8_t*) 0x34000;
  uint8_t* dst =(uint8_t*) 0x54000;
  uint32_t i;
  uint32_t dataBuf[32];// 128 字节缓冲区

 

  UINT 键= Hwi_disable();
  if (isTaskRunning)
    task_disable();

 

  // 1。 擦除目标页面(包括 CCFG)
  IF (FlashSectorErase (0x54000)!= FAPI_STATUS_SUCCESS)
    返回 false;
  IF (FlashSectorErase (0x56000)!= FAPI_STATUS_SUCCESS)
    返回 false;

 

  // 2. 以 128 字节块进行复制
  适用于 (i = 0;i < 0x4000;i += sizeof (dataBuf))
  {
    uint32_t j;
    对于 (j = 0;j < sizeof (dataBuf);j++)
    {
      ((uint8_t*) dataBuf)[j]= src [i + j];
    }

 

    IF (FlashProgram (((uint8_t*) dataBuf、(uint32_t)(dst + I)、sizeof (dataBuf))!= FAPI_STATUS_SUCCESS)
      返回 false;
  }

 

  对于 (I = 0;I < 100000;I++){}//小延迟

 

  if (isTaskRunning)
    task_enable ();
  Hwi_restore (KEY);

 

  返回 true;
}
```μ s

 

根据将该函数放入 RAM 中:

 

1 μ s ```
.ti_ram_code:{
  *(.TI_ram_code)
}> SRAM
```μ s

 

——

 

###**设计原理**
在擦除和编程操作期间、CC26x2 上的闪存操作会阻止 CPU 访问闪存、因此会将此函数显式移动至** RAM**以避免指令提取冲突。

 

此外:
-** Hwi_disable()**和**Task_disable()**在编程期间阻止从系统的其他部分访问闪存或抢占。
-所有操作都按顺序(擦除→编程)在小块中完成,以最大程度地减少内存使用。

 

——

 

###**问题**
在这些条件(正常运行,无电源故障场景)下、此方法是否被视为**安全且符合 TI 的闪存编程要求?

 

具体来说:
1.在运行时执行此代码而暂时禁用其他任务时、是否存在**隐藏风险**?
2.在多任务 RTOS 环境中从 RAM 执行闪存操作时、TI 是否建议**额外同步**或预防措施?
3.这是否是动态更新 BIM 和 CCFG 区域(无需重新启动到专用引导加载程序上下文)的**首选方法?

 

目前、这种实施在实践中运行良好、没有发现崩溃、验证失败或闪存损坏、但我想从架构的角度确认其正确性和潜在的限制。

 

——

 

感谢您提供任何见解、文档参考或示例。

 

此致、  
*Yusuf Ünlü  


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好:

    我已经审核了您的方法、但我必须阐明、TI 不会对您所写的内容提供任何保证。 换言之、我可以提供建议、建议和一些回顾、但就“这应该和将 100%工作“或“我已经验证了您的方法、它满足了所有要求“的说法而言、我不是很乐意说的。  

    话虽如此,我可以尽我的能力回答你的问题,并提出一些建议。 我仍然建议在生产中使用之前对您的实施进行全面测试(当然)、并且您已验证您的解决方案是否按照您预期的方式运行、是否发现并缓解/接受任何风险。

    在这些条件下(正常运行,无电源故障情况)、这种方法是否被视为**安全且符合 TI 的闪存编程要求?

    根据您的代码、我认为实施是可以的。 我看到您正在禁用硬件中断并通过 Task_Disable 禁用任务抢占、因此还应禁用软件中断。 您不希望在刷写序列过程中中断、尤其是对于 OTA 更新。 我相信您在实施时采取的预防措施是可以的。 (我要仔细检查 Task_Disable 是否禁用软件中断并暂停调度器。)

    在这些情况下(正常运行,无电源故障情况)

    原因是、如果出现功率损耗情况、并且您正在将 CCFG 写入存储器中的位置、则可能会使器件砖化。 通常、最好具有静态 CCFG、或使用引导加载程序来进行此更改。 此外、CCFG 不受写/擦除保护具有应被识别的安全含义。

    总之、我认为实施是可以的、但我仍然认为需要进行全面测试、应该处理或承认异常操作(断电情况)。  

    希望这能有所帮助!

    此致、

    Nima Behmanesh

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的详细说明和建议。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我更新了我的代码、似乎没问题。 它只更新 bim/ccfg 区域、证书区域通过键盘旋转进行更新。 感谢您的支持。


    __attribute__((section(“.ti_ram_code")“))
    bimUpdateFail_e copyBimToFinal (void)

    bimUpdateFail_e ret = BIM_UPDATE_SUCCESS;

    uint8_t* src =(uint8_t*) 0x34000;
    uint8_t* dst =(uint8_t*) 0x56000;
    uint32_t i;
    uint32_t dataBuf[32];

    UINT hwKey = Hwi_disable();
    UINT taskKey = Task_disable ();
    UINT swKey = swi_disable();

    IF (FlashSectorErase ((uint32_t) dst)!= FAPI_STATUS_SUCCESS)

    RET = BIM_UPDATE_ERASE_FAIL;
    }
    暴露

    对于 (i = 0;i < 0x2000;i += sizeof (dataBuf))

    memcpy (dataBuf、src + i、sizeof (dataBuf));

    IF (FlashProgram (((uint8_t*) dataBuf、(uint32_t)(dst + I)、sizeof (dataBuf))!= FAPI_STATUS_SUCCESS)

    RET = BIM_UPDATE_PROGRAM_FAIL;
    休息;
    }
    }

    if (RET == BIM_UPDATE_SUCCESS)

    对于 (i = 0;i < 0x2000;i += sizeof (dataBuf))

    IF (memcmp (dst + I、src + I、sizeof (dataBuf)))

    RET = BIM_UPDATE_VERIFY_FAIL;
    休息;
    }
    }
    }
    }
    SWI_RESTORE (swKey);
    task_enable ();
    Hwi_restore (hwKey);
    返回 ret;
    }