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.

添加Ipc_start之后程序不能自启的问题

Other Parts Discussed in Thread: SYSBIOS

我的工程是从vlfft_evmc6678l衍生出来的一个工程,程序架构我参考了mcsdk下面的image_processing_evmc6678l ipc模式的架构设计,该工程也实现了多核计算FFT的功能,core0是主核,其余core是从核,核间通过ipc ,MessageQ实现通信。多核加载方式为EMIF NOR FLASH 模式,core0 通过自己写的bootload.asm实现自启,core0启动之后,由core0将flash中其他core的程序代码拷贝到各自的L2中,发送IPC中断实现自启。

 

但是现在遇到以下的问题。

 

    整体上有两个工程,一个主核的master工程,一个从核的slave工程。在使用JTAG仿真调试的时候,除了在load程序的之前,需要进行一下System Reset,否则会出错,程序没有任何问题,运行也很稳定。

现在我把工程烧写在Nor Flash,想要上电自启,但是不能成功。

 

我尝试了以下几种情况,确定了问题是跟Ipc_start有关系。

 

先做一个说明:

主核和从核程序代码的主函数在后面附有。#if0…#end 之间代码是Ipc_start 和 MessageQ建立的一些代码。从现象来看问题就和这段代码有关。

 

尝试一:屏蔽主核和从核程序中#if0…#end之间的代码,只让core0通过bootload实现自启,没有core0加载其他core1-7的过程。观察core0 的0x860000地址的值是否正确,结果为可以成功加载。

 

尝试二:屏蔽主核和从核程序中#if0…#end之间的代码,core0通过bootload实现自启,添加core0加载其他core1-7的过程。观察每个core的0x860000地址的值是否正确,结果为可以成功加载。 此时,我查看了core0的 IER 的值为0x4783,中断 IE14(未知),IE7-10(网络中断),NMI 处于激活状态。Core1-7的 IER为0x3。

 

尝试三:屏蔽主核程序中#if0…#end之间的代码,打开从核程序中#if0…#end之间的代码,core0通过bootload实现自启,添加core0加载其他core1-7的过程。观察每个core的0x860000地址的值是否正确,结果为可以成功加载,但是core1-7 的pc指针会停在各自的Ipc_start函数中,这与预想结果一致。

 

尝试四:打开主核和从核程序中#if0…#end之间的代码,即将主核和从核代码中的#if0改成#if1,core0通过bootload实现自启,添加core0加载其他core1-7的过程。观察每个core的0x860000地址的值是否正确,结果为加载失败。我连接JTAG,查看所有core的pc指针,发现所有core都处于复位状态,如下图所示。此时,我查看了core0的 IER 的值为0x1,Core1-7的 IER为0x13。但是在这种情况下,用JTAG仿真调试一点问题都没有,跑的也很稳定。怎么解释?

 

我想问以下几个问题:

  1. load程序之前需要进行一下System Reset,即使是重新上电也需要System Reset,否则会出错,是怎么原因导致的。它会不会影响自启,我bootmode配置的是EMIF NOR FLASH。

 

  1. IE14是ROM bootloader中激活的ipc中断,还是IE04是,对Ipc_start()有没有影响?我尝试在main函数开头设置IER = 0;好像不起作用,还会把网络中断也给disable。目前我将IER = 0放在Reset模块的 system_reset的函数中,但是没有什么作用。

 

  1. 很明显,现象跟Ipc_start()的执行有关,我想请问Ipc_start()对自启到底有什么影响?为什么会将系统复位了? 还是在未进main函数之前系统就已经复位了,再也没有进入到main函数之中来。

 

  1. 在config文件中,Ipc.procSync is set to Ipc.ProcSync_ALL, 和 core0 启动其它core1-7的ipc中断有没有冲突?有冲突怎么解决?

 

  1. 你们有没有做过带有IPC  MessageQ实现核间通信的工程可以进行flash自启的例子,可否提供一个?image_processing_evmc6678l ipc模式的工程好像与此类似,不知你们是否试过这个可否实现多核加载。

 

以下是主核core0函数的代码,

/*

 *  ======== main ========

 *  Synchronizes all processors (in Ipc_start) and calls BIOS_start

 */

Int main(Int argc, Char* argv[])

