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.

[参考译文] TMS320F28027F:清除所有 RAM 内容、但保留自动初始化变量

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/704003/tms320f28027f-clear-all-ram-contents-but-keep-auto-initialization-variable

器件型号:TMS320F28027F

尊敬的香榭丽舍

TI 的示例项目只是具有自动初始化变量的功能、但没有清除 RAM 内容的功能。 您能否建议您使用一种方法清除所有 RAM 内容、但保留自动初始化变量值?

谢谢。。。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在汇编语言中编写启动代码以清除所有 RAM、甚至在其进入 cinit 之前。 这可能是实现它的最佳方法、不会有意外写入 cinit 数据的风险。 在 TI 示例中、您将看到一个* asm 文件。 在这里、您将添加此 RAM 清除代码。 请确保在清除 RAM 时禁用看门狗、因为这可能需要一段时间。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    听起来不错。 您可以与我共享参考代码吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Jack:

    标准 C 启动例程应清除所有静态存储变量(SSV)并初始化具有初始化程序的变量。 据我所知、由于这些 MCU 上具有 ECC 的 RAM 在没有初始化的情况下不可用(请参阅 DxINIT、LSxINIT 等寄存器)、引导 ROM 会清除(初始化)所有 RAM、因此 C 编译器不必清除 SSV。 这是正确的、但仅适用于正常启动电源。  调试时、不会调用引导 ROM 中的 RAM 清除例程、也不会清除 SSV。 链接器 RAM 初始化模型不起作用、因为通常需要在不重新加载的情况下重新启动程序。

    在用于 C2000的 TI C 编译器中、您可以定义 _system_pre_init ()例程、该例程在使用初始化程序初始化变量之前调用。 您可以添加该代码以通过某种方式清除.ebss 段。

    例如、您可以为.ebss 指定一些存储器、如 GS0、然后使用 GS0INIT 寄存器初始化 GS0。

    2.您也可以使用 memset()来初始化.ebss。

    在 cmd 文件中:

    ebss:> RAMGS23,PAGE = 1,RUN_START (_EbssStart),RUN_SIZE (_EbssSize),table (ebsstable )

    要使用链接器的???_start 和?_end 地址,.ebss 必须是连续的。 这就是我连接 GS2和 GS3存储器的原因。

    代码中

    #if defined (_debug)
    #include

    int _system_pre_init (void)

       extern int EbssSize、EbssStart;

       memset (EbssStart、0、(size_t)&ssSize);

       返回1;

    #endif

    Edward

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

    感谢您的快速响应。

    在我看来、您刚刚清除了.ebss 段、该段必须是连续的、因为您知道该器件中有两个 RAM 部分、即 M0&M1 SRAM 和 L0 SRAM。 2个 RAM 中的那些不是连续的、如何处理这2个 RAM?

    此外、如果我们只使用常规方法来清除 RAM、例如清除内部函数中的所有 RAM 内容、则会使堆栈内容崩溃、PC 将无法正常返回。 如果我们可以按照 Quark (在上面发布)的建议在 C 代码执行之前清除 RAM、那就更好了。 但该解决方案没有参考代码。

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

    清除.ebss 应该足以进行调试。

    您想要清除堆栈空间的原因是什么? 测量堆栈深度? 您可以从 CCS 存储器浏览器中清除所有存储器、然后再次重新加载代码、运行并查看堆栈增长的距离。

    CCS 引导例程位于 c:\ti\ccsv8\tools\compiler\ti-cgt-C2000-18.1.0.LTS lib\src\boot28.asm。 您无需编辑它。 您可以创建自己的内存清除例程、而不是进行编辑、而是使用前面的下范围将链接器设置中的入口点更改为您的例程、例如_MyStartup、然后在归零完成后跳转到 c_int00。

    void c_int00 (void);
    无效 MyStartup (无效)

    memset ((void*) 0x3000/*指定 RAM start*/、0、0x1000/* RAM 块大小*/);

    //针对不连续的 RAM 块重复 memset。

    asm (" MOV SP、#0x3000");//初始化 SP for c_int00 () C 调用、或使用 JUMP to c_int00指令*/
    c_int00();


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

    附件是我很久以前为28335修改的代码。

    请参阅第143行左右的函数"stack_fill"。 您可能需要修改__STACK_END 和__STACK_SIZE 符号以适合您的应用。

    此函数在第98行上调用。 请注意、c_init00会在后面的109行调用。

    e2e.ti.com/.../6242.CodeStartBranch.asm

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

    谢谢。 绝妙的创意。 能否在 c_int00之前显示如何运行 MystartUp? 下面是我想更改汇编代码的内容、您能帮您了解一下吗?

    WD_DISABLE:
    SETC OBJMODE ;为28x 目标代码设置 OBJMODE
    EALLOW ;启用 EALLOW 受保护寄存器访问
    MOVZ DP,#7029h>>>6;设置 WDCR 寄存器的数据页
    MOV @7029h、#0068h;将 WDCR 中的 WDDIS 位置位以禁用 WD
    EDIS ;禁用 EALLOW 受保护的寄存器访问
    ;LB _c_int00 ;分支到 RTS 库中 boot.asm 的启动
    LB _MyStartup

    清除所有 RAM 的原因是、我想构建一个标准平台、确保所有静态/全局变量为0。 但是、由于某些 RAM 位置用于不同的用途、.cmd 文件在不同的工程中是不同的、如果在初始化时未清除全局/静态变量、这将导致我的应用程序出现问题。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Quark、

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

    尊敬的 Jack:

    • 谢谢。 绝妙的创意。 能否在 c_int00之前显示如何运行 MystartUp? 下面是我想更改汇编代码的内容、您能帮您了解一下吗?

    我想我已经解释过了如何操作。 默认情况下,C2000链接器->高级选项->符号管理->指定程序入口点... =_c_int00。 在 C 语言中、您需要删除前导下划线:

    void c_int00 (void);

    因此、将链接器设置中的_c_int00替换为_MystartUp、然后在 C 中创建函数 void MystartUp (void)、该函数在 exit 时会调用 c_int00 ()。 由于是 C 语言,因此您可以从 MystartUp()调用 DisableDog (),根本不需要 ASM。 抱歉,我必须在 memset()上方插入栈初始化,但是,由于 ROM 初始化并使用栈,我认为堆栈初始化根本不是必需的。

    void c_int00 (void);
    无效 MyStartup (无效)

        asm (" MOV SP、#0x3000");// 指定 栈底地址 */

    DisableDog ();

    memset ((void*) 0x3000/*指定 RAM start*/、0、0x1000/* RAM 块大小*/);

    //针对不连续的 RAM 块重复 memset。

     c_int00();

    • 清除所有 RAM 的原因是、我想构建一个标准平台、确保所有静态/全局变量为0

    如果原因是标准归零,那么只清除.ebss 就足够了。 用于不同架构的任何其他 C 编译器只会清除 ebss 或 BSS。

    Edward

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

    这应该起作用,我将尝试你的建议。 谢谢。。。