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.

OMAP-L138 module Load & timers

Other Parts Discussed in Thread: OMAP-L138, SYSBIOS

Hello,

I've some questions related to the module Load on the ARM side of the OMAP-L138.
I'm the following versions on the ARM side of the OMAP-L138:
- CCS Version 5.2.1.00018
- SYS/BIOS 6.30.03.46 (eabi) ELF
- TMS470 Code Generation Tools 4.9.6
- XDCTOOLS 3.23.03.53

Within the ARM configuration I'm using amongst others
- the module ti.sysbios.BIOS, where the cpuFreq is set to 456MHz (hi = 0, lo = 456000000)
- the module Clock (with TickSource_TIMER as default tickSource) and one instance
  ++ var ti_sysbios_knl_Clock = xdc.useModule('ti.sysbios.knl.Clock');
  ++ var instti_sysbios_knl_Clock0Params0 = new ti_sysbios_knl_Clock.Params();
  ++ Program.global.armClock10ms = ti_sysbios_knl_Clock.create("&doArmClock10ms", 10, instti_sysbios_knl_Clock0Params0);
  ++ ti_sysbios_knl_Clock.timerId = 1;
- the module Timer (anyMask value is 255)
  ++ var ti_sysbios_timers_timer64_Timer = xdc.useModule('ti.sysbios.timers.timer64.Timer');
  ++ ti_sysbios_timers_timer64_Timer.intFreqs[0].lo = 24000000;
  ++ ti_sysbios_timers_timer64_Timer.intFreqs[1].lo = 24000000;
  ++ ti_sysbios_timers_timer64_Timer.intFreqs[2].lo = 24000000;
  ++ ti_sysbios_timers_timer64_Timer.intFreqs[3].lo = 24000000;
  ++ ti_sysbios_timers_timer64_Timer.defaultHalf = ti_sysbios_timers_timer64_Timer.Half_UPPER;

With these settings the ARM uses only the upper half of timer 1.
Timer 0, lower half of timer 1 and timer 2 are used by the DSP.

When I'm now adding the module Load to get some information about the ARM's CPU load,
it looks that the ARM is modifying/using the Timer 0 and thereby breaks the functionality of the DSP.

Is it possible that the module Load also uses the ARM's timer (upper half of timer 1) and not breaking anything else?
If yes, what needs to be done?

