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.

TMS320F28388D: Operating dual core on SYS/BIOS

Part Number: TMS320F28388D
Other Parts Discussed in Thread: C2000WARE

Hello. i'm a beginner of TMS320F28388D , trying to run both core with SYS/BIOS.

Here's the version of program that i'm using

- CCS 10.1.1

- C2000Ware 3.03.00

- Complier V20.2.1.LTS

- Xdc tool 3.61.02.27

- BIOS 6.83.00.18

----------------------------------------------------------------------------------------------------------------

At first, I tried it using single core with SYS/BIOS and it did work.

Then i tried same situation using both CPU cores, but it didn't work.

So I removed almost every Hwi, Swi , etc.. on app.cfg file , except simple timer & idle for trobleshooting. here's my code below

-----------------------------------------------------------------------------------------------------------------

CPU1

<main.c>

void main(void) {

Device_init();

#ifdef _FLASH
Device_bootCPU2(BOOTMODE_BOOT_TO_FLASH_SECTOR0);
#else
Device_bootCPU2(BOOTMODE_BOOT_TO_M0RAM); // activate
#endif

EINT;

ERTM;

BIOS_start();

}

add "timer1" ( 1 sec timer, counting "tickcount1" for every second ) at app.cfg

CPU2

<main.c>

void main(void){

EINT;

ERTM;

BIOS_start();

}

add "timer2" ( 2sec timer, counting "tickcount2" for every 2 sec ) at app.cfg
-------------------------------------------------------------------------------------------------------------------------

Although compiling was successful, but there are some difference between my expectation and actual performance

my expectation : increasing variables "tickcount1" & "tickcount2" seperately based on different timer period ( i think it means that SYS/BIOS is running at both CPU cores )

actual performance : when i started CPU1 first, nothing has changed (even timer1) . then i started CPU2 , both variables ( tickcount1 & 2 ) start increasing simultaneously based on timer2 period ( 2sec )

It seems that SYS/BIOS on CPU1 doesn't operate. Could you give me some advice about this situation or initial SYS/BIOS setting tips with multicore situation  ?

Since I can't find examples about SYS/BIOS with dual core. I can't go any futher.

Regards,

