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.

[参考译文] TMS320F28386S:串行闪存编程器和 SCI_Boot ()看起来不同步

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1204051/tms320f28386s-serial-flash-programmer-and-sci_boot-seem-out-of-sync

器件型号:TMS320F28386S

在函数 SCI_Boot 第119行中,它正在从数据包中查找关键字,然后通过 ReadReservedFn ()抛出16个字节。

uint32_t SCI_Boot(uint32_t bootMode)
{
    uint32_t entryAddress;
    uint16_t byteData;

    //
    // CPU1 Patch/Escape Point 13
    //
    entryAddress = CPU1BROM_TI_OTP_ESCAPE_POINT_13;
    if((entryAddress != 0xFFFFFFFFUL) &&
       (entryAddress != 0x00000000UL))
    {
        //
        // If OTP is programmed, then call OTP patch function
        //
        ((void (*)(void))entryAddress)();
    }

    //
    // Check if SCI is enabled on device or not
    //
    if((HWREG(DEVCFG_BASE + SYSCTL_O_DC8) & SYSCTL_DC8_SCI_A) == 0U)
    {
        return(FLASH_ENTRY_POINT);
    }

    //
    // Assign GetWordData to the SCI-A version of the
    // function. GetWordData is a pointer to a function.
    //
    GetWordData = SCIA_GetWordData;

    //
    // Initialize the SCI-A port for communications
    // with the host.
    //

    //
    // Enable the SCI-A clocks
    //
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIA);
    SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_4);

    EALLOW;
    HWREGH(SCIA_BASE + SCI_O_FFTX) = SCI_FFTX_SCIRST;

    //
    // 1 stop bit, No parity, 8-bit character
    // No loopback
    //
    HWREGH(SCIA_BASE + SCI_O_CCR) = (SCI_CONFIG_WLEN_8 | SCI_CONFIG_STOP_ONE);
    SCI_setParityMode(SCIA_BASE,SCI_CONFIG_PAR_NONE);

    //
    // Enable TX, RX, Use internal SCICLK
    //
    HWREGH(SCIA_BASE + SCI_O_CTL1) = (SCI_CTL1_TXENA | SCI_CTL1_RXENA);

    //
    // Disable RxErr, Sleep, TX Wake,
    // Disable Rx Interrupt, Tx Interrupt
    //
    HWREGB(SCIA_BASE + SCI_O_CTL2) = 0x0U;

    //
    // Relinquish SCI-A from reset and enable TX/RX
    //
    SCI_enableModule(SCIA_BASE);

    EDIS;

    //
    // GPIO INIT
    //
    SCIBOOT_configure_gpio(bootMode);

    //
    // CPU1 Patch/Escape Point 13
    //
    entryAddress = CPU1BROM_TI_OTP_ESCAPE_POINT_13;
    if((entryAddress != 0xFFFFFFFFUL) &&
       (entryAddress != 0x00000000UL))
    {
        //
        // If OTP is programmed, then call OTP patch function
        //
        ((void (*)(void))entryAddress)();
    }

    //
    // Perform autobaud lock with the host.
    // Note that if autobaud never occurs
    // the program will hang in this routine as there
    // is no timeout mechanism included.
    //
    SCI_lockAutobaud(SCIA_BASE);

    //
    // Read data
    //
    byteData = SCI_readCharBlockingNonFIFO(SCIA_BASE);

    //
    // Configure TX pin after autobaud lock
    // (Performed here to allow SCI to double as wait boot)
    //
    GPIO_setPadConfig(SCI_gpioTx,GPIO_PIN_TYPE_PULLUP);
    GPIO_setPinConfig(SCI_gpioTxPinConfig);

    //
    // Write data to request key
    //
    SCI_writeCharNonBlocking(SCIA_BASE,byteData);

    //
    // If the KeyValue was invalid, abort the load
    // and return the flash entry point.
    //
    if(SCIA_GetWordData() != SCI_DATA_WORD_KEY)
    {
        return FLASH_ENTRY_POINT;
    }

    ReadReservedFn();

    entryAddress = GetLongData();

    CopyData();

    return entryAddress;
}

在 serial_flash_programr.cpp 中、在解析和通信状态设置后、我的程序到达此行:

   if (g_bf021 == true && g_bf2838x == true)//f021

调用 f021_DownloadKernel (),打开内核文件,运行 autobaudLock()并调用 loadProgram ()。

函数 loadProgram()刚开始下载字节。 似乎应该在某个位置调用 f021_SendPacket()。 我没有收到它吗?

SCI_Boot()也调用 CopyData(),它只读取数据,而 loadProgram()要回传每个字节。

谢谢。

John

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

    您好、John:

    f021_SendPacket()函数与主机编程器驻留在 f021_SendMessage.cpp 文件中。  

    f021_SendPacket () 在 DFU_CPU1序列期间发生。  

    原始 CopyData()函数复制多个数据块,但不会错误检查 RAM 中的地址。 您是否说上面提到的 CopyData()函数只读取位置?

    谢谢。

    查理

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

    我的意思是 loadProgram()希望发送字节并让它们回传。 SCI_Init ()不回显字符,只读取和复制。

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

    John:

    在主机端,loadProgram()将内核数据发送到目标端。 在目标端,SCI_Boot()调用 CopyData()以将给定的内核数据编程到 RAM。  

    您是否有可用的示波器? 在主机端,在 loadProgram()尝试回显字符时,它将该字符写入 COM 端口,使用 WriteFile()发送字符,使用 Readfile()确保字符到达 COM 端口。 您需要检查 SCITX 和 SCIRX 线路以查看内核是否正确发送。  

    查理

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

     是的、这就是我的意思。 loadProgram()期望字符被回传。 唯一得到回显的东西是在 SCI_Boot ()中进行此调用:

      if (scia_GetWordData ()!= SCI_DATA_WORD_KEY)
    CopyData()不回显字符,但 loadProgram()期望它们被回显。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我明白了。 因此 CopyData()不回显字符的事实使查看内核是否在 RAM 中正确编程变得更加困难。 您是否能够在"Memory"窗口中检查 DestAddr 的地址以查看它是否被发送到同一位置? 如果可能、可以为 RAM 执行内存转储。

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

    loadProgram()将在这里挂起,因为 dwRead 为零,直到缓冲区中有一些东西。

    		dwRead = 0;
    		while (dwRead == 0)
    		{
           ReadFile(file, &rcvData, 1, &dwRead, NULL);
        }

    很抱歉螺纹对齐、但编辑代码块不起作用、我厌倦了与此斗争。

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

    如果它挂起在 DownloadKernel ()->loadProgram ()->ReadFile (),我会检查 内核文件是否被正确读取。  它会尝试通过内核文件进行解析、直到解析达到最终字符。 您能否打开 hex 文件并查看字节外观? 对齐是否正常?  

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

    我不认为你完全阅读我的文章。 这就是问题所在:

    CopyData()不回显字符,但 loadProgram()期望它们被回显。
    串行闪存编程器侧的 LoadProgram 预期回显。 复制数据没有任何 WRITE 语句、因此不会回显。
    但这不再重要、因为我不再在那里工作。