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.

[参考译文] CC2541:从闪存读取的值不正确(器件专用)

Guru**** 2587345 points
Other Parts Discussed in Thread: CC2541

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/592379/cc2541-incorrect-values-read-from-flash-device-specific

器件型号:CC2541

我们一直在构建基于 CC2541的器件的小批量(一次10到50次)、在成功构建数百个器件后、我在从2个器件上的闪存读取值时遇到了问题。

下面是背景:我们存储一个从闪存地址0x86开始的小结构。  它位于中断矢量表的顶部、长度为44字节。  它用于控制器件的各种间隔和功能。  这些设置与固件代码一起进行编程、作为我们编程过程的一部分。  我们在使用正确设置刷新.hex 文件之前对其进行修改。

问题在于:一个值无法从2个有问题的器件上的闪存中正确读取。  所有其他设置(就我所知)均已正确读取。  但有一个问题。   只要编程后器件仍通电、有问题的器件就会从闪存读取正确的值。  循环通电将导致使用一些其他(随机)值。  它只是一种设置。  所有其他设置均已正确加载。  编程后需要重启电源才能导致设置损坏。

这是位于闪存地址0x86的结构。

typedef struct
{
uint16_t setting1、
uint16_t setting2、
uint16_t setting3、
uint16_t setting4、
uint16_t setting5、
uint16_t setting6、
uint16_t setting7、
uint32_t setting8、
uint16_t setting9、
uint16_t setting10、
uint16_t setting11、
uint16_t setting12、
uint16_t setting13、
uint16_t setting14、
uint16_t setting15、
uint16_t setting16、
uint32_t setting17、
uint32_t setting18
}设置 T; 

调解8是有问题的。  它从闪存地址0x102开始、长度为4字节。  我甚至通过 TI 的闪存编程器读回闪存内容、闪存中存储的内容与下载到 CC2541的内容相匹配。  存储在闪存中的值没有问题。  我尝试禁用缓存(设置 FCTL = 0x00),但这没有解决问题。

重申一下、我们已经构建了数百个这些器件、所有器件都运行相同的固件、但2个器件无法正确加载闪存中的值。

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

    这是一个特殊的问题。 您能否尝试构建一个简单的程序、该程序除了从闪存中读回特定地址之外什么也不做? 无 BLE 堆栈等 您仍然看到问题吗?

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

    是否使用 osal_SNV_write 和 osal_SNV_read? 还是使用 HalFlashWrite 和 HalFlashRead?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我们不使用任何 TI 库(裸机编程)。 固件直接从闪存读取值。 这些值作为.hex 文件的一部分写入。 固件不会写入闪存。 只读。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Fredrik、

    我们不使用任何 TI 库(无操作系统、无 BLE 堆栈)。  只需裸机编程。  我可以尝试创建一些只从闪存读取的固件、但获取这些值将非常有趣、因为重现这些值的步骤之一包括下电上电。

    我很确定这不是固件问题。  我们有40多个器件都运行相同的固件、但只有2个器件表现出这种行为。

    下面是设置结构如何存储在闪存中。

    #pragma constseg=__code configuration
    __code volatile const Settings T Settings =
    {
    1、
    1、
    1、
    0、
    1、
    60、
    60、
    10、
    86400、
    1、
    4、
    300、
    30、
    30、
    30、
    60、
    10
    };
    #pragma constseg=默认值 

    我们将使用 IAR 编译器。  这是链接器脚本中将配置块放置在闪存中的部分。

    //内存顶部
    //---
    -Z (code) intvec=0
    -Z (code)配置
    -Z (code) sleep_code
    -Z (code) cstart=_CODE0_start-_CODE0_end 

    我们在代码中所做的就是从结构读取各种字段。  例如、要获得第一个设置、我们确实执行了

    uint16_t 设置= Settings.setting1; 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    有什么关于出错的想法吗? 数据在闪存和 RAM 之间的某个位置损坏、这让我感到非常不舒服。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Curtis、

    不、我不确定这里会发生什么情况。 是否确定要将正确的闪存区域映射到 XDATA 存储器空间(MEMCLL.XBANK)? 下面是我们的 BLE Stack 初始化的一部分:

    __low_level_init (void)
    {
    /*================================================= */
    *初始化硬件。 //*/*================================================
    //
    //将带有常量的闪存组映射到 XDATA 中,以访问“ROM 映射为数据”。
    #if defined HAL_IMAGE_A
    MEMTR =(MEMTR & 0xf8)| 0x05;
    #Elif defined HAL_IMAGE_B
    MEMTR =(MEMTR & 0xf8)| 0x04;
    #else
    MEMTR =(MEMTR & 0xf8)| 0x01;// Bank 1
    #endif
    
    /================================================================================================== //
    //*选择是否
    应执行段初始化*///*。 //
    //*返回:0以忽略 seg_init */
    * 1以运行 seg_init //*/*================================================
    */
    返回1;
    }
    

    下面是我们设置链接器的方法:

    //为闪存中的常量数据定义段。
    //首先是具有程序使用的地址的段(闪存映射为 XDATA)
    -P (CONST) XDATA_ROM_C=0x8000-0xFFFF
    //
    然后是具有十六进制文件中地址的段(闪存组1)
    -P (代码) XDATA_ROM_C_FLASH=0x18000-0x1FFFF
    //最后是 XDATA_ROM_C
    段(最后是 XDATA_ROM_FLASH)/ XDATA_FLASH 初始化程序段/ XDATA_ROM_C
    //我们将闪存映射到 XDATA 地址范围内,而不是将数据复制到 RAM)
    -QXDATA_ROM_C=XDATA_ROM_C_FLASH
    

    此致、
    Fredrik