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.

[参考译文] SM320F28335-Flash:SM320F28335-Flash EP、EP Programming Issue

Guru**** 2874030 points

Other Parts Discussed in Thread: C2000WARE, TMS320F28335, TMP1075

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1621410/sm320f28335-ep-sm320f28335-ep-flash-programming-issue

器件型号: SM320F28335-SM320F2833 EP
主题中讨论的其他器件: TMS320F28335、C2000WARE、 TMP1075

您好 TI 社区、

我正在开发一款 TMS320F28335 ECU 项目 Code Composer Studio (CCS) 我一直在努力解决闪存执行问题。 非常感谢您的帮助。

  我的设置:

  • 器件: SM320F28335- EP
  • IDE: Code Composer Studio (CCS) v20.3.1.5
  • 构建模式: 闪存中
  • 使用的外设: CAN-A、I2C-A、SPI (EEPROM)、ADC、EPWM、 GPIO

 

 问题:

  • 运行代码 完美处于 RAM 调试模式
  • 输出代码转换为低输出 闪存中 、设备将在停止 ILLIGAL_ISR 挂起或崩溃 初始化期间调用
  • CPU 不会到达while(1)主循环

 

ECUV3 flash.c (2).zip

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

    查看此示例: C:\ti\c2000\C2000Ware_6_00_00\device_support\F2833x\examples\flash_F28335。  

    当您从闪存运行时、代码中可能有一个仍然映射到 SRAM 的区域(并且很可能有)。  这样做的原因是 RAM 可以在完整 150MHz 下运行、当闪存被等待时、通常 ISR 保留在 RAM 中。

    无论如何、在.cmd 文件中、您应该会看到一段代码(通常调用 ramfuncs 或 tiramfuncs)、它具有对闪存的加载功能、但从 RAM 运行。  然而,这只是需要发生的事情的一部分。  另一部分在设置代码中、应该会对 memcopy 进行函数调用;其中代码从闪存复制到 RAM、然后才能运行。

    如果缺少此代码、那么 RAM 将没有任何代码、当您的程序尝试执行程序代码时、它将获得非法的操作码、因此是非法的 ISR。

    无论如何、查看上面路径中的示例代码和.cmd、并相应地更正您的代码/

    此致、

    Matthew

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

    您好、Matthew Pate、

    今天、我导入了 FLASH_F28335。  示例代码并尝试将其编程到 MCU。 但是,我仍然面临着相同的问题 — 程序将进入非法的 ISR。

    按照建议、我使用相同的方法 flash.cmd 项目中生成一个自举文件。 在我的主应用程序代码中、我完全实现了闪存示例中所示的配置、但问题仍未解决。

    为了供您参考、我附上了我的 main.c flash.cmd 和完整的项目文件(。 您能否回顾一下这些问题并帮助我确定可能导致此问题的原因?

    感谢您的支持。

    代码链接

    或 https://drive.google.com/drive/folders/12BsnElCT1Or0PcHcupE04FwNJmn2kfw-?usp=drive_link)  

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

    恶劣、

    我仍在查看您上传的项目/来源、到目前为止我没有发现任何内容。   

    在 PCB 上、您能否确认器件的输入时钟频率?  我想在这里排除超频可能是根本原因。

    此致、

    Matthew

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

    您好 Matthew、

    感谢您查看工程和源文件。

    在我们的 PCB 上、我们使用 25MHz 晶体时钟 EP 器件的输入时钟。 如果您需要我们这边的任何其他硬件详细信息或测量、敬请告知。

    此致、
    恶劣

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

    恶劣、

    我认为游戏中可能存在非常微妙的代码问题。  对于您正在调用的存储器副本:

    memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(Uint32)&RamfuncsLoadSize);

    C 标准库函数。

    您能否将其替换为 TI 定义的函数:

    Memcopy (&RamfuncsLoadStart、&RamfuncsLoadEnd、&RamfuncsRunStart);

    看看这是否能解决问题。

    此致、

    Matthew

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Matthew、
    感谢您的建议。
    我已经 memcpy  MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart); 按照您的建议将此函数替换为 TI 定义的函数。
    我验证了在调试模式下刷写时代码运行正常。
    但是、当我关闭主板电源并重新打开电源时、系统无法正常引导。
    请确认 PLL 配置值是否正确。 我将 25MHz 晶体用于系统时钟。
     我将继续调试、但如果您建议进行任何其他检查或提供建议、请告知我。
    #define DSP28_PLLCR 4.
    #define DSP28_DIVSEL  1.
    #define CPU_RATE 10.000L  //以实现 100MHz CPU 时钟速度 (SYSCLKOUT)
    void main (void)
    //初始化系统控制
      InitSysCtrl();
      
      //禁用 CPU 中断
       DINT;
       InitPieCtrl();
       IER = 0x0000;
       IFR = 0x0000;
           Memcopy (&RamfuncsLoadStart、&RamfuncsLoadEnd、&RamfuncsRunStart);
     
      ////
      ////调用闪存初始化以设置闪存等待状态
      ////这个函数必须驻留在 RAM 中
      ////
       InitFlash();


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

    Harshath

    您能否检查以下引导引脚、以确保它们都在您的电路板上被拉至“高电平“、从而将引导调用到闪存

    此外、对 PLL 设置进行小幅校正。

    目前、您已经指定了 PLLCR = 4(乘以 4)、并且 DIVSEL=1(这除以 4)、所以最终将得到 25MHz SYSCLK。

    对于 100MHz、您需要使用以下设置:

    #define DSP28_PLLCR 8.
    #define DSP28_DIVSEL   2.
    这将得出 25MHz * 8/2 = 100MHz。
    我认为你打算用你的原始设置是 25 *4/1.  在本例中为 DIVSEL = 3。不过、如果使用 PLL、我们不允许/1 (DIVSEL = 3)、那么我们必须使用/2 或/4。
    请告诉我。
    此致、
    Matthew
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Matthew、
    感谢您的建议。
    正如您提到的、我更新了 PLL 设置 (PLLCR = 8 和 DIVSEL = 2)。 但是、使用这些值时、代码会在停止 非法 ISR。
    当我使用以下设置时:

    #define DSP28_PLLCR 6.
    #define DSP28_DIVSEL 2.
    代码运行时不会出现任何问题。
    我还观察到、当我对闪存进行编程并在调试模式下运行代码时、它可以正常工作。 但是、在下电上电(关闭和打开电源)后、代码无法从闪存正确引导。
    您能帮助我了解为什么会出现此问题吗?
    谢谢。此致、
    Harshath
    974334682.
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Harshath

    您能像以前一样通过驱动器附加最新的代码源吗?

    此致、

    Matthew

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Matthew、
    请参阅我之前通过 Drive 共享的相同代码库。 我只对 main 函数进行了更改、并更新了一些 PLL 值。 为了供您参考、我附上了下面更新后的代码。
    在当前配置下、闪存工作正常、我不会遇到任何问题。 大家知道、我的外部振荡器频率是 25MHz。 我正在尝试在 125MHz 或 150MHz 运行系统时钟。
    您能指导我如何正确配置系统以实现 150MHz SYSCLK 吗? 如果需要对时钟晶体或配置进行任何更改、请告知我、我们已准备好进行必要的修改。
    此外、在调试此问题时、我犯了错误、 两个 MCU 上每 5ms 启用一次内部看门狗、 并且我们在故障排除过程中更换了 MCU。
    我期待您提供有关在闪存引导模式下实现 150MHz 稳定运行的指导。
    此致、
    哈沙特  
     
    //////必须从 RAM 运行的函数(闪存功耗操作或时间关键型)
     #ifdef _TI_COMPILER_VERSION__
      #if __TI_COMPILER_VERSION_>= 15009000
        #pragma CODE_SECTION (ecana_ISR、“.TI.ramfunc")“);
    //     //在此处添加任何其他触及闪存功率寄存器的 ISR
      #else
       pragma CODE_SECTION (ecana_isr、“ramfuncs")“);
       #endif
     #endif
     
     
    ////这些是由链接器定义的(请参阅 F28335.cmd)
    ////
     extern Uint16 RamfuncsLoadStart;
     extern Uint16 RamfuncsLoadEnd;
     extern uint16 RamfuncsRunStart;
     extern Uint16 RamfuncsLoadSize;
     
     
     
     
    uint16 write_word = 0x1234;
    uint16 READ_WORD = 0;
     uint16 abc = 0;
    void main (void)
      //变量声明
       uint16_t i;
      uint32_t txMailbox[2]={1、2};
      uint32_t txIDs[2]={0x100、0x101};
      int tmp1075_status;
      
      //初始化系统控制
      InitSysCtrl();
      
      //禁用 CPU 中断
       DINT;
       InitPieCtrl();
       IER = 0x0000;
       IFR = 0x0000;
      Memcopy (&RamfuncsLoadStart、&RamfuncsLoadEnd、&RamfuncsRunStart);
     
       InitFlash();


      InitPieVectTable();
     
      //设置中断向量
      EALLOW;
      PieVectTable.ECAN0INTA =&ecana_isr;
      //PieVectTable.I2CINT1A =&i2c_int1a_ISR;
      SysCtrlRegs.PCLKCR0.bit.ECANAENCLK = 1;
      SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1;  //启用 I2C 时钟
      EDIS;
     
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    恶劣、

    1) 在您的 Ecanmain.c 中、此处是 TI Memcopy 的正确语法(您可能已经完成了此操作,但只是刚刚完成)

     Memcopy (&RamfuncsLoadStart、&RamfuncsLoadEnd、&RamfuncsRunStart);

    这与 memcpy 具有不同的参数、用于获取启动、加载开始和加载大小。  我认为、只要您给 memcpy 提供了正确的变量、可能也可以、但我们坚持以上内容。

    2) 对于具有所需 100MHz SYSCLK 的 10MHz 输入时钟、DSP2833x_Examples.h 线路 53 - 71 应该如此

    // Specify the PLL control register (PLLCR) and divide select (DIVSEL) value.
    //
    //#define DSP28_DIVSEL   0   // Enable /4 for SYSCLKOUT
    //#define DSP28_DIVSEL   1 // Enable /4 for SYSCKOUT
    #define DSP28_DIVSEL     2 // Enable /2 for SYSCLKOUT
    //#define DSP28_DIVSEL     3 // Enable /1 for SYSCLKOUT
    
    //#define DSP28_PLLCR   10
    //#define DSP28_PLLCR    9
    #define DSP28_PLLCR    8
    //#define DSP28_PLLCR    7
    //#define DSP28_PLLCR    6
    //#define DSP28_PLLCR    5
    //#define DSP28_PLLCR    4
    //#define DSP28_PLLCR    3
    //#define DSP28_PLLCR    2
    //#define DSP28_PLLCR    1
    //#define DSP28_PLLCR    0  // PLL is bypassed in this mode
    

    和第 103-113 行用于将时钟设置为 10ns 周期

    //#define CPU_RATE    6.667L   // for a 150MHz CPU clock speed (SYSCLKOUT)
    //#define CPU_RATE    7.143L   // for a 140MHz CPU clock speed (SYSCLKOUT)
    //#define CPU_RATE    8.333L   // for a 120MHz CPU clock speed (SYSCLKOUT)
     #define CPU_RATE   10.000L   // for a 100MHz CPU clock speed (SYSCLKOUT)
    //#define CPU_RATE   13.330L   // for a 75MHz CPU clock speed (SYSCLKOUT)
    //#define CPU_RATE   20.000L   // for a 50MHz CPU clock speed  (SYSCLKOUT)
    //#define CPU_RATE   33.333L   // for a 30MHz CPU clock speed  (SYSCLKOUT)
    //#define CPU_RATE   41.667L   // for a 24MHz CPU clock speed  (SYSCLKOUT)
    //#define CPU_RATE   50.000L   // for a 20MHz CPU clock speed  (SYSCLKOUT)
    //#define CPU_RATE   66.667L   // for a 15MHz CPU clock speed  (SYSCLKOUT)
    //#define CPU_RATE  100.000L   // for a 10MHz CPU clock speed  (SYSCLKOUT)

    现在在第 120 - 126 行、您将看到一个#if (compile time if)、它正在查找器件定义以定义器件是 150MHz 还是 100MHz。  

    #if DSP28_28332 || DSP28_28333  // 28332 and 28333 devices only
      #define CPU_FRQ_100MHZ  1     // 100 Mhz CPU Freq (20 MHz input freq)
      #define CPU_FRQ_150MHZ  0
    #else
      #define CPU_FRQ_100MHZ  0  // DSP28_28335||DSP28_28334
      #define CPU_FRQ_150MHZ  1  // 150 MHz CPU Freq (30 MHz input freq) by DEFAULT
    #endif

    我们可以将其用于我们的优势、因为您仍然在 100MHz 计时(即使您有支持 150MHz 的设备)、因为在其他一些地方使用#if 来缩放时钟。  但是、对它的控制不是预定义、而是在 DSP2833x_Device.h 中、在我们进行更改并重新编译后、我们希望 100MHz #define 变为灰色。  Device.h 第 61-64 行

    #define   DSP28_28335   0        // Selects '28335/'28235
    #define   DSP28_28334   0         // Selects '28334/'28234
    #define   DSP28_28333   0         // Selects '28333/'
    #define   DSP28_28332   TARGET         // Selects '28332/'28232

    这应该会设置代码和放置都能正常工作。  我已经验证代码已正确置于闪存入口点 0x33 FFF6 - 0x33 FFF7、最终将调用 main。  我还验证了代码是否正确复制了 RAM 并从中执行。

    只要将引导模式引脚正确设置为引导至闪存、我们在调试期间看到的代码就应该与独立运行的代码完全匹配。

    此致、
    Matthew