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.

[参考译文] 读取和写入 MSP430FR5994上的 FRAM2

Guru**** 2551110 points
Other Parts Discussed in Thread: MSP430FR5994

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/589551/reading-and-writing-to-fram2-on-msp430fr5994

主题中讨论的其他器件:MSP430FR5994

因此、我尝试将大型多维有符号整型数组(200KB Worth)读取并写入到我的应用程序的 FRAM 中。 到目前为止,我已经成功地创建了一个6000x4的阵列,并在永久性 FRAM 中初始化它,如下所示。

#pragma PERSISTENT (FRAM_WRITE)
signed int FRAM_WRITE[WRITE_SIZE][COL_SIZE]={0}; 


这会填充我的 FRAM、但我可以看到使用 CCS 中的"Memory Allocation"工具、FRAM2只有7%已满。

那么、我的简单问题是、如何在 FRAM2中创建一个数组、并能够从主循环中读取数据并将数据写入该数组?

谢谢、

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

    您好 Steven、

    默认情况下、PERSISTENT 将被放置在较低的 FRAM 中、因此它可能是使用 FRAM 部分而不是用于阵列的 FRAM2。 如果您想查看 FRAM_WRITE[]的位置、可以在 CCS 的 Debug 文件夹中的.map 文件中找到它。

    PERSISTENT 通常放置在 FRAM 的开头、然后 FRAM 存储器的第一部分配置为 MPU 中的读取+写入权限、 将其他所有内容设置为 Read + Execute Only -这是指您使用 CCS 中内置的 MPU 工具(位于 Project > Properties 下)并将其设置为默认值、允许编译器和链接器决定存储器分段。

    这背后有一些原因-如果您要对 具有20位地址的区域(地址0x10000以上的任何内容、FRAM2部分)进行读取或写入、则必须使用特殊的20位写入指令。 这是通过使用 编译器指南 www.ti.com/lit/pdf/slau132中的__data20_write_char ()等内在函数在 C 中实现的。 因此、它会使您的代码读取起来不太好(不能像在较低内存中那样只使用正常的阵列读取/写入进行访问)。 必须像这样使用大内存访问也会对性能产生轻微影响-它们需要更多的周期-因此这是在可能的情况下使用较低内存的另一个原因。

    但是、对于像您这样的应用、您将在需要可读和可写的数组中记录大量和大量数据、这种默认用例不再有意义。 对于您的情况、我建议修改链接器命令文件、因为您的数据大小太大、您需要使用上部存储器、其中大多数 FRAM 空间位于 FR5994上-因此您需要它进入 FRAM2。

    我之前有一篇文章、帮助遇到类似问题的人员修改其链接器文件: https://e2e.ti.com/support/microcontrollers/msp430/f/166/p/461905/1712925#1712925 如果您想获得有关修改链接器文件以支持您的特定情况的更具体指导、请告知我、因为这可能是一个复杂的主题。

    此致、

    Katie

     

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

    Katie、

    感谢您的快速响应! 20位地址现在非常有意义。  

    下面是我最近对 C 代码所做的更改:

    1)。 已更新我的 Properties->Build->MSP430 Compiler->Processor Options->Specify the Data Memory Model = Large

    2)。 以 persistent 形式初始化 FRAM 中的数据阵列:

    #pragma PERSISTENT (fram_data)
    unsigned short fram_data[0x10000]={0}; 

    3)。 将陀螺仪数据(z_gyro_data 短接)写入 FRAM2:

    while (row < array_length){ 
    __data20_write_short ((unsigned long int) fram_data + row、z_gyro_data);
    row++;

    4)。 填充阵列后、我将需要从中读取:

    ROW = 0;
    
    while (row < array_length){
    __data20_read_short (unsigned long int) fram_data+ row);
    row++;
    }
    

    链接器文件:

    关于链接器文件、我认为我已经接近、但可能缺少一些重要的东西。  

    1) 1)如 https://e2e.ti.com/support/microcontrollers/msp430/f/166/p/461905/1712925#1712925中所示 ,我从 read_write_memory 组中删除了 TI.persistent,并分配了 TI.persistent >> FRAM2。  

    组(RW_IPE)
    {
    
    组(READ_WRITE_MEMORY)
    {
    
    //.TI.persistent:{} 对于#pragma PERSISTENT *
    .cio :{} /* C I/O 缓冲器 *
    sysmem :{} /*动态内存分配区域*/
    } PALIGN (0x0400)、RUN_START (fram_rw_start)
    
    组(IPENCAPSULATED_MEMORY)
    {
    
    ipestruct :{} /* IPE 数据结构 *
    IPE :{} /* IPE *
    .ipe_const :{} /* IPE 受保护的常量 *
    .IPE:_ISR :{} /* IPE ISR */
    } PALIGN (0x0400)、run_start (fram_ipe_start) run_end (fram_ipe_end) run_end (fram_rx_start)
    
    } > 0x4000
    
    .TI.persistent:{}>> FRAM2 

    2)。 我更新了 LARGE_DATA_MODEL 条件:

    #ifndef __large_data_model__
    .text :{}> FRAM /*代码 */
    #else
    //.text :{}>> FRAM2 | FRAM /*代码 *
    .text :{}>> FRAM
    #endif 

    总之、在 C 代码和链接器文件更新之间、这似乎允许我在地址0x010000处分配内存。 我可以在.map 文件、内存浏览器和内存分配工具中看到这一点。  

    然而、当我尝试写入该地址时、似乎没有任何内容在写入。 您是否认为 MPU 配置不正确存在问题?

    谢谢、

    Steve

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

    是的、这里的问题是 MPU 配置。 对于第一个测试、进入 Project > Properties > General 转至 MSP430 MPU 选项卡并取消选中 Enable Memory Protection Unit。 然后尝试您的代码-如果它能够正常工作、这意味着这是由于 MPU 所致。

    要解决此问题、您有2个选项:
    1.我可以提供有关如何修改链接器文件中控制 MPU 设置的某些区域的信息、以便在读取/写入区域增加/缩小时进行调整。 这将对链接器文件进行更多的自定义手动修改。 这更困难、但也更灵活。
    2.(更简单、但灵活性较低):在同一 MPU 选项卡中、选择"Manually specify memory segment boundaries and access rights"(手动指定内存段边界和访问权限)。 然后、您可以为您的句段选择地址。 如果在链接器文件中分配给 FRAM2的唯一内容是.persistent、则可以将这两个边界都设置为0x10000。 将段3设置为读取+写入权限、并将段1设置为读取+执行权限。 段2无关紧要、因为在这种情况下、您可以设置边界、这样就不会有段2。 您还可以设置代码对存储器访问违规的反应方式-选中复选框以使 PUC 复位、 或者将其保持为未选中状态-无论 MPU 不允许写入受保护区域(如您所见)、这也正是您想要复位的情况。 最后、您还可以选择是否有违反的 NMI 中断(默认为非)-您可以使用启用 NMI 来设置此中断。

    对于上述任一情况、请确保选中"Enable Memory Protection Unit"。

    选项2灵活性较低的原因是您使用的是固定地址、因此如果您要将部分 FRAM2用于其他用途、则必须更新这些设置以匹配您使用的存储器区域。 但是、如果您只打算为数据留出所有 FRAM2、那么只需使用 MPU 工具的手动功能就会很容易。

    希望这对您有所帮助!

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

    Katie、  

    解决方案#2非常适合我的应用、谢谢! 我能够遵循您的建议、现在能够使用 __data20_write_short ()和 __data20_read_short ()函数读取和写入所有 FRAM2。  

    对于其他读取此内容的人、我可以通过 执行以下操作来写入和读取 FRAM2 (PERSISTENT 和 NOINIT):

    第一。 编辑链接器文件(lnk_msp430fr5994.cmd)。

    2。  修改 MPU 设置。

    3号。 将处理器选项更新为以下选项。



    4. 声明 persistent 和 NOINIT。 在这里、我将长度为0x186A2的持久"fram_data"数组初始化为0。 在下电上电后、NOINIT numLogFiles 将存储器内容保存在此地址。  

    #pragma PERSISTENT (fram_data)
    unsigned short fram_data[0x186A2]={0};
    
    #pragma NOINIT (numLogFiles)
    unsigned short numLogFiles; 

    5号。 要写入 FRAM2存储器:

    __data20_write_short ((unsigned long int) fram_data、data_yo_want 至_write); 

    6号。 要从 FRAM2存储器读取:

    __data20_read_short ((unsigned long int) fram_data); 

    希望这对您有所帮助! 再次感谢 Katie!

    Steve

    
    

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

    我很高兴能够提供帮助。 非常感谢您为其他人发布详细信息-这真的很有帮助! :-)

    此致、
    Katie