{

    Int status;

    HeapBufMP_Handle    heapHandle;

    HeapBufMP_Params    heapBufParams;

    Task_Params         params;

 

    System_printf("enter main()\n");

 

Board_init();//系统时钟,DDR3,EMIF,以太网初始化,

 

*(int*) 0x860000 = 0xaa55aa55; //自启测试地址

 

#if 0

    /*

     *  Ipc_start() calls Ipc_attach() to synchronize all remote processors

     *  because 'Ipc.procSync' is set to 'Ipc.ProcSync_ALL' in *.cfg

     */

    status = Ipc_start();

    if (status < 0) {

        System_abort("Ipc_start failed\n");

    }

    /*

     *  Create the heap that will be used to allocate messages.

     */

    HeapBufMP_Params_init(&heapBufParams);

    heapBufParams.regionId       = 0;

    heapBufParams.name           = HEAP_NAME;

    heapBufParams.numBlocks      = 24;

    heapBufParams.align          = 128;

    heapBufParams.blockSize      = sizeof(process_message_t);

    heapHandle = HeapBufMP_create(&heapBufParams);

    if (heapHandle == NULL) {

       System_abort("HeapBufMP_create failed\n" );

    }

    /* Register this heap with MessageQ */

    MessageQ_registerHeap((IHeap_Handle)heapHandle, HEAPID);

 

 

    /* Generate queue names based on own proc ID and total number of procs */

    System_sprintf(localQueueName, "CORE%d", MultiProc_self());

    System_sprintf(core0QueueName, "CORE%d", 0               );

    System_sprintf(core1QueueName, "CORE%d", 1               );

    System_sprintf(core2QueueName, "CORE%d", 2               );

    System_sprintf(core3QueueName, "CORE%d", 3               );

    System_sprintf(core4QueueName, "CORE%d", 4               );

    System_sprintf(core5QueueName, "CORE%d", 5               );

    System_sprintf(core6QueueName, "CORE%d", 6               );

    System_sprintf(core7QueueName, "CORE%d", 7               );

   

    /* Create a unique 'master' Task if on proc 0 */

    Task_Params_init(&params);

    params.stackSize = 0x2000;

    params.priority = 7;

    Task_create(tsk_master_func, &params, NULL);

#endif

    BIOS_start();

    return (0);

}

 

从核(core1-core7)代码:

/*

 *  ======== main ========

 *  Synchronizes all processors (in Ipc_start) and calls BIOS_start

 */

Int main(Int argc, Char* argv[])

