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.

[参考译文] TMS320F28377D:为什么可以'我在没有仿真器的情况下独立使用串行端口来对 TMS320F28377D 进行编程?

Guru**** 2837190 points

Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1613666/tms320f28377d-why-can-t-i-use-the-serial-port-independently-to-program-tms320f28377d-without-the-emulator

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

我们公司开发了一台上层计算机,用于通过串行端口进行编程。 有两个用于刻录和读回版本的按钮。图 1 和图 2 分别显示了两个工作流程。 过程的每个步骤都由上层计算机发出的指令控制、28377 同时响应。

在刻录过程中、当 CPU2 闪存的整个芯片擦除时、无法收到 28377 的响应、从而导致刻录故障。 经检查发现没有删除任何数据。

在读取特定地址以获取版本的过程中、最后一个扇区出现不可读、因为在读取闪存地址 0x000BFFFA 和 0x000BFFF8 之后、28377 没有响应。

当使用模拟器刻录引导程序并发送指令以擦除整个芯片上的 CPU1 和 CPU2、然后使用串行端口再次刻录程序时、问题 1 和 2 被多次测试、不再重复。用于测试的软件和硬件完全相同。那么、如何独立使用串行刻录程序?

 

2a0653a4a4ac02dcffc7af7aa029c650.jpg

图 1.

 

 

