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.

RTOS/66AK2H12: Mailbox_pend() Timeount value

Part Number: 66AK2H12
Other Parts Discussed in Thread: SYSBIOS, TCI6636K2H

Tool/software: TI-RTOS

I read that the timeout value used in Mailbox_pend() is in "system clock ticks". I've read here in the E2E forum that the default for clock ticks is 1/ms. I checked my cfg under XGCONF and indeed SYS/BIOS-Scheduling-Clock : Timer Control Tick period (us) is 1000. When running I check the global Clock_tickPeriod and see it is 1000. Yet if I set my Mailbox_pend() timeout to 10000 expecting to get  a timeout in 10 seconds, I am getting closer to 2 seconds. What am I doing wrong?

Mike

  • Hi,

    Which RTOS version are you using?

    Best Regards,
    Yordan
  • XDCtools 3.50.02.20, SYS/BIOS 6.50.01.12
  • Hi again Yordan. Can you check w/ sw team on this? I'm hoping it should be an easy answer.
    Kind regards, Mike
  • Mike,

    Do you see the incorrect Mailbox_pend() timeout in ARM or DSP? Would it be possible for you to upload a small CCS project that can demonstrate the issue?

    Regards,
    Garrett
  • Garrett,

    Thanks for looking into this. I am running on the ARM. Build info is:

    XDCtools 3.50.02.20, SYS/BIOS 6.50.01.12, NDK 2.25.1.11, GNU 4.9.3.

    I've built a small example but I'm not sure how to uploaded. I'll post the code below my name.

    Maybe my question to start with should have been:

    What is the proper/preferred  way to convert milliseconds to system clock ticks?

    Mike

    main.c:

    /*
    * ======== main.c ========
    */

    #include <xdc/std.h>

    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>

    #include <ti/sysbios/BIOS.h>

    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Mailbox.h>

    /*
    * ======== taskFxn ========
    */
    Void taskFxn(UArg a0, UArg a1)
    {
    int mail;

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

    Mailbox_Handle h = Mailbox_create(sizeof(mail), 1, NULL, NULL);

    // 10 seconds (10000 ms) to "system clock ticks"
    UInt toSysTicks = (10000 * 1000 / Clock_tickPeriod);
    for ( int i = 0; i < 5; i++ ) {
    Mailbox_pend(h, &mail, toSysTicks);
    System_printf("Got TO\n");
    System_flush(); /* force SysMin output to console */
    }

    System_printf("exit taskFxn()\n");

    System_flush(); /* force SysMin output to console */
    }

    /*
    * ======== main ========
    */
    Int main()
    {
    Task_Handle task;
    Error_Block eb;

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

    Error_init(&eb);
    task = Task_create(taskFxn, NULL, &eb);
    if (task == NULL) {
    System_printf("Task_create() failed!\n");
    BIOS_exit(0);
    }

    BIOS_start(); /* does not return */
    return(0);
    }

    app.cfg:

    var Defaults = xdc.useModule('xdc.runtime.Defaults');
    var Diags = xdc.useModule('xdc.runtime.Diags');
    var Error = xdc.useModule('xdc.runtime.Error');
    var Log = xdc.useModule('xdc.runtime.Log');
    var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
    var Main = xdc.useModule('xdc.runtime.Main');
    var Memory = xdc.useModule('xdc.runtime.Memory')
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    var System = xdc.useModule('xdc.runtime.System');
    var Text = xdc.useModule('xdc.runtime.Text');

    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    var Mailbox = xdc.useModule('ti.sysbios.knl.Mailbox');
    var Swi = xdc.useModule('ti.sysbios.knl.Swi');
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');

    /*
    * Uncomment this line to globally disable Asserts.
    * All modules inherit the default from the 'Defaults' module. You
    * can override these defaults on a per-module basis using Module.common$.
    * Disabling Asserts will save code space and improve runtime performance.
    Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
    */

    /*
    * Uncomment this line to keep module names from being loaded on the target.
    * The module name strings are placed in the .const section. Setting this
    * parameter to false will save space in the .const section. Error and
    * Assert messages will contain an "unknown module" prefix instead
    * of the actual module name.
    Defaults.common$.namedModule = false;
    */

    /*
    * Minimize exit handler array in System. The System module includes
    * an array of functions that are registered with System_atexit() to be
    * called by System_exit().
    */
    System.maxAtexitHandlers = 4;

    /*
    * Uncomment this line to disable the Error print function.
    * We lose error information when this is disabled since the errors are
    * not printed. Disabling the raiseHook will save some code space if
    * your app is not using System_printf() since the Error_print() function
    * calls System_printf().
    Error.raiseHook = null;
    */

    /*
    * Uncomment this line to keep Error, Assert, and Log strings from being
    * loaded on the target. These strings are placed in the .const section.
    * Setting this parameter to false will save space in the .const section.
    * Error, Assert and Log message will print raw ids and args instead of
    * a formatted message.
    Text.isLoaded = false;
    */

    /*
    * Uncomment this line to disable the output of characters by SysMin
    * when the program exits. SysMin writes characters to a circular buffer.
    * This buffer can be viewed using the SysMin Output view in ROV.
    SysMin.flushAtExit = false;
    */

    /*
    * The BIOS module will create the default heap for the system.
    * Specify the size of this default heap.
    */
    BIOS.heapSize = 0x1000;

    /*
    * Build a custom SYS/BIOS library from sources.
    */
    BIOS.libType = BIOS.LibType_Custom;

    /* System stack size (used by ISRs and Swis) */
    Program.stack = 0x2000;

    /* Circular buffer size for System_printf() */
    SysMin.bufSize = 0x200;

    /*
    * Create and install logger for the whole system
    */
    var loggerBufParams = new LoggerBuf.Params();
    loggerBufParams.numEntries = 16;
    var logger0 = LoggerBuf.create(loggerBufParams);
    Defaults.common$.logger = logger0;
    Main.common$.diags_INFO = Diags.ALWAYS_ON;

    System.SupportProxy = SysMin;

  • Mike,

    The issue appears to be caused by default frequency for systimer that BIOS assumes for the clock tick. From Clock_getTicks(), the Mailbox_pend() or Task_sleep() does pend/sleep as expected ticks. You may try to add the following code snippet in your cfg file:

    /* Set CPU freq to 1GHz */
    BIOS.cpuFreq.lo = 1000000000;
    BIOS.cpuFreq.hi = 0;

    /* Set Timer64 freq */
    var Timer = xdc.useModule('ti.sysbios.timers.timer64.Timer');
    for (var idx = 0; idx < 18; idx++) {
    Timer.intFreqs[idx].lo = 163840000; // PLL freq / 6
    Timer.intFreqs[idx].hi = 0;
    }

    /* Set systimer freq */
    var SysTimer = xdc.useModule('ti.sysbios.family.arm.systimer.Timer');
    SysTimer.intFreq.lo = 163840000; // PLL freq / 6
    SysTimer.intFreq.hi = 0;

    Regards,
    Garrett

  • Hi Garrett and thanks for looking into this.
    I would really not like to change clock frequencies or other configuration info for my SBC. There are others on the project that have specific requirements and if I change these I'm pretty sure it will mess them up. I'd rather go the other direction and convert my desired milliseconds into the number I need to pass to these functions give what I'm given in so far as cpu freq., pll, etc. . Can you tell me how to do that?
    mike
  • Mike,

    If so, you need to multiply your desired milliseconds by 6 as timeout value. The default system timer uses 1GHz CPU frequency as timer frequency without above code snippet in cfg.

    Regards,
    Garrett
  • I don't need to get any system variables like Clock_tickPeriod or read any cfg data? Just multiple by 6?
  • Mailbox_Handle h = Mailbox_create(sizeof(mail), 1, NULL, NULL);

    // 10 seconds (10000 ms) to "system clock ticks"
    UInt toSysTicks = (10000 * 1000 / Clock_tickPeriod);
    toSysTicks = (10000 * 6);
    for ( int i = 0; i < 5; i++ ) {
    Mailbox_pend(h, &mail, toSysTicks);
    }

    System_printf("exit taskFxn()\n");

    The above gets me about 39 seconds from the for() to the System_printf(). It should be 50 seconds.
  • Mike,

    The shared local clock divider for Timers is 6, see table 11-13 of data sheet - Main PLL Controller Module Clock Domains Internal and Shared Local Clock Dividers. You CPU frequency SYSCLK1 might not be 1 GHz, and you can find out with
    xdc_runtime_Types_FreqHz cpuFreq;
    BIOS_getCpuFreq(&cpuFreq);
    System_printf("cpuFreq.lo= %d\n", cpuFreq.lo);

    Regards, Garrett
  • xdc_runtime_Types_FreqHz cpuFreq = 125000000 (hi = 0, lo = 125000000)
  • What does Clock_tickPeriod give me? (From ti.sysbios.knl.Clock) It says "Tick period specified in microseconds". Mailbox_pend() timeout is in "maximum duration in system clock ticks". What is a "system clock tick"?
  • Mike,

    You can specify the tick period in cfg file:
    /* Clock tick in microseconds */
    Clock.tickPeriod = 1000;

    Regards,
    Garrett
  • From one of my prior posts: "I checked my cfg under XGCONF and indeed SYS/BIOS-Scheduling-Clock : Timer Control Tick period (us) is 1000. When running I check the global Clock_tickPeriod and see it is 1000."
  • Mike,

    xdc_runtime_Types_FreqHz cpuFreq = 125000000, i.e. 125MHz not 1250000000, 1.25GHz?
    Your 39 seconds (instead of 50 seconds) is probably from 50 * (1GHz/1.25GHz).
    By setting up correct cpuFreq and timer/systimer intFreq.lo in cfg file according to your board config seems to be the solution.

    Regards,
    Garrett
  • Yes, 125Mhz. If I knew how to do a screen shot of the XGCONF screen I would. Under SYS/BIOS > System > Program - Runtime Sizes there is an area call Platform Information * In that area it has:
    Device name TCI6636K2H Clock rate (MHz) 125.0
  • 125MHz is TCI6636K2G reference clock.
    cpuFreq is expected to be computed by reference clock and PLLM/CLKOD as shown in GEL script function Set_Tetris_Pll().
    You need to specify the cpuFreq in cfg file correctly: BIOS.cpuFreq.lo = 1000000000; /* 1GHz */ or 1.4GHz according to your custom board configure, and set up Timer/SysTimer.intFreq.lo accordingly.

    Regards, Garrett