Thanks,
Frank

  • Frank,

    Frank said:
    Is it possible that the module Load also uses the ARM's timer (upper half of timer 1) and not breaking anything else?

    Can you please attach your config file (*.cfg)?  I'd like to have a look at your Load module settings, in addition to the above.

    I've also spoken to another team member about your issue, and we think it may be worthwhile for you to upgrade your version of BIOS.  6.30.x is a bit old now, and there has since been a redesign of the Timer module and how it handles conflicts between the ARM and DSP.  You may find that this problem has been fixed when you upgrade (you can find SYS/BIOS releases on this page).

    Steve

  • Hello Steve,

    uploaded the cfg file.

    Your link to the SYS/BIOS releases seems not to work (-> Group Not Found).

    Switching to a new SYS/BIOS would result in a big effort (from development over testing up to the end customer).

    Therefore lets try to solve this with 6.30.03.46.

    Thanks,

    Frank

    ARM9_OS_SPIW_ELF_configuration.cfg
  • Frank,

    A colleague of mine just stopped by after looking into this a little more.  It turns out the Load module does use a timer.  Since the load module does time stamping, it uses the TimestampProvider module, which uses a timer.

    Can you try the following configuration setting?  This setting will cause the TimestampProvider to use the same timer that you have configured the Clock module to use (based on your previous post, that would be ti_sysbios_knl_Clock.timerId = 1;):

    var TimestampProvider = xdc.useModule('ti.sysbios.timers.timer64.TimestampProvider');

    TimestampProvider.useClockTimer = true;

    This should hopefully allow the Load module to work without causing any timer conflicts.

    Steve

  • Also, not sure what happened with the link to the BIOS download page.  It should be fixed in the previous post now, or can be found here:

    http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/bios/sysbios/index.html

    Steve

  • Hello Steve,

    thanks.

    The link is now working.

    I tried the TimestampProvider settings on an Eval board and it does not touch timer 0, it seems to use upper half of timer 1.

    I'll need to verify these settings on a custom board, once done I'll close the ticket (give me some time for this).

    Frank

  • Hello Steve,

    I tried it on a custom board and it looks that only upper half of timer 1 is used.

    However, I've still some problems with the load module.

    Under normal circumstances I got a cpu load of about ~37% ( calling Load_getCPULoad(); every second caused by cfg setting "Load.windowInMs = 1000;" ).

    Then I increased the load by issuing some debug cmds through the USB connection and got values of about 95% to 97%.

    When stopping the debug cmds, I could not see that the load is decreasing back to the ~37%, it was always above 90%.

    Do you have any clue why the load does not decrease?

    Are you aware of any problems?

    Thanks,

    Frank

  • Hi Frank,

    Is it possible that you are executing more code in the idle loop after you ran the debug commands?  The Load module computes the CPU load in the configured time window, by multiplying the number of times the idle loop ran by the minimum time through one pass of the Idle loop:

        Idle time = minIdle time * numLoops

    (The cdoc for ti.sysbios.utils.Load explains this in detail.)  Any work done in the idle loop that is not included in the shortest trip through the idle loop, will be counted as CPU load.  So if you have added functions to the idle loop with varying execution times, this can affect the CPU load.

    Another thing you can try is enabling Swi and Hwi load to see where the load is coming from.  This can be done in the configuration file by adding:

    Load.swiEnabled = true;
    Load.hwiEnabled = true;

    Then you can get your Task, Swi, and Hwi loads using these functions:

    Bool Load_getTaskLoad(Task_Handle task, Load_Stat *stat)
    Bool Load_getGlobalHwiLoad(Load_Stat *stat)
    Bool Load_getGlobalSwiLoad(Load_Stat *stat)

    Best regards,

        Janet

  • Hello Janet,

    sorry for the delay.

    In the idle loop only two things are running:

    ti_sysbios_hal_Hwi_checkStack

    ti_sysbios_utils_Load_idleFxn__E

    By default, Task, Swi and Hwi are already enabled:

     

    Load.hwiEnabled = true;
    Load.swiEnabled = true;
    Load.taskEnabled = true;

    Give me some more time to check where the load is coming from.

    Best regards,

    Frank

  • All,

    as my original question about the timere is claryfied, it is ok to mark it as "answered"

    However, some more things to mention:

    CPU load seems not to work correctly within my environment, maybe caused by the old SYS/BIOS.

    E.g. when checking the HWI load (Load_getGlobalHwiLoad(&stat) -> Load_calculateLoad(&stat)) I'm always getting a load of > 100% (max seen was 179%).

    Even setting all 3 enabled to flase (hwiEnabled, swiEnabled & taskEnabled) and generating CPU load (~70%) and taking away the CPU load, the Load_getCPULoad() still returns (checked for nearly one hour) the high load (~70%).

    Immediately after Load_reset() the Load_getCPULoad() returns the values around ~23%.

    Due to the Load_reset() behavior it looks for me, that there is something not correct in the SYS/BIOS for the CPU load handling.

    Thanks for your support,

    Frank

  • Hi Frank,

    It's possible that the problem is due to an old version of BIOS.  There have been some changes to the Load module since BIOS 6.30.03.46.  The fact that Load_reset() causes the CPU load to go back down leads me to believe that one of the passes through the idle loop is coming out with a very low time.  If this time, Load->minLoop, does not accurately reflect the average time through the idle loop when there is no load, the whole CPU load calculation will be off.  Load_reset() will set Load->minLoop to 0xffffffff, so that it will be recalculated.  If you can look at Load->minLoop in a debugger, you could determine if that is the problem.  You'd have to use the full name of the Load module object, ti_sysbios_utils_Load_Module__state__V.

    Best regards,

        Janet

  • Hello Janet,

    thanks.

    Just compared the code for load calculation between 6.30.03.46 and 6.33.05.46.
    6.33.05.46 has slight modification:
    - added function "UInt32 Load_setMinIdle(UInt32 new)" which allows setting a min (minIdle) value.
    - this is the minimum value which might be taken if minLoop is less than minIdle
        /* Update Global CPU load */
        idle = Load_module->minLoop;
        if (idle < Load_module->minIdle) {
            idle = Load_module->minIdle;
        }
    So minimum will never get below minIdle, even minLoop is below.

    Is there a way to overwrite the minLoop by the application code (Load_module->minLoop = 0xffffffff;)?
    If not we can stop investigation here.
    If yes I could think that overwriting it every time when retrieving the Cpu load (Load_getCPULoad()) could help in 6.30.03.46, i.e.
    the current delta is used:

      if (delta < Load_module->minLoop) {
            Load_module->minLoop = delta;
        }

    Best regards,
    Frank

  • Hi Frank,

    You could configure a Load.postUpdate function that calls Load_reset().  Your postUpdate function would be called immediately after the Load statistics are computed at the end of the Load benchmark window. (See the Load cdoc for a detailed description).

    Best regards,

        Janet

  • Hello Janet,

    i run this test for a longer time and it appeard that I got a min cpu load of 1% (which i can't belive) and a max cpu load of 100%.

    We can stop investigation here.

    Thanks again for your support.

    Frank