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.

[参考译文] TMS320F28379D:独立模式下的闪存写入

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

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1047885/tms320f28379d-flash-writing-in-standalone-mode

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

您好!

在我的软件中、我使用的是 CPU1和 CPU2。 每个内核的程序被加载到闪存上。 我将使用以下指令来使用独立模式:  

IPCBootCPU2 (C1C2_Brom_BOOTMODE_BOOT_FROM _FLASH);

在我的程序期间、我需要在专用闪存(闪存 J)中写入一些值。

当我处于调试模式时(当我不使用之前的指令时)、它可以正常工作、但当我处于独立模式时(我猜当我调用闪存写入(或擦除)函数时、程序会停止)、它不能正常工作。

您是否有办法解决此问题?

感谢您的反馈。

此致、

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

    您好!  

    当您写入 CPU2闪存组中的扇区 J 时是否会发生此问题? IPC 引导函数在哪里被调用?

    谢谢、  

    Anu

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

    Anu、您好!

    问题未链接到 CPU2。 为了理解这个问题,我没有加载 CPU2程序,我只能:  

    -已加载 CPU1程序
    -删除了指令  IPCBootCPU2 (C1C2_Brom_BOOTMODE_BOOT_FROM _FLASH);
    - 已删除所有 IPC 标志

    当我重新启动 CPU1时、它 在我调用闪存写入(或擦除)函数时停止。
    我不明白为什么? 当我处于调试模式(重新启动之前)时、闪存功能工作正常。
    当我删除闪存功能时、CPU1在重新引导后工作良好。

    感谢您的反馈。

    此致、

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

    您好!  

    闪存 API 是否与.TI.ramfunc 一同复制到 RAM 中? 这应该在链接器命令文件中完成。  

    谢谢、  

    Anu

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

    您好!

    是的,我在链接器命令文件中执行了该操作:  

    #ifdef __TI_COMPILER_VERSION__
        #if __TI_COMPILER_VERSION__ >= 15009000
            GROUP
            {
                .TI.ramfunc
                { -l F021_API_F2837xD.lib}
    
            } LOAD = FLASHABCDEFG,
              RUN  = RAMLS03,
              LOAD_START(_RamfuncsLoadStart),
              LOAD_SIZE(_RamfuncsLoadSize),
              LOAD_END(_RamfuncsLoadEnd),
              RUN_START(_RamfuncsRunStart),
              RUN_SIZE(_RamfuncsRunSize),
              RUN_END(_RamfuncsRunEnd),
              PAGE = 0
        #else
            GROUP
            {
                ramfuncs
                { -l F021_API_F2837xD.lib}
    
            } LOAD = FLASHABCDEFG,
              RUN  = RAMLS03,
              LOAD_START(_RamfuncsLoadStart),
              LOAD_SIZE(_RamfuncsLoadSize),
              LOAD_END(_RamfuncsLoadEnd),
              RUN_START(_RamfuncsRunStart),
              RUN_SIZE(_RamfuncsRunSize),
              RUN_END(_RamfuncsRunEnd),
              PAGE = 0
        #endif
    #endif


    问题是否来自我调用函数的顺序?

    void Init (void)
    {
        memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (uint32_t)&RamfuncsLoadSize);
    
        InitSysCtrl();
    
        IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);
        
        InitFlash();
        
        DINT;
    
        InitPieCtrl();
    
        EALLOW;
        IER = 0x0000;
        IFR = 0x0000;
        EDIS;
    
        InitPieVectTable();
    
        SeizeFlashPump();
    }

    void InitSysCtrl(void)
    {
        //
        // Disable the watchdog
        //
        DisableDog();
    
        EALLOW;
    
        //
        // Enable pull-ups on unbonded IOs as soon as possible to reduce power
        // consumption.
        //
        GPIO_EnableUnbondedIOPullups();
    
        CpuSysRegs.PCLKCR13.bit.ADC_A = 1;
        CpuSysRegs.PCLKCR13.bit.ADC_B = 1;
        CpuSysRegs.PCLKCR13.bit.ADC_C = 1;
        CpuSysRegs.PCLKCR13.bit.ADC_D = 1;
    
        //
        // Check if device is trimmed
        //
        if(*((Uint16 *)0x5D1B6) == 0x0000){
            //
            // Device is not trimmed--apply static calibration values
            //
            AnalogSubsysRegs.ANAREFTRIMA.all = 31709;
            AnalogSubsysRegs.ANAREFTRIMB.all = 31709;
            AnalogSubsysRegs.ANAREFTRIMC.all = 31709;
            AnalogSubsysRegs.ANAREFTRIMD.all = 31709;
        }
    
        CpuSysRegs.PCLKCR13.bit.ADC_A = 0;
        CpuSysRegs.PCLKCR13.bit.ADC_B = 0;
        CpuSysRegs.PCLKCR13.bit.ADC_C = 0;
        CpuSysRegs.PCLKCR13.bit.ADC_D = 0;
        EDIS;
    
        InitSysPll(XTAL_OSC, IMULT_20, FMULT_0, PLLCLK_BY_2);
    
        //
        // Turn on all peripherals
        //
        InitPeripheralClocks();
    }

    此致、

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

    函数调用的顺序与 F2837xD 的 C2000Ware 中提供的 FLASH_programming_cpu01示例不同。 您能否浏览该示例以查看示例并按照示例所做的相同方式调用初始化函数中的函数、并查看问题是否得到解决?

    谢谢、  

    Anu

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

    Anu、您好!

    我更改了函数的顺序、如 FLASH_programming_cpu01 示例中的顺序。 它无法解决问题。

    它实际上与闪存 API 函数相关联。

    此致、

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

    您能否分享闪存 API 的初始化方式以及函数在映射文件中的位置?

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

    Anu、

    我不理解您的第二个请求“函数放置在映射文件中的什么位置”;是否需要我的所有链接器文件?

    我共享函数(SaveCPU1DSPParameters (void)),其中我在指定的闪存(闪存 J)中写入数据;如前所述,操作非常奇怪:  

    -当我重新启动 CPU1时, 它在我调用 此函数时停止。
    -当我处于调试模式(在重新启动之前)时,此函数 运行良好。
    -当我删除 此函数时,CPU1在重新引导后工作良好。

    void SaveCPU1DSPParameters(void)
    {
    
        // ---------- Declaration ----------
    
        int TableIndex, Index2;
        Fapi_StatusType oReturnCheck;
        Fapi_FlashStatusWordType oFlashStatusWord;
        Uint32 address;
        Uint16 count, moduloResult;
    
        // ---------- Code ----------
    
        //
        // This function is required to initialize the Flash API based on System
        // frequency before any other Flash API operation can be performed
        //
        oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 200);
    
        if(oReturnCheck != Fapi_Status_Success) {}
    
        //
        // Fapi_setActiveFlashBank function sets the Flash bank and FMC for further
        // Flash operations to be performed on the bank
        //
        oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
        if(oReturnCheck != Fapi_Status_Success) {}
    
        address = FlashptrDSP;
        count = 0;
    
        if((NV_DSP_BASE_ADDRESS + NV_DSP_MAX_USE - (long) FlashptrDSP) < (NB_OF_PARAMETER_DSP * NB_OF_TABLES + FLASH_MARGIN))
        {
            oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32 *)Bzero_SectorJ_start);
    
            while(Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
    
            oReturnCheck = Fapi_doBlankCheck((uint32 *)Bzero_SectorJ_start, Bzero_16KSector_u32length, &oFlashStatusWord);
    
            if(oReturnCheck != Fapi_Status_Success) {}
    
            FlashptrDSP = (Uint16*)(NV_DSP_BASE_ADDRESS);
            address = FlashptrDSP;
        }
    
        EDIS;
    
        // Sensor 1
    
        // Check FFFF
        for (TableIndex = 0; TableIndex < NB_OF_TABLES; TableIndex++)
        {
            for (Index2 = 0; Index2 < NB_OF_PARAMETER_DSP; Index2++)
            {
                DSPParameter_S1[TableIndex][Index2] = (DSPParameter_S1[TableIndex][Index2] == 0xFFFF) ? 0xFFFE : DSPParameter_S1[TableIndex][Index2];
            }
        }
    
        // Program new settings for sensor 1
        for (TableIndex = 0; TableIndex < NB_OF_TABLES; TableIndex++)
        {
            while (address < FlashptrDSP + NB_OF_PARAMETER_DSP)
            {
                FLASH_WriteData_4_words( address, &DSPParameter_S1[TableIndex][count]);
                address += 4;
                count += 4;
            }
    
            count = 0;
            moduloResult = address % 4;
            if (moduloResult !=0 ) { address += (4 -moduloResult); }
            FlashptrDSP = address;
        }
    }

    等待您的反馈。

    此致、

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

    映射文件应该在您在项目中使用的构建配置之后命名的文件夹中可用。  

    例如、它将位于此处的 CPU1_FLASH 文件夹中、扩展名为.map:

    您能否在此处查看闪存 API 函数的映射位置? 此外、您能否检查 FLASH_WriteData_4_words 函数的映射位置? 它应该被映射到 RAM。  

    此外、请查看此常见问题解答:https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/951668/faq-faq-on-flash-api-usage-for-c2000-devices 

    谢谢、  

    Anu

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

    Anu、

    我认为我发现了这个问题;在 Fapi_initializeAPI 指令之前缺少了指令 EALLOW。

    这是问题吗? 为什么它在调试模式下工作而不是在独立模式下工作?

    但现在我有一个与 CPU2相关的新问题,更精确 地将 eFlashPump();函数在我的 Init(void)中
    当我不添加此行时、程序正在运行、但在重新引导后无法在 CPU2的闪存 J 中写入数据。
    当我添加此行时、程序在某个位置停止、可能在 CPU2中的函数 SaveCPU2DSPParameters 中停止
    (CPU1和 CPU2之间的闪存的所有函数相同)。

    CPU1和 CPU2之间是否存在闪存功能的同步问题?
    此函数(SeizeFlashPump();)必须是 exe"由 CPU1和 CPU2标记的?

    等待您的反馈。

    此致、

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

    缺失的 EALLOW 可能是问题、我需要检查它为什么不在独立模式下工作。  

    除了电子闪存泵之外、是否调用 ReleaseFlashPump? 两者都是必需的。  

    谢谢、  

    Anu

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

    Anu、您好!

    我在 每个之前函数(SaveCPU1DSPParameters 和 SaveCPU2DSPParameters)的末尾为 CPU1和 CPU2添加了 ReleaseFlashPump()函数。
    我还在 每个函数的开头添加了 SeizeFlashPump()。

    我将在星期一进行测试以测试这些修改,但另一个问题是:可否    同时在 CPU1和 CPU2上调用函数 SeizeFlashPump()和 ReleaseFlashPump()?

    感谢您的反馈。

    此致、

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

    闪存泵一次只能由一个 CPU 控制。  更多信息、请参阅 F2837xD TRM 的第3.12.4节。  

    谢谢、  

    Anu

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

    Anu、您好!

    感谢您的反馈。

    我使用 IPC 标志为 CPU1使用闪存泵、然后为 CPU2使用闪存泵。 但它似乎不适用于 CPU2 (没有值写入 CPU2闪存)。

    CPU1 program :
    
    SeizeFlashPump();
    
    SaveCPU1DSPParameters() function (see above)
    
    ReleaseFlashPump();
    
    IPCLtoRFlagSet(IPC_FLAG8);

    CPU2 program :
    
    while(!IPCRtoLFlagBusy(IPC_FLAG8));
    
    SeizeFlashPump();
    
    SaveCPU2DSPParameters() function (same function than SaveCPU1DSPParameters() (see above))
    
    ReleaseFlashPump();
    
    IPCRtoLFlagAcknowledge(IPC_FLAG8);
    IPCLtoRFlagClear(IPC_FLAG8);


    CPU2定义为 CPU2的预分版符号。

    我是否还需要为 InitSysCtrl()使用 IPC 标志;为 CPU1和 CPU2使用 IPC 标志? (可能 是 InitSysCtrl();对于 CPU1,必须在 InitSysCtrl()之前执行;对于 CPU2,必须执行)

    谢谢。

    此致、

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

    IPC 示例应该是查看如何在 CPU1和 CPU2之间调用 InitSysCtrl 的好来源、您可以参阅这些示例以查看 InitSysCtrl 的调用顺序。  

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

    Anu、

    IPC 示例中没有指示如何调用 InitSysCtrl;FLASH_programming_cpu01和 CPU_02也是如此,这就是我向您提出要求的原因。

    此致

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

    您好!  

    我查看了您提到的示例、从这两个示例中、我认为可以推断 InitSysCtrl 例程需要首先由 CPU1调用、因为它负责 PLL 初始化。 CPU2函数调用只会禁用看门狗并将闪存设置代码复制到 RAM、因此需要首先调用 CPU1的 InitSysCtrl 函数。  

    谢谢、  

    Anu