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.

28377D 双核烧写flash 的一些疑惑

Other Parts Discussed in Thread: CONTROLSUITE

您好,请教些问题,

使用双核,以前一直用ram做的正常工作,现在改了下cmd 搬到单机运行,结果两个cpu都不工作了,没有任何输出,感觉没有加载起来。自己折腾了好久,网上看了好些问题,也还是没明白为啥不工作了。板子本身应该没问题,以前单核的程序,可以standalone运行。


疑惑一:
从一些帖子里看到<www.deyisupport.com/.../190597.aspx

看controlsuite里的双核例程,在cpu1的主函数里有InitSysCtrl(); cpu2的主函数里没有,是不是双核初始化就是这样,只需要在cpu1里进行一次初始化?

你说的对,就是在CPU1初始化一下系统时钟,flash等就行了。CPU2无需配置。

另外从这个贴里也看到
<www.deyisupport.com/.../311014.aspx

"大哥,你好,我在你的指示下将blinky双核的程序做了化简,只在cpu1中写了IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);  
将cpu2中的
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadSize;
extern Uint16 RamfuncsRunStart;
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
都删除了 ,load 完之后   掉电 再 上电   发现两个小灯确实按程序的设定进行亮灭了,
"

InitSysCtrl() V140版本里这个函数里含有memcpy() 和 InitFlash(), (另外已经设置了ifdefCPU1 配置clk 对cpu2 也不影响)。所以我的问题是在 cpu2里 不需要memcpy()和 InitFlash()吗?
按道理两个cpu是独立的flash,cpu2应该也还要把代码搬运代码到ram吧,如果为了加快速度。


疑惑二:
参考例程在自己的板子上做了双核的程序,使用ram和flash 设置可以,但用standalone后,断电开电运行,两个cpu都不work了。在cpu2里, 我加了 InitSysCtrl() 和 一些函数的加载ram设置  #pragma CODE_SECTION(critical funs xxx, "ramfuncs"); 请问,有什么可能原因呢?

疑惑三:
当出现standalone不工作后,怎么才能知道哪里出问题,有哪些调试手段可以看到cpu此时是卡在哪里了,还是根本没有boot起来?