Kim

  • So you are able to get them both to run, but the timer frequency appears to be incorrect on CPU1? Do you mind sharing your .cfg files?

    Whitney

  • I have .cfg files . but because of my company's secure issue, I can't upload my cfg files directly into this forum once it is installed in my computer (even it is from Ti example...)

    sorry for saying so. 

    but here's brief code in cfg files and function that i defined

    ------------------------------------------------------------------------------------------------------------------

    <CPU1.cfg>

    var loggerBufParams = new LoggerBuf.Params();
    loggerBufParams.numEntries = 32;
    var logger0 = LoggerBuf.create(loggerBufParams);
    Defaults.common$.logger = logger0;
    Main.common$.diags_INFO = Diags.ALWAYS_ON;

    System.SupportProxy = SysMin;
    Idle.idleFxns[0] = "&myIdleFxnCPU1";
    Boot.configureClocks = true;
    Boot.OSCCLKSRCSEL = Boot.OscClk_XTAL;
    Boot.OSCCLK = 20;
    Boot.SPLLIMULT = 20;
    BIOS.cpuFreq.lo = 200000000;
    var timer0Params = new Timer.Params();
    timer0Params.instance.name = "timer0";
    timer0Params.period = 1000000;
    Program.global.timer0 = Timer.create(null, "&myTickFxnCPU1", timer0Params);

    <CPU1 function >

    Void myTickFxnCPU1(UArg arg)
    {
    tickCount1 += 1;
    isrFlagCPU1 = TRUE;
    }


    Void myIdleFxnCPU1(Void)
    {
    if (isrFlagCPU1 == TRUE) {
    isrFlagCPU1 = FALSE;

    System_printf("CPU1 BIOS running\n");
    System_flush();
    GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;

    }
    }

    --------------------------------------------------------------------------------------------------------------------------------

    < CPU2 .cfg >

    var loggerBufParams = new LoggerBuf.Params();
    loggerBufParams.numEntries = 32;
    var logger0 = LoggerBuf.create(loggerBufParams);
    Defaults.common$.logger = logger0;
    Main.common$.diags_INFO = Diags.ALWAYS_ON;

    System.SupportProxy = SysMin;
    Boot.configureClocks = true;
    Boot.OSCCLKSRCSEL = Boot.OscClk_XTAL;
    Boot.OSCCLK = 20;
    Boot.SPLLIMULT = 20;
    BIOS.cpuFreq.lo = 200000000;
    Idle.idleFxns[0] = "&myIdleFxnCPU2";
    Idle.idleFxns[1] = null;
    var timer0Params = new Timer.Params();
    timer0Params.instance.name = "timer0";
    timer0Params.period = 2000000;
    Program.global.timer0 = Timer.create(null, "&myTickFxnCPU2", timer0Params);

    <CPU2 function >

    Void myTickFxnCPU2(UArg arg)
    {
    tickCount2 += 1;
    isrFlagCPU2 = TRUE;
    }


    Void myIdleFxnCPU2(Void)
    {
    if (isrFlagCPU2 == TRUE) {
    isrFlagCPU2 = FALSE;
    /*
    * Print the current value of tickCount to a log buffer.
    */
    //Log_info1("Tick Count = %d\n", tickCount);
    System_printf("CPU2 BIOS running\n");
    System_flush();


    }
    }

    ** do i have to write " BIOS_start() " on both CPUs main.c file seperately? or just on master CPU1?

    Regard

    Kim

  • Yes, you do need to call BIOS_start() in main() in both projects.

    A few things about the BIOS Boot module--on CPU1, it is redundant to have the Boot module configure the system clock and then to call Device_init() which tries to configure it again. Either comment out the redundant code in Device_init() or disable clock configuration in the .cfg file. You don't need to configure the clock from both CPUs either, so consider disabling clock configuration in the CPU2 .cfg file.

    You do still need to keep the "BIOS.cpuFreq.lo = 200000000;" line though since it's there to tell SYS/BIOS how fast the system clock is running.

    Whitney

  • Thanks again , Whitney.

    I changed my settings as you told. by doing so, it seems that CPU1 timer and CPU2 timer doesn't run simultaneously.

    but i think CPU1 runs inappropriately as i expected.

    here's my main source of CPU1 once again. 

    ---------------------------------------------------------------------------------------------------

    void main(void){

    System_printf("enter CPU1\n");
    System_flush();

    InitGpio();


    #ifdef _FLASH
    Device_bootCPU2(BOOTMODE_BOOT_TO_FLASH_SECTOR0);
    #else
    Device_bootCPU2(BOOTMODE_BOOT_TO_M0RAM);
    #endif


    System_printf("CPU2 booting\n");
    System_flush();

    DINT;

    init_led();
    init_epwm();

    System_printf("led , epwm init\n");
    System_flush();

    EINT;
    ERTM;
    System_printf("enable interrupt & real time \n");
    System_flush();

    BIOS_start();

    }

    and i added "CPU1 BIOS running" comment printing on CPU1 timer isr & "CPU2 BIOS running" on CPU2 timer isr 

    ---------------------------------------------------------------------------

    Performing sequence ( in my intent ) is this : 

     run CPU1.out first -> boot CPU2 & write comments (from CPU1 main source) on console -> run CPU2.out -> write comment on console

    as a result , there are comments on console like :

    "enter CPU1" - > "CPU2 booting" -> "led , epwm init" -> "enable interrupt & real time" -> keep printing "CPU1 BIOS running"

    -> (after run CPU2.out ) "enter CPU2" -> keep printing "CPU2 BIOS running " & "CPU1 BIOS running" alternately ( because both CPU's BIOS are running ) 

    but actual performance is like :

    (after run CPU1.out) -> nothing on console -> run CPU2.out -> "enter CPU2 " -> keep printing " CPU2 BIOS running " alone

    it looks like i miss something about booting sequence or performing sequence..

    Could you give some advice about this situation? i 've trapped on this situation ( running both CPU's SYS/BIOS ) for several weeks....

  • When you halt CPU1, where is it stuck? Is it even making it to main()? Is ROV showing any errors?

    Whitney

  • i changed command file ( CPU2 project ) "TMS320F2838X1.cmd" to "TMS320F2838X2.cmd"  to define memory map differently with CPU1.

    now, CPU2 starts running as i debug  .ccxml ( exists both CPU project ) even i don't click resume button , and nothing change as i run CPU1 ( it supposed to increase timer count )

    here's an error message on CPU1.out ROV

    1. [Timer] Error: java.lang.Exception: Target memory read failed at address: 0x7460656, length: 24 This read is at an INVALID address according to the    application's section map. The application is likely either uninitialized or corrupt.

    and messages from CPU1.out debug session

    1. xdc_runtime_Error_policyDefault__E(struct xdc_runtime_Error_Block *, unsigned int, char *, int, unsigned long, long, long)() at Error.c:168 0x08189E 

    2. xdc_runtime_Error_raiseX__E(struct xdc_runtime_Error_Block *, unsigned int, char *, int, unsigned long, long, long)() at Error.c:126 0x082919 

    ** where can i find basic code structure or examle about dual core SYS/BIOS ?

  • I was able to get an application similar to yours working. I'll share my main.c, linker command file, and .cfg file.

    https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/171/2838x_5F00_FLASH_5F00_lnk_5F00_cpu1.cmd
    app_cpu1.cfg

    /*
     *  ======== main.c ========
     */
    
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    
    #include "device.h"
    #include "f2838x_device.h"
    
    uint32_t tickCount1;
    Bool isrFlagCPU1;
    
    Void myTickFxnCPU1(UArg arg)
    {
        tickCount1 += 1;
        isrFlagCPU1 = TRUE;
    }
    
    
    Void myIdleFxnCPU1(Void)
    {
        if (isrFlagCPU1 == TRUE) {
            isrFlagCPU1 = FALSE;
    
            System_printf("CPU1 BIOS running\n");
            System_flush();
            GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;
        }
    }
    
    /*
     *  ======== main ========
     */
    Int main()
    { 
    //    Device_init();
        System_printf("enter CPU1\n");
        System_flush();
    
        #ifdef _FLASH
        Device_bootCPU2(BOOTMODE_BOOT_TO_FLASH_SECTOR0);
        #else
        Device_bootCPU2(BOOTMODE_BOOT_TO_M0RAM); // activate
        #endif
    
        EINT;
    
        ERTM;
    
        BIOS_start();
        return(0);
    }
    

    https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/171/2838x_5F00_FLASH_5F00_lnk_5F00_cpu2.cmd
    app_cpu2.cfg

    /*
     *  ======== main.c ========
     */
    
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    
    #include "device.h"
    
    uint32_t tickCount2;
    Bool isrFlagCPU2;
    
    Void myTickFxnCPU2(UArg arg)
    {
        tickCount2 += 1;
        isrFlagCPU2 = TRUE;
    }
    
    Void myIdleFxnCPU2(Void)
    {
        if (isrFlagCPU2 == TRUE) {
            isrFlagCPU2 = FALSE;
            /*
            * Print the current value of tickCount to a log buffer.
            */
            //Log_info1("Tick Count = %d\n", tickCount);
            System_printf("CPU2 BIOS running\n");
            System_flush();
        }
    }
    
    /*
     *  ======== main ========
     */
    Int main()
    { 
        EINT;
    
        ERTM;
    
        BIOS_start();
        return(0);
    }
    

  • thanks for sharing file, Whitney. 

    I removed my .c  & .cmd & .cfg file and put your files on my project , but problems are still remained.

    no errors on compiler , CPU2 starts running as i debug ( it doesn't seem that CPU2 is actually running. because tickCount2 doesn't increase )  , but hopely, CPU1 runs properly ( "CPU1 BIOS running " comments are writted on console  & tickCount1 increase) 

    for now, i guess there is an error on debugging procedure

    i debugged my projects by .ccxml file ( exists both project with same filename ) based on "Debugging Multi-Core Device" (https://software-dl.ti.com/ccs/esd/documents/ccs_multi-core-debug.html

  • and plus, i don't know why CPU2's state is always "Running" on Debug Session..

  • I had that issue with CPU2 at first yesterday, but after increasing the stack size and making some updates to the cmd file file it seemed to go away. The updates were in the files I sent, so I'm not sure why it's still happening for you. Can you get CPU2 to go to main() if you reset and restart it?

    If you hit the suspend button for CPU2, can you see where it is getting stuck--at a certain address or line of code? Did the .out even load properly? You can go to Run -> Load -> Load Program... to load it again to be sure.

    Whitney

  • Finally, it works ! 

    i made new project and import your file . i did work!!

    i think something in  previous project  has collided with your fille. that's why i didn't run project with your file.

    I have one last question. there are two solutions you give  :  increasing the stack sizes & making updates to the cmd file.

    it seems you use existing .cmd file ( 2838x_FLASH_Ink_cpuX.cmd ) ( making updates to the cmd file )

    but how can i check the increased stack sizes? what's the effects of increasing stack sizes?

    Sincerely

    Kim

    ** For everyone who gets problems similar to mine and is reading this post , it would be better to set timer ID differently ( at .cfg file ) for controlling CPUs timer independently. 

  • Glad it's working now! When I mentioned the stack size change, I was referring to the Program.stack line in the cfg file. You can use ROV to monitor the system stack usage by Swis and Hwis to know how close you are to an overflow. SYS/BIOS also fills the stack with a pattern (0xBEBEBEBE if I recall correctly) during system initialization which makes it easy to look at the stack in the memory browser and see how much as been used.

    Whitney