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.

c6678 timers for multicore

Other Parts Discussed in Thread: SYSBIOS

I am running sysbios 6.33.

I am able to get my timer interrrupt code working for a single core were I would initialize the INTC module then the timer CSL module  I finally then setup a high timer in continuous mode (unchained) and then call a function that is waiting for the timer to go off 3 times (10ms every time). Every time the timer goes off i.e. (timerTickCount == 1) I reset it to timerTickCount=0; I expect then that the difference between the before and after count should be approx 3*10ms i.e. 30,000,000. However, when I go to multiple cores and load the application on say two cores I am no longer able to get this 10ms interrupt to work. I am attaching my source code. How do I go about using a timer other than timer 0? Will I need to have 8 different timers if I am wanting this behaviour to happen on 8 cores or can one timer suffice that will wake up all 8 cores?  I also want to use something other than CSL_GEM_TINTHN and have different IDs for each core when I call the setup_hig_continuous_timer() function.

My source is: 5488.multicore_example_test.c

My cfg file is as follows:

/* Load all required BIOS/XDC runtime packages */
var Memory                      =   xdc.useModule('xdc.runtime.Memory');
var BIOS                        =   xdc.useModule('ti.sysbios.BIOS');
var HeapMem                     =   xdc.useModule('ti.sysbios.heaps.HeapMem');
var HeapBuf                     =   xdc.useModule('ti.sysbios.heaps.HeapBuf');
var Log                         =   xdc.useModule('xdc.runtime.Log');
var Task                        =   xdc.useModule('ti.sysbios.knl.Task');
var Hwi                   = xdc.useModule('ti.sysbios.family.c64p.Hwi');
var xdc_runtime_Timestamp = xdc.useModule('xdc.runtime.Timestamp');
var Timer = xdc.useModule('ti.sysbios.hal.Timer');

/* Use the CSL module and indicate that INTC library will be used. */
var cslSettings = xdc.useModule ('ti.csl.Settings');
cslSettings.useCSLIntcLib = true;

/* Load the CSL package */
var Csl          =  xdc.loadPackage('ti.csl');

/* Load the CPPI package */
var Cppi                        =   xdc.loadPackage('ti.drv.cppi');    

/* Load the QMSS package */
var Qmss                        =   xdc.loadPackage('ti.drv.qmss');

/* Load the PA package */
var Pa        =  xdc.loadPackage('ti.drv.pa');

var System                      =   xdc.useModule('xdc.runtime.System');
SysStd                          =   xdc.useModule('xdc.runtime.SysStd');
System.SupportProxy             =   SysStd;


/* Create a default system heap using ti.bios.HeapMem. */
var heapMemParams1              =   new HeapMem.Params;
heapMemParams1.size             =   8192 * 30;
heapMemParams1.sectionName      =   "systemHeap";
Program.global.heap0            =   HeapMem.create(heapMemParams1);

/* This is the default memory heap. */
Memory.defaultHeapInstance      =   Program.global.heap0;

/*Program.sectMap["systemHeap"]   =   Program.platform.stackMemory;*/

/* Create an internal buffer heap using ti.bios.HeapMem. */
var bufHeapMemParams1              =   new HeapMem.Params;
bufHeapMemParams1.size             =   424734;
bufHeapMemParams1.sectionName      =   "bufferHeap1";
Program.global.heap1            =   HeapMem.create(bufHeapMemParams1);

Program.sectMap["bufferHeap1"]   =   Program.platform.stackMemory;

/* Create an external buffer heap using ti.bios.HeapMem. */
var extBufHeapMemParams1              =   new HeapMem.Params;
extBufHeapMemParams1.size             =   180224;
extBufHeapMemParams1.sectionName      =   "extBufferHeap1";
Program.global.extHeap1            =   HeapMem.create(extBufHeapMemParams1);

/* Enable BIOS Task Scheduler */
BIOS.taskEnabled   =   true;

Program.stack = 1024;
Task.defaultStackSize = 1024;

/* memory map */
Program.sectMap[".text"] = "MSMCSRAM";
Program.sectMap[".switch"] = "MSMCSRAM";
Program.sectMap[".const"] = "MSMCSRAM";
Program.sectMap["systemHeap"] = "MSMCSRAM";
Program.sectMap["bufferHeap1"] = "L2SRAM";
Program.sectMap["extBufferHeap1"] = "DDR3";

