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.

Timer_create returns NULL, C6472, Bios 6.32.5.54

Other Parts Discussed in Thread: SYSBIOS, OMAP-L138, OMAPL138

Hi

I am executing the code below and get a NULL returned for the pointer handle.

I've checked the ROV ti.sysbios.timers.timer64.timer and it says "nulLocalTimers" = 6 and "numTimerDevices" = 24.

The ROV "Basic" tab shows only one timer instance with id 0 and intNum 14

The error block msg says "0x0081683A "E_alreadyD"" which when I look at the memory at 0x0081683A it has "E_alreadyDefined: Hwi already defined: intr# %d....."

Is there a way to pass the message in eb to some error handler for printing? I'd like to find out when intr %d is.

How can I change what HWI the timer module wants to use?

And one more question: Where do I find the enums for timers other than Timer_ANY?

The code below only runs on CORE 0.

Error_Block eb;

Timer_Params timerParams;

//Task_Handle taskHandle;

Log_print1(Diags_USER1, "Creating timer with period = %d", periodInUsec);

Log_print1(Diags_USER1, "The number of timers before create = %d", Timer_getNumTimers());

Error_init(&eb);

Timer_Params_init(&timerParams);

timerParams.period = periodInUsec; /* 2 ms */

timerParams.periodType = Timer_PeriodType_MICROSECS;

timerParams.startMode = Timer_StartMode_AUTO; // will start timer automatically

//timerParams.startMode = Timer_StartMode_USER; // needs Timer_start()

gapFillTimerHandle = Timer_create(Timer_ANY, gapFillTimerIsr, &timerParams, &eb);

//gapFillTimerHandle = Timer_create(1, gapFillTimerIsr, &timerParams, &eb);

//Timer_start(gapFillTimerHandle);

Log_print1(Diags_USER1, "The number of timers after create = %d", Timer_getNumTimers());

if (gapFillTimerHandle == NULL)