{

    Int status;

    Task_Params         params;

    System_printf("enter main()\n");

 

    IER = 0x3;

 

    *(int*)0x860000 = 0xAA55AA55;

#if 0

    /*

     *  Ipc_start() calls Ipc_attach() to synchronize all remote processors

     *  because 'Ipc.procSync' is set to 'Ipc.ProcSync_ALL' in *.cfg

     */

    status = Ipc_start();

    if (status < 0) {

        System_abort("Ipc_start failed\n");

    }

 

    /* Generate queue names based on own proc ID and total number of procs */

    System_sprintf(localQueueName, "CORE%d", MultiProc_self());

    System_sprintf(core0QueueName, "CORE%d", 0               );

    System_sprintf(core1QueueName, "CORE%d", 1               );

    System_sprintf(core2QueueName, "CORE%d", 2               );

    System_sprintf(core3QueueName, "CORE%d", 3               );

    System_sprintf(core4QueueName, "CORE%d", 4               );

    System_sprintf(core5QueueName, "CORE%d", 5               );

    System_sprintf(core6QueueName, "CORE%d", 6               );

    System_sprintf(core7QueueName, "CORE%d", 7               );

   

 

    /* Create a unique Task */

    Task_Params_init(&params);

    params.stackSize = 0x2000;

    Task_create(tsk_slave_func, &params, NULL);

#endif

 

    BIOS_start();

 

    return (0);

}

 

 

 

 

 

  • 怎么没人回复啊?着急啊! 这问题解决不了,IPC MessageQ就完全不能用啊

  • 难道我写的太复杂了,没人看吗?

    我简单描述一下:

    我的程序用JTAG仿真调试一点问题没有,8个核都工作非常正常,但是烧写的Flash中之后自启,启动不了。只要我将主核程序中 Ipc_start() 代码注释掉,程序就可以自启,请问是什么原因?

    请TI工作人员尽快给点回复,哪怕是建议也行啊!

  • 你这是在EVM上测试么,flash加载的时候8个core都跑起来了么,有没有都运行到main函数呢;flash加载如果能起来的话,程序运行与ccs加载没什么差异。

  • 建议把程序换成闪灯程序,测试一下你的Flash自启有没有问题,按理说J-tag加载和Flash自启两种模式对用户程序是没有影响的。

  • 多谢您的解答,我的问题解决了,原因是打开#if 0 ... #end之间的代码段,程序代码变长了,烧写Flash的时候,后面的数据被截断了

  • 你好,我在进行多核加载的时候也遇到了类似的问题。

    我用的是 I2C NAND 启动,仿真测试是,8个核都可以运行起来;我利用一个非常简单的测试程序,8核自起也正常;但运行大系统代码自起时,发现核0的代码运行起来了,但过了ipc_start后,程序就跑飞了,再用CCS连接DSP,8个核都无法连接。

    想问一下,你说的打开#if 0 之后,数据被截断怎么理解?我该如何处理才不会被截断?谢谢 

    这个问题困扰好久了,麻烦解答一下,谢谢

  • 还有就是,运行带ipc_start的代码自启后,ccs无法连接DSP,不知你的是否出现过这样的状态?

  • 您好!我现在也在仿照image_processing_evmc6678l的ipc模式的框架设计来实现vlfft_evmc6678l的多核计算FFT功能,core0是主核,其余core是从核。有许多不懂之处,希望能向您请教!谢谢!

  • 代码变长了,烧写到Flash中的数据被截断了,是我烧写的问题,你检查一下的烧写有没有问题,看看是不是都烧进去了

  • 没有这样的问题。

    Wu Feng 说:
    还有就是,运行带ipc_start的代码自启后,ccs无法连接DSP,不知你的是否出现过这样的状态?
  • wei yi 说:

    您好!我现在也在仿照image_processing_evmc6678l的ipc模式的框架设计来实现vlfft_evmc6678l的多核计算FFT功能,core0是主核,其余core是从核。有许多不懂之处,希望能向您请教!谢谢!

    vlfft_evmc6678l的例子挺好的,你多研究一下吧,主要看看程序的架构,具体算法可以不用管。

  • 谢谢 Wenguo Li1

    我的问题根源找到了,由于DDR3的设计与开发板不一致,IBL中DDR3的初始化没改对,导致代码运行错误

  • 您好!原来vlfft工程中的全局变量数组inData,fftInBuf,vlfft_w1,inBuf,core0QueueName等该如何声明定义,如何在两个工程中共享?
  • 我可能我描述的不清楚,我再说得清楚一点吧。 在vlfft工程中,上述变量是在两个task(vlfft_master和vlfft_slave)中进行初始化的。当分成两个工程后,若只在主核工程中声明定义,从核工程无法识别;若在两个工程中都声明定义,则各自是各自的,无法共享汇总结果。有没有类似“全局变量”的存在,使数据在两个工程间共享? 真的很急,希望各位专家不吝赐教啊!
  • 你好,如下问题你解决了没?
    load程序之前需要进行一下System Reset,即使是重新上电也需要System Reset,否则会出错,是怎么原因导致的。 

  • 你好,我也是在vlfft工程上添加SRIO的doorbell中断,想通过doorbell中断出发fft的计算。

    1.通过hwi添加中断,因为通过.asm文件添加中断,无法进入中断函数

    2.将vlfft_master中的初始化函数保留,计算fft的部分另外放到另一个函数calc_fft里。

    假如收到门铃,则调用calc_fft,能进入calc_fft,但是通信无法成功了,vlfft_master里的使用的变量我都设置成全局的了。vlfft_slave没有变化。不知道这样做是否可行,例如通过中断触发等?不知道你是怎么实现的

  • 你好,我对多核启动还不太了解,想完成vlfft这个工程的自启,使用nor flash方式。有以下疑问,希望你能解答 1.和你的不一样,我所有核都是同一个代码,使用hex6x.exe生成bin后,再在整个文件开头加一段bootload的代码,主要完成数据搬移,怎么样能把数据搬移到不同的核? 2.还是要把bin复制8份每个核都一样,这些代码从flash里搬移到哪里,每个核各自的l2吗? 3.加载完后主核就直接触发每个核的ipc中断吗? 希望解答,非常感激
  • SPI nor flash启动会自动把你的段搬移到对应地址上,多核代码都在一个image里面,仅仅是段地址不一样而已;

    记住要是用全局地址!不要使用0x00800000开始的局部地址,所以你想的复制8份应该是不可行的。

    core 0加载完成后,给每个核的magic address写启动地址(c_int00),然后写IPC中断地址。

    附件是说明文档

    0601.Booting from the SPI NOR on C6670.pdf
  • 你的意思是多核如果使用同一个代码,不需要复制,只要将这块代码到flash里,上电后会自动加载到各个核?代码搬移是需要自己写搬移代码?根据image里给出的目的地址搬移到相应核的L2中?只会是L2吗,会不会存放在MSMC中?谢谢

  • 你好Allen Yin,我看到SPI启动使用的转换工具比较多

    1.如果使用emif16 nor flash启动,是不是只要hex6x这个工具生成的文件就可以了?

    2.按照你说的,每个核的.out文件应该不一样,对于vlfft 基于bios的工程,我是不是每个核都要再重新生成一个平台?内存分配使用如0x10800000,0x11800000这样的全局地址?如附件右图所示地方进行修改

    3.如果就是按照问题2所描述的需要生成8个platform,那么data、代码段等段放在那里,如有像附件右图所示的放置情况。附件左图是内存使用情况,这个空间远远不够?需要怎么做?

    4.当前的vlfft代码只可以在线通过仿真器加载,如果要自启,主核先加载自己的代码,然后还需要完成将辅核的代码拷到辅核的工作?最后再触发IPC中断通知其它核运行?主核拷贝其他核的代码是怎么进行的?

    5.由于8个核使用的是同一个变量,如果每个核加载自己的代码,这些共同变量是否只能放到共享区,还是需要其他什么处理?或者不需要,直接加载后也可以识别这些全局变量?

    6.自启和仿真调试有什么区别,仿真调试所有核使用的都是同一个.out和platform,自启就不能使用同一个?

    希望专家能给与解答,对于多核的启动还是比较迷茫?

  • 1. 无论是何种启动方式,boot table的格式都是一样的,所以hex6x是通用的;

    2. 是的,boot都应该使用全局地址,如果你自己的代码里需要用到局部地址,你可以写一个函数将变量的全局地址转换成局部地址,根据DNUM进行判别即可;

    3. 共享的数据,代码可以放在同一地址上,内存不够的问题和使用什么地址没有什么关系;

    4. 把8个核的boottable合在一起,RBL可以加载所有的代码数据,核0要负责写magic address以及发IPC的工作,不需要负责拷贝,见boot 的例子;

    5. 共享的变量制定全局地址就可以了,cache一致性的维护就是另一个话题了;

    6. 还是那句话,boot必须使用全局地址,你可以在同一个platform里把8个核的内存都分配好,所有的工程都可以建在这个platform上,然后根据DNUM的不同运行不同的分支,或者每个核建一个工程写不同的代码,不能用局部地址加载所有的核,RBL没有办法区分core 0还是core 1的0x00800000地址。

  • 非常感谢Allen Yin的回答 1.按照你说的,out文件通过hex6x工具生成bin后,将八个核的bin直接按顺序拼接生成一个bin后,将其烧写到nor flash中,就可以? 2.使用局部地址的地方也可以使用全局地址,应该没影响 3.共享的数据都放在DDR中,这样所有核都可以访问了,每个核各自的变量放在各自的L2中,变量名一样,应该不会有影响吧? 4.八个核通过hex6x生成的文件直接按顺序合并后,烧写到flash中,RBL不会加载到DSP中,只会直接执行。我之前做过单核的自启,flash的前1kb烧写的是一段汇编代码转换后的文件,由它来完成将代码搬移到DSP中。这样做后可以完成单核自启。不知多核是否不需要? 6.我烧写的是vlfft工程的out,八个核使用同一个,不需要创建多核工程,是否可以创建一个platform?如果可以,在同一个platform中怎么实现八个核内存分配?具体怎么操作,是否有文档说明?如果同一个platform实现八个核内存分配后,八个核只需要有一个out文件?将这个out文件用hex6x转换后烧写,上电就可以实现自启? 因为论坛里看到过其它人总结的sysbios工程通过SPI烧写的说明,感觉生成SPI烧写文件用到的工具不止hex6x,你给我的也是,所以不太理解。还有就是每个核的代码都是怎么样搬移到DSP内的,RBL好像没有代码搬移的功能,看大家的说明好像都要自己写搬移代码。还有附件里的,platform创建时候各段怎么映射?八个核都是映射到一样的地方吗? 最好能有例子或者详细说明,说的太宽泛新手不太理解,请多包涵,谢谢