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.

如何把需要掉电保存的数据固定到某一指定位置?

我现在需要把一些数据保存在FRAM的指定位置,并且要求能掉电保存,尝试如下,使用的CCS10:

1、修改cmd文件,新增一个空间存储数据

MEMORY
{

SHARD : origin = 0x4002, length = 0x0002

}

SECTIONS
{

.sharedspace : {} > SHARD

}

然后在程序中定义变量abc到这个空间

#pragma DATA_SECTION(abc, ".sharedspace")
#pragma RETAIN(abc)
uint16_t abc;

经过测试abc能固定存储到0x4002这个位置,但是每次复位这个值就被清零了。

2、使用#pragma NOINIT和#pragma PERSISTENT指令

测试发现能够复位掉电保存,但是并不能达到存储到指定位置的目的,默认是按照.TI.persistent或者.TI.noinit指向的区间顺序存放。

请问有什么办法能同时达到掉电保存和指定位置目的的方法吗?

  • FRAM本身就具备Flash的掉电不复位和RAM的快速读写功能

    我认为#pragma NOINIT和#pragma PERSISTENT不应该一起使用。CCS在构建时会有任何警告消息吗?

    对于PERSISTENT,它实际上需要具有一个初始化值,例如

    #pragma PERSISTENT( FRAM_write )
    unsigned long FRAM_write[ 128 ] = {0};

    这与NOINIT冲​​突,因为这将要求您不要具有初始化值。建议单独使用PERSISTENT

    如果您始终将FRAM变量引用为变量,而不是尝试使用指针写入硬编码地址,那么链接器将变量放置在什么位置实际上并不重要。所以为什么您要锁定FRAM变量的特定地址?

    使用PERSISTENT,默认的链接器文件将所有读写变量放在部件上FRAM的开头。但是,如果您添加/删除/更改变量的大小,则它们最终可能会在该组中的地址稍有不同。但是实际上需要设置特定的绝对地址的用例很少。
  • 我没有一起使用NOINIT和PERSISTENT,只是分开测试了一下,我现在是要保存BOOT程序和APP程序的共享标志和APP里面的一些历史运行参数(需要掉电保存),看了一下官方FRBOOT的示例,一些共享标志位(PassWd和StatCtrl)是被定位到了RAM开头的空间里面,然后把MEMORY里面RAM的起始地址后移了一些,我试了一下在不掉电的情况下复位数据不会丢失并且APP和BOOT能共享这些标志位,但是掉电后数据就会丢了
    但是我有一些标志位需要掉电也不丢,我想可以尝试一下把这些数据定位到FRAM中,然后把FRAM的起始地址后移一些,这样APP和BOOT就都能从这个地址读取并修改这些参数,并且掉电保留了
  • 有些类似于IAR中__no_init uint16_t abc @0x4002这样的操作,既能指定存储位置(到Flash中指定位置能掉电保存)又能保证复位时不会被再次初始化
  • 您可以尝试下面的操作:

    1 修改 linker文件来创建一个新的section,如.myvars。将其放在READ_WRITE_MEMORY组中,因为要存储的变量数据-如果是常量的话,则可以将它们存储在READ_ONLY_MEMORY组中。

    GROUP(READ_WRITE_MEMORY)
    {
       .cio        : {}                   /* C I/O BUFFER                      */
       .sysmem     : {}                   /* DYNAMIC MEMORY ALLOCATION AREA    */
       .myVars     : {}  //space allocated to store variables in FRAM
    } 

    2 在C文件中,可以告诉编译器要将数组放置在刚创建的此部分中,而不是放置在RAM中。您可以使用DATA_SECTION编译指示来完成此操作 (具体信息可以参考 www.ti.com/lit/pdf/slau132 )

    #pragma DATA_SECTION(myArray, ".myVars")
    unsigned char myArray[10];

    您可以直接将数据直接放入FRAM中的该数组中,而无需使用任何绝对地址,您可以使用诸如myArray [i] = data;之类的