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 + printf 上的 FRAM2

Guru**** 2560320 points
Other Parts Discussed in Thread: MSP-EXP430FR5994, MSP430FR5994

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

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

主题中讨论的其他器件:MSP-EXP430FR5994MSP430FR5994

(原始线程:  )

您好 Katie、

这一切似乎都很好[你和 Steven 达成的设置]、我想我会利用这一点、但我似乎还有一个问题。  我似乎无法使用 printf(" ”)向控制台发送消息的命令。  这是因为我们现在使用的是大内存模型吗?  是否有一个简单的解决方法?  

我使用  的是 Code Composer Studio 的版本:6.1.3.00034。

printf 语句停留在的确切位置似乎是 在名为"copy_decompress_rle.c"的文件中的_TI_decompress_rle_core 函数 中我发现的代码复制如下:

/*------------------ *
/* MSP 由于代码大小原因不使用 memset、且 memset 不会*/
/*适用于大型代码、小型数据模型。 *
/*------------------ *
while (run_len--) WRITE8_ADV (outbuf、ch); 

感谢您提供的任何帮助。

此致、

-Tom

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

    您好、Tom、

    我怀疑看门狗计时器(WDT)可能会由于大量初始化值而在您到达 main 之前超时。 这将解释为什么您被困在 main 之前发生的 c init 代码中。  请参阅此早期帖子:  。 基本上、您只需将此函数添加到项目中:

    int _system_pre_init (void)
    {
    
    WDTCTL = WDTPW + WDTHOLD;//禁用看门狗计时器*/
    返回1;
    
    } 

    对于 printf 的使用、这里有一些指导: http://processors.wiki.ti.com/index.php/Printf_support_for_MSP430_CCSTUDIO_compiler  和 http://processors.wiki.ti.com/index.php/Tips_for_using_printf

    但是、我们通常建议您尽量不要在 MSP430上使用 printf、因为它会消耗大量的系统资源。 大多数人使用其他形式的调试(切换引脚、通过简单的 UART 例程发送数据等)。
    此致、

    Katie

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

    您好 Katie、

    感谢您的回答。 我仍在尝试使 printf()语句正常工作。 不过、WDD 可能不是问题。

    下面是一些详细信息。 我有一个 MSP-EXP430FR5994 Launchpad 开发套件。 LaunchPad PCB 上的丝印指示修订版1.1。 MSP430FR5994芯片上的实际器件标识跨越3条线路。 第一行是:(TI-logo) 5CA8VTW G4 (G4带下划线)。 第二行是:X430FR5994。 第三行是 REV A

    我使用的 CCS 版本是6.1.3.00034。

    我正在运行的测试程序非常简单、是 TI 演示"Blink the LED"的修改版本。 可以在下面嵌入整个代码。 该程序将运行并可进行调试,因此我确信它将到达 main()。 FRAM2写入和读取已验证正常工作(即、我可以在读取后暂停程序、并验证发送到 FRAM2的任意数据是否正确回读)。 当 printf 的行未注释时、会发生该问题。 当尝试单步执行该命令时、程序将挂起到 copy_decompress_rle.c 文件中的_TI_decompress_rle_core 函数。 我不知道这意味着什么。

    根据我在前面的帖子中找到的建议、对项目设置进行了一些修改、以访问 FRAM2存储器。 其中包括将"数据存储器模型"设置为大容量。 此外、MPU 的设置也发生了变化(如下图所示-这应该与之前帖子中的设置相匹配)。 对于 printf 支持(仍然设置为最小值)和堆栈/堆大小的 MSP430连接器基本选项、库函数假设没有改变。 我曾尝试临时增加这些数字,但没有结果。 链接器命令文件代码也根据先前文章中的建议进行了修改。 同样、下面嵌入了相关更改的代码片段。

    我真的很想使用 printf 命令、因为它易于使用、而且我以前也使用过它(在进行更改以适应 FRAM2访问之前)。 我想继续使用它从 Launchpad 通过 USB 接口向 CCS 内的控制台窗口发送调试消息[在我们项目的开发阶段]。 我觉得这很有帮助。 我正在开发的实际程序使用 RTC 来休眠、并通过日历警报中断唤醒。 一旦唤醒、它会对一套传感器(例如加速计)进行采样并在样本之间休眠[使用计时器和相关中断]、直到获得预定数量的样本。 一旦所有数据被"记录"(在 FRAM2中)、它将在重新复位 RTC 之前被处理。 这些消息可帮助我了解器件正在执行的操作、而不会暂停程序、也不会失去实时与 RTC (程序暂停时暂停)之间的相关性。 话虽如此、我对您关于"通过简单 UART 例程发送数据"的评论感到好奇。 如果有办法不使用 printf 通过连接 CCS 控制台的 USB 接口实现相同的结果、我会很感兴趣地听到它。

    非常感谢、

    -Tom

    P.S. 互联网读取让我想知道是否还需要更新控制台 I/O 缓冲区内存定义(链接器命令文件中的.cio)、但我不知道这一点。  更多的阅读信息让我想知道 printf 是否能够在大内存模型中完全正常工作(例如 https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/37516)。  无论通过哪种方式、我都可以使用一些帮助、因为在开始这个项目时、有很多关于 MSP430使用的详细信息、这是我所期望的(这并不像我所期望的那样容易)。

    总之、下面是有关我将使用 printf 测试 FRAM 访问的修改后的简单程序的嵌入式详细信息。

    #include 
    #include 
    
    #pragma PERSISTENT (fram_data)
    unsigned short fram_data[0x02]={0};
    unsigned short read_value;
    
    int main (void){
    WDTCTL = WDTPW | WDTHOLD; //停止看门狗计时器
    PM5CTL0 &=~LOCKLPM5; //禁用 GPIO 上电默认高阻抗模式
    //激活先前配置的端口设置
    P1DIR |= 0x01; //将 P1.0设置为输出方向
    
    printf ("Hello");
    
    for (;;){
    volatile unsigned int i; //易失性以阻止优化
    
    __data20_write_short ((unsigned long int) fram_data、0xA4);
    read_value =__data20_read_short ((unsigned long int) fram_data);
    
    P1OUT ^= 0x01; //使用异或切换 P1.0
    
    I = 10000; // SW 延迟
    我----
    while (i!= 0);
    }
    
    返回0;
    } 

    组(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
    .TI.noinit:{}>> FRAM2
    
    .cinit :{}> FRAM /*初始化表 *
    二进制文件 :{}> FRAM /*引导时初始化表*/
    .pinit :{}> FRAM /* C++构造函数表 *
    init_array :{}> FRAM /* C++构造函数表 *
    mspabi.exidx :{}> FRAM /* C++构造函数表 *
    .mspabi.extab :{}> FRAM /* C++构造函数表 *
    .text:_ISR :{}> FRAM /*代码 ISR */
    
    #ifndef __large_data_model__
    .const :{}> FRAM /*常量数据 */
    #else
    .const :{}>> FRAM | FRAM2 /*常量数据 //
    #endif
    
    #ifndef __large_data_model__
    .text :{}> FRAM /*代码 */
    #else
    //.text :{}>> FRAM2 | FRAM /*代码 *
    .text :{}>> FRAM
    #endif 

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

    您好、Tom、

    我仔细研究了您的问题-感谢您提供了如此详细的信息。 我在 MSP-EXP430FR5994 Launchpad 上重现了问题。 这种情况下的问题是您的链接器文件。 目前、它将用于 C I/O 缓冲区和堆的.cio 和.sysmem 放置在 FRAM 开头标记为"read_write_memory"的区域中。 但是、由于 MPU 中的手动配置、您将 FRAM2设置为唯一的读取+写入区域、因此该区域不是真正的读取+写入访问。

    我们不希望堆和 CIO 位于上部存储器中。 因此、我们有几个选项:

    1.将.cio 和.sysmem 放入 RAM 中。 这是最简单的、但它确实会占用您的一些有限 RAM。

    2.将.cio 和.sysmem 放入 FRAM 的第三个部分、我们也将其定义为读取+写入访问。

    为了实现选项1、您只需从 GROUP (READ_WRITE_MEMORY)中注释掉.CIO 和.sysmem。 然后,在您拥有.TI.persistent 行之前:{}>> FRAM2,您可以添加以下行:

    .cio :{}> RAM /* C I/O 缓冲器 */
    .sysmem :{}> RAM /*动态内存分配区域*/ 

    然后,您还需要转到“项目”>“属性”>“生成”>“高级选项”>“语言选项”,然后选择 printf 支持级别:完全。 此外、您必须按照此处所述增加堆大小:

    最后、如果您尝试在 CCS 中查看控制台输出、请确保控制台处于打开状态、并且必须确保数据将被清除。 我通过在您的"Hello"消息的末尾添加\n 来完成此操作。 您也可以使用 flush 命令执行此操作(请参阅此处的 Flushing 部分  )

    如您所见、这将占用大量 RAM (堆为320字节)、并且还会占用大量堆栈。 此外、这种方法实际上通过使用断点(对用户而言是不可见的)将数据输出回 PC、以便调试器可以拉出数据。 这意味着您可以看到性能的影响、例如、如果您在其他引脚上输出波形、因为它实际上会暂停器件一会以获取此数据。 这就是为什么我们通常建议使用 printf 以外的东西来从器件中获取数据的原因。 MSP-EXP430FR5994 Launchpad 包含一个反向通道 UART、用于此目的-器件上的一个 UART 模块通过仿真电路连接回 USB 和 PC。 因此、您可以使用此 UART 模块向 PC 上的 COM 端口发送和接收数据。 如果您查看 MSP-EXP430FR5994 Launchpad 用户指南 www.ti.com/lit/pdf/slau678 第2.2.4节"应用(或反向通道) UART"、则可以从 PC 端找到有关连接此器件的更多信息。 对于您的代码,您需要为 eUSCI_A0模块编写代码,以便通过 UART 初始化和发送(并可能接收)数据(通常我们建议使用9600波特,无奇偶校验)。 此处提供了 UART 的代码示例:

    Driverlib 样式代码:

    寄存器级样式代码:

    此致、

    Katie