图 2.

 

 

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

    是否可以共享在 CPU2 上运行的引导加载程序代码?  唯一需要注意的是、CPU2 尚未获取/获得闪存泵信标的控制权、因此不允许其擦除闪存。

    此致、

    Matthew

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

    很抱歉、我无法提供 CPU2 的源代码程序、因此我提供了一些函数的屏幕截图、希望这可以帮助您找到问题。

     

    这是 CPU2 的 CMD 文件。

     

    这是 CPU2 的主函数和初始化部分函数

      

     

    这是 CPU2 擦除闪存函数

     

     

    此函数是 CPU2 读取闪存数据的函数。

     

     

    此外、我还提供了 CPU1 的一些函数、以便从 CPU1 跳转到 CPU2。

     

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

    我有点落后在这里回答,我将看看你提供了什么和今天的答复.

    此致、

    Matthew

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

    好的、我将等待您的回复消息。

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

    您能告诉我哪个源文件具有 SeizeFlashPump 函数吗?  我在源文件中似乎找不到此函数。  CPU1 上应有相应的 IPC 接收命令、以便将泵的控制权交给 CPU2。

    此致、

    Matthew

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

    我们在 main 中将 SeizeFlashPump 函数称为。 c.在 BOOT_CPU2 函数中调用 ReleaseFlashPump 函数。

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

    Cheng、

    对不起,没有答复,我将需要更多的时间在这方面。  我会在第 17 点发言答辩。

    此致、
    Matthew

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

    我将等待您的信息,祝您度过一个美好的周末。

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

    Cheng、

    您是否在使用 C2000Ware 中的示例闪存内核、该示例位于:  

    C:\ti\c2000\C2000Ware_6_00_00_00\device_support\f2837xd\examples\dual\F2837xD/sci_flash_kernels\

    根据您的代码、我认为这是您正在使用的内容、但需要确保。

    我在 SCI_Boot.c 中看到了这个函数、您能否确认连接了哪些引脚用于 SCI 通信?  我想确保传递相同的引脚供 CPU2 在引导中使用

    void Assign_SCIA_IO_CPU2(Uint32 BootMode)
    {
        EALLOW;
        DevCfgRegs.CPUSEL5.bit.SCI_A = 1;    //SCIA connected to CPU2
        ClkCfgRegs.CLKSEM.all = 0xA5A50000;  //Allows CPU2 bootrom to take control
                                             //of clock configuration registers
        ClkCfgRegs.LOSPCP.all = 0x0007;
    
        if((BootMode & 0xF0) == 0x0)
        {
            //
            //OPTION 1
            //
            GPIO_SetupPinOptions(84, GPIO_OUTPUT, GPIO_ASYNC);
            GPIO_SetupPinMux(84,GPIO_MUX_CPU2,5);
            GPIO_SetupPinOptions(85, GPIO_INPUT, GPIO_ASYNC);
            GPIO_SetupPinMux(85,GPIO_MUX_CPU2,5);
        }
        else
        {
            //
            //OPTION 2
            //
            GPIO_SetupPinOptions(29, GPIO_OUTPUT, GPIO_ASYNC);
            GPIO_SetupPinMux(29,GPIO_MUX_CPU2,1);
            GPIO_SetupPinOptions(28, GPIO_INPUT, GPIO_ASYNC);
            GPIO_SetupPinMux(28,GPIO_MUX_CPU2,1);
        }
        EDIS;
    }

    为此、您是否在为用例移植时对该示例代码进行了任何修改?   

    此致、

    马特

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

    是的、我调用了函数 Assign _SCIA_IOU_CPU2 并进行了一些修改。 通过的参数 BootMode I 为 0。

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

    Cheng、

    由于我们正在处理 JTAG 工作/独立无法工作的问题;我想重点介绍代码中与时序相关的问题:

    这来自 CPU01 目录第 172 行中的 SCI_Boot.c。  我的更改由////////封装

     while(IPCLtoRFlagBusy(IPC_FLAG0) | IPCLtoRFlagBusy(IPC_FLAG31)){}
    
        CpuSysRegs.PCLKCR7.bit.SCI_A = 1;
        DevCfgRegs.SOFTPRES7.bit.SCI_A = 1;
    /////////////////////////////////////////////////////////
        DELAY_US(1000);  // Replace the short for-loop
    //////////////////////////////////////////////////////
        CpuSysRegs.PCLKCR7.bit.SCI_A = 0;
        DevCfgRegs.SOFTPRES7.bit.SCI_A = 0;
    /////////////////////////////////////////////////////////
        DELAY_US(1000);  // Replace the short for-loop
    //////////////////////////////////////////////////////
    
        Assign_SCIA_IO_CPU2(BootMode);
        assignSharedRAMstoCPU2();
    /////////////////////////////////////////////////////////
        DELAY_US(10000);  // Replace the short for-loop
    //////////////////////////////////////////////////////   
        //
        // CPU1 to CPU2 IPC Boot Mode Register
        //
        IpcRegs.IPCBOOTMODE = C1C2_BROM_BOOTMODE_BOOT_FROM_SCI;
    
        //
        // CPU1 to CPU2 IPC Command Register
        //
        IpcRegs.IPCSENDCOM = C1C2_BROM_IPC_EXECUTE_BOOTMODE_CMD;

    驱动程序包  

    第 124 行

        
      ////////////////////////////////////////////////////////
      GPIO_WritePin(31, 1);  // Prove CPU2 is running, you can change the pin based on your PCB
      for(x = 0; x < 100000; x++){}
      GPIO_WritePin(31, 0);
    /////////////////////////////////////////////////////////  
        Uint16 x = 0;
        for(x = 0; x < 32676; x++){}
        for(x = 0; x < 32676; x++){}
    
        IpcRegs.IPCBOOTSTS = C2_BOOTROM_BOOTSTS_SYSTEM_READY;
        while(IpcRegs.IPCBOOTMODE != C1C2_BROM_BOOTMODE_BOOT_FROM_SCI){}
    
        EINT; //enable global interrupt INTM
        ERTM; //enable global realtime interrupt

    然后在第 140 行重新初始化 SCI、以确保它不会损坏

    SeizeFlashPump();
        Init_Flash_Sectors();
        //put GetFunction here
    ///////////////////////////////////////////    
        SCIA_Init(SCI_BOOT);  // ADD THIS LINE
    //////////////////////////////////////////    
        uint32_t EntryAddr = SCI_GetFunction();
    
    //
    // Leave control over flash pump
    //
        SignalCPU1();
        return EntryAddr; //load entry address of application into
                          //RPC: return program counter
    }

    此致、
    Matthew

    您还需要添加以下原型:

    extern void SCIA_Init(UINT32 引导模式);
    extern void GPIO_WritePin (Uint32 引脚、Uint32 outVal);到 cpu02.c 文件

    让我们看看延长其中一些时序是否能在独立模式下正常工作。

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

    我成功找到了一个解决方案、即阻止以下图像中的代码。 当我保留程序的这一部分时、它会在这里崩溃。 阻止这部分代码后、可以通过 SCI 正常使用内部闪存擦除、读取和写入函数。 我想你可以告诉我这个问题的原因,谢谢你。

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

    Cheng、

    感谢您提供这些信息、这确实解释了问题。   

    Fapi_issueAsyncCommandWithAddress 在返回前不会等到操作(在这种情况下为闪存擦除)完成。  由于在此之后会立即调用空白检查、因此不能保证擦除完成。  因此、在这种情况下、空白检查会停止或失败。

    使用任何 ASYNC 命令的正确实现是在执行另一个 API 调用之前检查 FSM 以确保其不处于繁忙状态、如以下代码所示。

    如果在异步命令之后将 while (Fapi_checkFsmForReady ()...) 插入代码、这也应该会修复内容。

    此致、

    Matthew

    oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,
                       (uint32 *)Bzero_SectorC_start);
    
        //
        // Wait until FSM is done with erase sector operation.
        //
        while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady)
        {
        }
    
        //
        // Verify that Sector C is erased. The erase step itself does verification
        // as it goes. This verify is a second verification that can be done.
        //
        oReturnCheck = Fapi_doBlankCheck((uint32 *)Bzero_SectorC_start,
                       Bzero_16KSector_u32length,
                       &oFlashStatusWord);