Any help would be appreciated.

  • Aamir,

    First of all, you should not use CSL's timer and interrupt management APIs within a SYS/BIOS application.

    SYS/BIOS should manage the timers and the interrupts associated with them in order to insure proper kernel behavior.

    I believe the ti.sysbios.timers.timer64.Timer module will natively provide you with precisely what you want and allow your timer interrupt handlers to safely post Semaphores (which I see you wanting to do in the C code you attached).

    In order for all 8 cores to share a common timer interrupt, you must use one of the 8 shared timers. For your device, these are timers 8 through 15.

    Try this:

    var Timer = xdc.useModule('ti.sysbios.timers.timer64.Timer');
    /* set core 0 to initialize and release Timer 8 */
    Timer.timerSettings[8].ownerCoreId = 0;
    var timerParams = new Timer.Params();
    timerParams.period = 10000; /* 10ms */
    /*
     * create Timer instance using timer 8, with period 10ms,
     * which calls TimerTick on every interrupt
     */

    Timer.create(8, '&TimerTick', timerParams);

    I believe this will give you what you want. Every 10ms all 8 cores will be interrupted and their copy of TimerTick invoked.

    The example above borrows a little from the example provided in the CDOC for the timer64 Timer module shown here:

        http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/bios/sysbios/6_33_04_39/exports/bios_6_33_04_39/docs/cdoc/ti/sysbios/timers/timer64/Timer.html

    Alan

  • Alan,

    Okay I take it then I should not call any of the CSL or INTC APIs including calling my setup_continuous_timer which has many calls to the above.

    I tried what you suggested and it could not compile as it gave an "unresolved symbol TimerTick"

    Aamir

  • Remove the 'static' from in front of your TimerTick() declaration. And also remove the CSL_intcEventClear() call:

    static void TimerTick (void *arg)
    {
        /* Increment the number of interrupts detected. */
        timerISRCounter++;

        timerTickCount = 1;
        //Semaphore_post(semTimerTick);

        /* Clear the event ID. */
        CSL_intcEventClear((CSL_IntcEventId)arg);
    }

  • Thanks,

    I did get it to compile but when I ran it, my output looked like the following: I would have expected the TSCL to increment by 30,000,000.

    Aamir

    [C66xx_1] ************************************************

    [C66xx_1] ************** MS Started on Core 1 ***********

    [C66xx_1] ************************************************

    [C66xx_1] home addr=2

    [C66xx_1] core 1 can start receiving and sending

    [C66xx_1] TSCL=418873 timerISRCounter=5

    [C66xx_1] after TSCL=11675677 timerISRCounter=8

    [C66xx_1] **********************************************

    [C66xx_1] *** MS Ended on Core 1 ***

    [C66xx_1] **********************************************

    [C66xx_0] ************************************************

    [C66xx_0] ************** MS Started on Core 0 ***********

    [C66xx_0] ************************************************

    [C66xx_0] home addr=1

    [C66xx_0] core 0 can start receiving and sending

    [C66xx_0] TSCL=420463 timerISRCounter=5

    [C66xx_0] after TSCL=19902819 timerISRCounter=8

    [C66xx_0] **********************************************

    [C66xx_0] *** MS Ended on Core 0 ***

    [C66xx_0] **********************************************

  • I believe each core has its own copy of timerISRCounter.

    You'll have to place timerISRCounter at a fixed shared memory space if you want all cores to operate on the same variable.

    Alan

  • Oops. I didn't fully read your post.

    The TSCL is incremented at the processor clock speed.

    Based on your CPU clock speed you can calculate how many cpu clock periods occur in 30ms.

    Alan

  • yes my clock speed is 1GHz so I expect 30ms to correspond to 30,000,000 cycles.

    I actually had that all working using the CSL and intc for a single core with the PA and switch etc receiving packets together with my proprietary code. I just hit a snag when I went to multicore. Why is it that I cannot have all the cores have separate interrupts go off with separate timers and then each call the timerTick function and give control back to my main task. Basically the intent is for me to setup the switch, PA etc then go into a main while loop that receives packets form the outside, processes them and then essentially waits till 10ms has elapsed at which time, I am expecting all my processing to complete, and then an interrupt gets timerTick to be called which gives control back to the main task to read more packets and process them.

    Thanks, Aamir

  • Alan,

    Please disregard my note above about the cycle discrepancy. I needed to remove the System_printfs that were happening between the time I started the maintask and the point where I had the last system printf expecting the count to go up by 30,000,000. Once I remove them, as expected my cycle difference is right. Previously as I was setting up the timers using the CSL and intc, I could system_printf prior to starting the timer and then after the point where I was measuring the time difference elapses without any impact on the cycles measured.

    Thanks, Aamir

  • So is this issue resolved? Please mark the post as answered if so.

    Alan

  • Yes, it is working now. I will mark it as answered.

    General question just to understand it better: Why could I not use the CSL, INTC calls with sysbios (what would appear to be unstable in the kernel behaviour?) as it appeared that I was able to get it all working with a single core?

    Secondly, If I wanted to stagger all the cores so that they woke up for processing every 10ms, offset from one another, so as to distribute the peak core usage from a thermal perspective, could I do that with timers 0-7 as opposed to one of the common timers 8-15?

    Thanks, Aamir

  • Aamir,

    If you're opening new lines of inquiries, please start new threads.

    Otherwise:

    1) I think that in fact, your single-core CSL INTC usage was a ticking time bomb. The commented out call to Semaphore_post() in TimerTick() was probably removed because it did not work as expected. In order for an ISR to call Semaphore_post() (or Swi_post()) and get the desired behavior, some kernel house keeping must be performed prior to entering the ISR function and immediately after exiting the ISR function prior to returning to the interrupted thread. This house keeping is NOT performed by the CSL code.

    2) I think you would get the behavior you want using timers 0-7. But you will have to configure the 'owner' for each of the Timers to match the core you want the corresponding timer interrupt to occur on.

    Alan