非常感谢!

  • 疑惑一:哈哈 第二帖子是我发的  问题已经解决  。cpu2也做了搬运代码到ram。

    可以加我qq:292835953  交流下!

  • 问题已经解决,这里说一下。后来仔细查看了代码,最后又翻看了这个帖子,有了点提示。https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/317040#pi316717=3

    在上面这个帖子里 它虽然不是28377,但是最后问题出现在IPC boot的函数上。 。 该驱动函数的版本不适用于老的REV0版本,丢失了一些语句,导致无法boot成功.“Mike,
    I think I might know the problem now. you are running on REV0 device. Take a look at this function in the driverlib
    unsigned short IPCMtoCBootControlSystem(unsigned long ulBootMode); does it have the below code?
        //Initialize Control Subsystem memories
        if(RAMControlInitM1MsgRam())
            return true;
        if(RAMControlInitL0L3Ram())
            return true;
     
    if not you are using latest driverlib which is good for REVA and beyond. For REV0 you would need the function from earlier version of driverlib (for ex: v160). Take a look at file ipc_util.c for the above function (edit: in C:\ti\controlSUITE\device_support\f28m35x\v160\MWare\driverlib). It has the above mentioned piece of code which does RAM-INITS for C28x RAMs before the boot mode command is sent. This is needed on REV0 F28M35x devices.
    you can keep using the latest version of driverlib (it has other fixes) but please modify the above function and try it out.
     
    Best Regards
    Santosh”

    我查看了我的377D的 IPC drive 函数,我的是controlsuite V140 版本,而我之前测试成功的例程是v200 版本。主要区别见图。 

    我觉得是v200 版本里,先检测了cpu2 如果没有boot, 那么再等待检测知道它ready for boot,而在v140 里, 

       do

        {

            bootStatus = IPCGetBootStatus() & 0x0000000F;   

        } while ((bootStatus != C2_BOOTROM_BOOTSTS_SYSTEM_READY) ||

                 (bootStatus != C2_BOOTROM_BOOTSTS_C2TOC1_BOOT_CMD_ACK));

    这里一直halt 在着,如果 not ready for boot 或者not boot。问题是,没有boot的话,应该是正常的状态,结果因为用了个 或者的逻辑 “||” 导致正常状态下,一直halt这了。

    所以,把“||” 改成“&&” 后,就好了。或者直接使用 v200里的函数也就好着。

    所以这个bug,好伤人,花费了好几天, 找了各种相关问题,也从没有见哪里提到过。以后还是应该及时使用最新版的驱动和例程来开发。

    建议是: 如果TI更新了不同的驱动,最好作者在本函数文件头,加一个注释,至少说明下和前一个版本的区别。或者在官网论坛上highlight说明下,因为我们用户可能是早期使用了该芯片,使用了早期软件版本,大家测试功率电路已经挺费劲挺小心了,一般不会不停的跟着软件版本更改之前已经经过功率电路测试好的代码,尤其驱动函数之类。很底层的驱动bug 用户也不回那么注意到。

    也多谢datong 兄的热心帮助和自己调试经验的分享!

  • 感谢分享    学习一下了

  • 学习学习

  • 你好   我用的就是V200的程序 还是卡在那个地方 

    //
    // Wait until CPU02 control system boot ROM is ready to receive
    // CPU01 to CPU02 INT1 interrupts.
    //
    do
    {
    bootStatus = IPCGetBootStatus() & 0x0000000F;
    } while ((bootStatus != C2_BOOTROM_BOOTSTS_SYSTEM_READY));

    看这句话的意思是从CPU2读取boot状态  但是读取过来的数据一直是个0            这里我不太明白,此时CPU2还没有运行到main函数中,这个boot状态寄存器CPU2是怎么写进去的?    CPU1读取这个状态赋值给这个变量bootStatus,好像也没用到呀.

  • CPU2的启动是受CPU1来控制的,通过CPU1中的函数 “IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);”来启动CPU2。

    Executes a CPU02 control system bootloader.
    //!
    //! \param ulBootMode specifies which CPU02 control system boot mode to execute.
    //!
    //! This function will allow the CPU01 master system to boot the CPU02 control
    //! system via the following modes: Boot to RAM, Boot to Flash, Boot via SPI,
    //! SCI, I2C, or parallel I/O. Unlike other IPCLite driver functions, this
    //! function blocks and waits until the control system boot ROM is configured
    //! and ready to receive CPU01 to CPU02 IPC INT0 interrupts. It then blocks and waits
    //! until IPC INT0 and IPC FLAG31 are available in the CPU02 boot ROM prior to
    //! sending the command to execute the selected bootloader.

     这个状态寄存器在硬件上就是一个来自于cpu2 boot rom的一个信号,“CPU1读取这个状态赋值给这个变量bootStatus” 就是个基本的查询的while 循环嘛,cpu 1 检查等待这个boot rom上电后是否准备好了来接受它的中断 int 1。 然后再等待IPC INT0 and IPC FLAG31 are available in the CPU02 boot ROM了,就可以根据外部的启动模式,cpu1使能一些和启动相关的几个IO和外设的控制权给cpu2 和它的boot rom 控制系统,然后就可以发送一些command给这个boot rom:

    //CPU01 to CPU02 IPC Boot Mode Register
    IpcRegs.IPCBOOTMODE = ulBootMode;
    // CPU01 To CPU02 IPC Command Register
    IpcRegs.IPCSENDCOM = BROM_IPC_EXECUTE_BOOTMODE_CMD;
    // CPU01 to CPU02 IPC flag register
    IpcRegs.IPCSET.all = 0x80000001;

    (关于command的讨论的参考:

    https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/489067

    https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/591993?TMS320F28377D-The-bootloader-about-28377D )

    然后cpu2 boot rom 接受了这些配置,就可以来引导cpu2去加载运行之前烧写在cpu 2 flash里的用户程序(数据和函数)去从特定的地址来开始启动运行。 (默认的代码也是从flash里运行的,但用户可以在cpu2的主函数初始化时memcopy 一些关键的程序到ram上加快执行速度)。你的那个问题是可以这么来大概解释: cpu2主体是还没有运行,但是它的boot rom可以运行 (boot rom是一小块受保护的rom/flash,固化了一小段芯片制造商提供的程序,上电后这段程序马上用来引导cpu 去特定的地址加载运行特定的程序。触发它的也即是那些关键的几个command,也就是上面那些cpu1发过来的flag信号)。boot rom 还有bootloader 可以参见:https://stackoverflow.com/questions/15665052/what-is-the-difference-between-a-bootrom-vs-bootloader-on-arm-systems