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.

[参考译文] TMS320F28069:从闪存运行时模拟闪存中的 EEPROM

Guru**** 2562120 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/998827/tms320f28069-emulating-eeprom-in-flash-while-running-from-flash

器件型号:TMS320F28069
主题中讨论的其他器件:C2000WARE

您好!

´ve、我一直在尝试使用 F28069微控制器将此处详述的 EEPROM 仿真实现到制动模块中。 实际上、我希望在闪存中保存一些用户定义的参数、以便不必在每个开/关周期后设置这些参数。  

经过一些修改后、我设法使 EEPROM 仿真正常工作、同时添加我自己的函数来替换 EEPROM_Write()和 EEPROM_Read()、因为它们并不完全满足我的需求。 事情是程序在调试模式下工作正常、但每当我将其加载到制动模块并从闪存运行时、它会突然停止向我为 EEPROM 仿真定义的闪存扇区写入任何内容。 我 怀疑、由于程序本身从闪存运行、它会干扰闪存 API 函数。 此外、还有几个来自 ADC、CPU 计时器和 ePWM 的中断变得模糊;因此、我还担心这些相同的中断会阻止闪存编程。

在闪存 API 将数据编程到闪存扇区中时、是否有任何方法可以在短时间内停止所有中断和/或闪存操作? 这听起来是否有任何修复方法、或者我是否应该专注于在我的设计中实现实际的 EEPROM?

非常感谢您提供的任何帮助。

谢谢、

Michael

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

    Michael、
    我将为位于 C2000Ware 中的 F2806x 导入 FLASH_API 示例工程、如下所示:

    C:\ti\c2000Ware_3_04_00_00\libraries\flash_api\f2806x\example_Flash2806x_API

    在对闪存/ OTP 阵列进行编程/擦除之前、主要需要考虑的问题是。

    对于您的直接问题、C28x 内核寄存器中有一个全局中断启用/禁用。

    我们已在 Device.h 中设置了一个别名、您可以从 C 调用该别名作为"DINT" 执行汇编指令 SETC INTM、它设置 INTM (中断屏蔽)位。  这将取代任一 PIE 使能、但如果您想保留某些中断而不是全局禁用所有中断、也可以禁用/启用 PIE。

    此外、正确的是、在从闪存/ OTP 执行时、不能对闪存/ OTP 进行编程/擦除。  对于 F2806x、我们已经将闪存 API 放置在 ROM 中、这样您就不需要使用 RAM 或将闪存复制到 RAM 来获得 API 源。  以上示例将使用此映射、因此您可以在代码中重复使用。

    如果您有其他问题、请告诉我。

    最棒的

    Matthew

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

    Matthew、

    感谢您指引我正确的方向。 我之前已经检查过闪存 API 库中的示例文件、但再次通读它让我对可能出现的问题有了一些了解。 具体而言、我认为解锁 CSM 模块可以实现这一目的。

    另一个注意事项。 是否在启动时将整个项目从闪存/ OTP 移动到 SARAM? 由于代码从闪存运行、我不确定在正常运行期间如何能够写入闪存。 我已经尝试将所有时间关键型函数移动到 ramfuncs、但这似乎根本没有帮助。 我想编写一个函数、在对闪存进行编程之前、暂停所有中断服务和直接从闪存运行的任何代码。 如前所述、使用 DINT 和 EINT 宏可以直接停止中断、但我不清楚如何或是否可以在将用户变量编程到闪存时短暂停止闪存操作。

    再次感谢您的帮助。

    此致、

    Michael

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

    Michael、

    在.cmd 文件内、您将看到一个标记为"ramfuncs"的段和如下所示的指令:

    ramfuncs            : LOAD = FLASHA, 
                             RUN = PRAML0, 
                             LOAD_START(_RamfuncsLoadStart),
                             LOAD_END(_RamfuncsLoadEnd),
                             RUN_START(_RamfuncsRunStart),
                             PAGE = 0

    这是一个指令、用于告知链接器代码将加载到闪存中、但希望从 RAM 运行代码。  这是从 RAM 运行所需的2个器件中的第一个器件。

    第二部分发生在主 C 文件内,并通过函数调用 example_Memcopy()函数:

    Example_MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
    
    void Example_MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr)
    {
        while(SourceAddr < SourceEndAddr)
        { 
           *DestAddr++ = *SourceAddr++;
        }
        return;
    }
    

    这会传递我们在链接时分配给 ramfuncs 的符号、并将闪存中当前的数据复制到 RAM。  一旦完成此操作、一旦我们调用该区域中的函数、链接器将会进行必要的偏移、以调用代码的 RAM 版本与闪存版本。  只要我们保持在链接器中分配给 ramfuncs 的代码中、我们就会避免在对闪存进行编程时从闪存中执行代码。

    最棒的

    Matthew

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

    Matthew、

    谢谢!

    我设法解决了这个问题。 我n´t string.h 中的 memcpy()将 ramfuncs 复制到 ram 中,这显然不起作用。 我使用了 example_Memcopy(),这似乎是为了达到目的。 我还删除了 EEPROM.c 和 EEPROM.h 文件、并用我自己的函数、变量和主程序中的 defs 及其相应的头文件替换了它们。 我´m 了它们,所以我不能超级确定它是否只是 memcpy(),但我对它有一个很高的把握。