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.

how to burn master and slave project into EVM6678L

Good day to all,

A newbie question. I've modified the Image Processing demo project to do a simple message passing using MessageQ. Mainly, CORE0 the master core will send out 7 messages to 7 slave cores(core 1-7). The slave cores will receive the messages and then reply back to CORE0. The master and slave codes are in 2 different project, so how do i burn the 2 different .out files into the respective cores?

I wanted to try using platform_write to output simple messages such as 'Message Received' etc. I've tried burning single .out files using the norwriter before, but i've no idea how do i burn the master.out into core0 and slave.out to the other 7 cores.

EVM6678LE
CCS v5.5
IPC             1.24.2.27
MCSDK      2.1.0.3
PDK           1.1.0.3
NDK           2.22.2.16
SYS/BIOS  6.33.6.50
UIA             1.3.1.08

Thanks.

  • Does anyone know how to?

    Anyway, I took the hello world example in mcsdk, and I added in the IPC modules etc, loaded the .out into 8 cores and I manage to print hello world 8 times, once from each core. But when I flash it to my board using nor writer nothing appears in my tera term. Even when I debug normally only core0 is loaded.

    Am I missing something or does IPC just works differently, and requires a different or extra step during flashing to nor flash?

  • The hello world example has all the cores running the same application binary and there is a check int he application to see if the code is run on the master core or on secondary core. In order to have the secondary cores executing the code you need to populate the Magic address for the secondary cores and then provide the apporpirate IPC interrupt to wake up the secondary core. This has been demonstrated in the hello world examples. Can you confirm that you have the base example working and the issue is seen only when IPC module is introduced in the code.

    Typically if you have multiple application for multiple cores, you can explore the option of using Mutlicore application deployment utilities that are part of the MCSDK. Here is the documentation for the (MAD)utilities.

    http://processors.wiki.ti.com/index.php/MAD_Utils_User_Guide

    Regards

    Rahul

  • Hi,

    Thanks for replying. Yes i tested the base example(the default hello world) and everything printed out fine. I then removed all the setting up of network portion(as i don't really need them for now) and have a 'platform_write("Hello World!");' after the platform is being set up, debugged the program and hello world printed out fine as well(i checked using Tera Term and there's output from serial as well).

    I then moved on to include the respective code sections in the .cfg file, as well as the necessary include paths in my .c file. And obviously when i debug only core0 is being loaded, but it'd work fine if i manually load the .out into the rest of the 7 cores, all 8 hello worlds will be printed.

    Hmm populate the Magic address for secondary cores? It's in the .cfg file? Hmm okay, i'll try and check it out tml as i'm currently off from work, i'll also try and take a look at the link u provided. Though i'm probably required to have the 8 cores running a same application.

    Thanks.

  • Hi,

    I'm looking at the hello world sample now (mcsdk_2_01_02_06\examples\ndk\helloWorld) and I don't see anything that specifies if its core0 that's running the code, except for the portion on qmss and cppi where there's 'platform_get_coreid()'. Also, what is the magic address u mentioned and what kind of IPC interrupt do u mean?

    Regarding the part where u mentioned its being demonstrated in the hello world sample. I've read through the codes and I only the sample setting up network and printing hello world, there's nothing related to IPC from what I can see.

    Thanks.

  • Jing,


    I was refering to the helloworld examples in the boot examples. Please refer to its source in the following directory:

    mcsdk_2_01_02_06\tools\boot_loader\examples\srio\srioboot_helloworld\src

    Regards,

    Rahul

  • Hi Rahul,

    I have looked through the boot example for hello world and found the 'magic' address u were talking about. I don't quite understand what the parts highlighted in red actually do, or which part of my code i have to insert them in. Could you help clarify my doubts?

    if (core == 0)
    {
      for(core =1; core< pform_info.cpu.core_count; core++)
      {
        sprintf(boot_msg, ".......", core);
        write_uart(boot_msg);

        DEVICE_REG32_W(BOOT_MAGIC_ADDR(core), (unit32_t) write_boot_magic_number);
        platform_delay(1);
      }
      for(core =1; core< pform_info.cpu.core_count; core++)
      {
        /*IPC interrupt other cores */
        DEVICE_REG32_W(IPCGR(core), 1);
        platform_delay(1000); //why do we need the 1000 delay here? what will this interrupt do?
      }
    }
    else
    {
      write_boot_magic_number();
    }

    The following is the main code section of my program:

    master_main()
    {
      if (MultiProc_self() == 0)
      {
        platform_init etc
        HeapBufMP_Params_init($heapBufParams);
        //place the for loop with DEVICE_REG32_W(BOOT_MAGIC_ADDR(core), (unit32_t) write_boot_magic_number); here?

      }
      else
      {
        HeapBufMP_open
      }
      MessageQ_registerHeap
      MessageQ_create
      MessageQ_open(nextQueueName, $remoteQueueId)

      if (MultiProc_self() == 0)
      {
        MessageQ_alloc
        platform_write("Hello World");
        MessageQ_put
      }
      else
      {
        while (TRUE)
        {

          MessageQ_get
          platform_write("Hello World");
          MessageQ_put
        }
      }

    }

    What my program does is just ensuring that core0 will output a hello world message followed by core1 then core2 etc, i understand the 'DEVICE_REG32_W(BOOT_MAGIC_ADDR(core), (unit32_t) write_boot_magic_number);' is just to set the magic address for each core, so i can probably just place it somewhere together with the section where i initialize the platform and HeapBufMP right?

    Then what about the IPC interrupt? Where should i actually place the interrupt? And why do i need the delay(1000)?

    And lastly the else statement where the other cores will run write_boot_magic_number(). What exactly happens when the slave cores run the function? I know that it writes the boot_magic_number to the magic_addr, but what happens then? Where should i actually place this statement in my code?

    Thanks.

  • I did a platform_write before and after write_boot_magic_number() , but the output weren't displayed. Meaning the rest of the cores didnt run.

    else
    {

      Platform_write("before");
      write_boot_magic_number();

      Platform_write("after");

  •  

    The following code places the entry point of the application in the magic address for each core.  The BOOT_MAGIC_ADDRESS of each core is different so it is computed using the Macro BOOT_MAGIC_ADDR.


        DEVICE_REG32_W(BOOT_MAGIC_ADDR(core), (unit32_t) write_boot_magic_number);
        platform_delay(1);

    The code inside the second loop then issues the IPC interrupt to the secondary core to wake up and read its Magic address. The platform delay is only a safety measure to let the core wake up before the master core wakes up the next seondary core. The else statement only ensure that the secondary core only write magic address and don`t issues IPC interrupts, you can replace that by idle or any other code you want the secondary cores to execute but not the master core.

    Regards,

    Rahul

  • After you run your code can you connect to the secondary cores ? What are their program counters? Are the Magic address for secondary cores populated as expected ? Can you manually write to the IPC registers through CCS from master core and see if the secondary cores wake up??

    Regards,

    Rahul

  • Good day to you Rahul,

    May i clarify further regarding the interrupt? The first loop populates the magic address, the second loop provides the slave cores with the interrupt. Does this interrupt means 'activating' the slave cores? Currently the codes i want the slave cores  to run can be places in the else statement, but i can choose to do it later right? For example:
    If (core=0)
    {
      //populate magic address and interrupt
    }
    // other codes i want all 8 cores to run here
    If(core=0)
    {
    }
    else
    {
      //my slave codes here
    }

    As for your second post, here's what i did. I debug the code, CCS prompts me to select cores, and i select all 8 cores. I will then manually click on the play(resume) button for all of the 8 cores. I was able to see the output from my core0, as well as outputs from my slave cores on my TeraTerm. But when i wrote the program into norflash using NorWriter and boot the board up in IBL mode, not even the output from core0 was displayed.

    - With that said, i assume i could connect to the secondary cores? Since i managed to see the output from them in debug mode.
    - Hmm.. I'm not sure how to retrieve the program counters.
    - I assume the magic addresses were correctly populated? As i was able to see all 7 outputs from the slave cores.
    - What do you mean by manually write to IPC registers? You mean the interrupt? Isn't that done in the loop? When i see an output from my slave cores in TeraTerm, does that mean my secondary cores were woken up? Though i am still not sure why i can see the outputs in debug mode but not after i burn into the nor flash.

  • I noticed something, I was stepping through core 0, and when the code reaches the part where u unlock the chip registers kick0 and kick1, it ends. I wasn't able to step till the for loop.

    /* Unlock the chip registers */

    DEVICE_REG32_W(KICK0, 0x83e70b13);

    DEVICE_REG32_W(KICK1, 0x95a4f1e0);

  • Okay, i found an easier to understand and simpler method. Thanks anyway.

    http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/233889.aspx