{

System_abort("Doppler timer create failed");

}

  • What version of SYS/BIOS are you using and on which device?

    You can add "eb" into a watch window and see what it contains. You can also use the Error APIs (e.g Error_print, Error_getMsg, Error_getSite, etc.) if you prefer to get it during runtime.

    Todd

  • D'oh! Sorry, I just looked at the title! Ignore my two questions. I'll try it out here.

  • I've attached a modified SYS/BIOS Task example. I've added your code snippet and confirmed the timer was created and ran properly at the configured rate. Can you create the Task example and substitute the .c and .cfg with the attached files? Does it run properly?

    Todd

  • Looks like attaching is not working...Trying again...

    2844.mutex.cfg.txt

    3225.mutex.c.txt

    Todd

  • Update

    I added timerParams.intNum = 13 and the handle was no longer NULL.

    Does't setting intNum to its default let the BIOS select an available interrupt to use?

    Cheers

  • It should. What does your useModule for Timer look like in your .cfg? What does your Timer #include look like in your .c? They must be the same (e.g. either ti.sysbios.hal.Timer or ti.sysbios.timers.timer64.Timer).

    Todd

  • Hi Todd

    Darn, I hopped that was the problem. Unfortunately they are the same.

    In my .c I have

    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    //#include <csl_tmr.h>
    #include <ti/sysbios/BIOS.h>
    #include <xdc/runtime/Diags.h>
    #include <xdc/runtime/Log.h>
    #include <xdc/runtime/Error.h>
    #include <ti/sysbios/timers/timer64/Timer.h>
    #include <ti/sysbios/hal/Cache.h>

    And in my .cfg I have

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

    Cheers

  • Did you resolve the problem? I have similar situation happening.

  • I noticed that it is happening when I am trying to use Timer 0 or Timer 1. Even when I set SYS/BIOS Timer ID to 2 or 3 I still can't use timer 0 and 1. Is there any solution for that?

  • Damian,

    Timer0 is local to core0...timer1 is local to core1...this is true for the first 6 timers.  SYSBIOS by default uses the Lower half of each of those timers for its Clock for the core its executing on.

    The upper half can still be used by the app, but must be specified in the params when creating the Timer:

    ie (in cfg).....   params.half = Timer.Half_UPPER;

    Setting Timer ID to 2 or 3 will give you Timer 2 or 3.

    If you want to use a timer that is shared by several cores, use one of the shared timers (id 7-12).

    Judah

  • I forgot to mention that I am using OMAP-L138. How are Timer assigned in it?

  • Um...yes, i thought you were on the same device as the original poster of this thread.

    On OMAP-L138 you have Timers 0-3 for DSP but you have to be weary of what timers the ARM is using so that you don't collide.

    There are no hard assignments.  You should be able to grab any of those timers.  Timers 2,3 cannot be run as 2 -32bit timers while 0,1 can be run as 2 32-bit timers.

    As before, this can be specified via the "half" parameter...either Half_LOWER or Half_UPPER.

    Judah

  • I am trying to understand what is all about in the TM64P_OUT and TM64P_IN GPIO mode. I have read the spruh77a datasheet and the library documentation from following website:

    ti.sysbios.timers.timer64.timer

    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/index.html

    I am still confused how it works. Is there any other more detailed specification of this functions? How it relates to the fact that in OMAP-L138 TM64P_OUT and TM64P_IN are on the same pin? What are doing exacly GPINT__ENO, GPINT__ENI, GPDATO__, GPDATI__ bits? What is TIMER mode in GPIO mode?

    I will appreciate if somebody will explain this peripheral more clearly.

    One more thing. Why no matter what timer I choose as a SYS/BIOS clock I can't  'Timer_create' on this with ID 0 ?

  • I have double checked and it seems like I can't create a timer with ID 0 and use lower half. It is possible to create it when using upper half. But I need to generate clock on PIN TM64P0_OUT12. 

    Error_block says "E _ n o t A v a i l a b l e".

    Is this problem is related with SYS/BIOS configuration ?

  • Damian,

    The most likely reason why you can't use Timer 0 lower half is because BIOS is using it by default thus...its "not available".

    Having said that, you can change the BIOS default and then use it as you like.  Try the following:

    var Clock = xdc.module ('ti.sysbios.knl.Clock');
    Clock.timerId = 1;

    Now, try creating your Timer 0 is you have tried.

    Judah

  • Judahvang,

    In previous posts I described situation which you are talking about. 

  • I'm sorry, what do you mean?

    You said you can't create a Timer 0 lower half and I proposed a reason why you can't and how you can go about creating it.

    Judah

  • Judah,

    I am just saying that I have tried your solution before. I mentioned it in my previous post:

    "Even when I set SYS/BIOS Timer ID to 2 or 3 I still can't use timer 0 and 1. Is there any solution for that?"

    I am looking for reason why I can't use Timer 0 lower half no matter which timer I will choose for clock in SYS/BIOS configuration.

  • Damian,

    Can you attach your *.cfg file here?

    I'm looking at the source code and I don't see a reason why you can't do what I have suggested.

    Judah

  • Here it is:

    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 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 Swi = xdc.useModule('ti.sysbios.knl.Swi');
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
    var Event = xdc.useModule('ti.sysbios.knl.Event');
    var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
    var Cache = xdc.useModule('ti.sysbios.family.arm.arm9.Cache');
    var Exception = xdc.useModule('ti.sysbios.family.arm.exc.Exception');
    var Mmu = xdc.useModule('ti.sysbios.family.arm.arm9.Mmu');
    var Memory = xdc.useModule('xdc.runtime.Memory');
    var ti_sysbios_hal_Cache = xdc.useModule('ti.sysbios.hal.Cache');
    var Agent = xdc.useModule('ti.sysbios.rta.Agent');
    var ti_sysbios_timers_timer64_Timer = xdc.useModule('ti.sysbios.timers.timer64.Timer');
    var ti_sysbios_family_arm_da830_Hwi = xdc.useModule('ti.sysbios.family.arm.da830.Hwi');
    var Clock = xdc.useModule('ti.sysbios.knl.Clock');

    //************ CACHE DEFINITION ************

    Cache.enableCache = true;
    Mmu.enableMMU = true;
    var peripheralAttrs = {
    type : Mmu.FirstLevelDesc_SECTION, // SECTION descriptor
    bufferable : false, // bufferable
    cacheable : false, // cacheable
    };

    // Define the base address of the 1 Meg page
    // the peripheral resides in.
    var peripheralBaseAddr = 0x01E00000; /* substitute the 1MB base address of your peripheral here */

    // Configure the corresponding MMU page descriptor accordingly
    Mmu.setFirstLevelDescMeta(peripheralBaseAddr, peripheralBaseAddr, peripheralAttrs);
    peripheralBaseAddr = 0x01D00000;
    Mmu.setFirstLevelDescMeta(peripheralBaseAddr, peripheralBaseAddr, peripheralAttrs);

    // ************ END CACHE DEFINITIONS ************

    /*
    * Program.argSize sets the size of the .args section.
    * The examples don't use command line args so argSize is set to 0.
    */
    Program.argSize = 0x0;

    /*
    * 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 = 0x80000;

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

    /* 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;
    Task.defaultStackSize = 4096;
    Task.deleteTerminatedTasks = true;
    Memory.defaultHeapSize = 524288;
    Agent.sysbiosSwiLogging = true;
    Agent.sysbiosHwiLogging = true;
    Agent.sysbiosHwiLoggingRuntimeControl = true;
    Agent.sysbiosSwiLoggingRuntimeControl = true;
    Agent.sysbiosTaskLoggingRuntimeControl = true;
    Clock.timerId = 2;

  • Damian,

    It turns out that on the ARM side of OMAPL138, there's two timers that are being used. 1 by the Clock module and 1 by the Timestamp module.  Had you created your Timer 0 statically in your *.cfg file it would have worked for you since it would have grabbed Timer 0 before the Timestamp module, but since you are creating this at runtime, you need to also specify a different Timer for the Timestamp module.  Add the following to your cfg file

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

    Now your program should not get an error when you try to create Timer 0.

    Judah

  • Is it possible to turn off the TimestampProvider?

  • Looks like you can tell Timestamp to use the same timer as Clock.  If you do this then it won't try to create its own Timer.

    Timestamp.useClockTimer = true;

    Judah

  • Thank you, this solved the problem.

    Do you have any idea where I can get more information about Timers GPIO mode? I didn't found clear explanation in spruh77 datasheet - it still makes me confused when I am reading it.

  • Damian,

    That question is out of the realm of my expertise.  I think its best if you open a new thread in a hardware specific forum to get a quicker response.

    Judah