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.

Bios6 and Timers

Other Parts Discussed in Thread: SYSBIOS

I would like to know in a C6472, what hardware timers does BIOS6 use? I ask because I would like to use the two timer input pins and the timer output pin , as well as the watchdog feature (and pin) without interfering with BIOS. Do all timer or periodic functions use the same hardware timer?

  • The answer depends on what version of BIOS 6 you have.  For BIOS v6.30 and later, each core on the C6472 would use its local timer.  Another words...if you build an app without specifying which Timer you want BIOS to use, and you ran the app on core0 it would use Timer0.  Run the same app on core1 and it would uses Timer1, etc...  I recommend you read the 'cdoc' documention for ti.sysbios.timers.Timer64.Timer for additional information like if you want to used one of the shared timers.

    For earlier versions of BIOS 6, BIOS uses the first available Timer.  In the general cases this would be Timer 0.  The only time Timer 0 is not used is if the user grabs it first.

    In general, yes, all timing sevices in BIOS is driven by the Clock module which uses the Timer as its source, however, this is configurable by the user.  See the ti.sysbios.knl.Clock module for additional information.

  • I am using BIOS 6_21_00_13.

    After looking through those docs, I am very confused as to how all of the various Timer modules play together. I currently have: ti.sysbios.knl.clock, ti.sysbios.hal.timer, and ti.sysbios.timers.timer64.timer. To that end, I went through and specified a timer ID for each specific timer. ti.sysbios.knl.clock.timerid = 0, an instance of ti.sysbios.hal.timer has an id of 1. then I have three instances of ti.sysbios.timers.timer64.timer: two sharing timer id 2 (one using the lower 32bit counter, the other using the upper 32 bit counter), and timer id 3 i would like to be a watchdog timer. While trying to use XDCScript to set this up in combination with the GUI is rather interesting. In particular I am having difficulties with the timer settings value. This is my latest failed attempt:

    ti_sysbios_timers_timer64_Timer.timerSettings = [{ti_sysbios_timers_timer64_Timer.Mode_64BITGPTIMER,true},{ti_sysbios_timers_timer64_Timer.Mode_64BITGPTIMER,true},{ti_sysbios_timers_timer64_Timer.Mode_UNCHAINED,true},{ti_sysbios_timers_timer64_Timer.Mode_WATCHDOG,true}];

  • The relationship between ti.sysbios.knl.clock, ti.sysbios.hal.Timer, and ti.sysbios.timers.timer64.Timer is this:  The default behaviour of clock is that it is driven by a Timer (in this case, ultimately ti.sysbios.timers.timer64.Timer).  ti.sysbios.hal.Timer is a common interface Timer module.  Typically you would want to use this if you aren't doing anything that is Timer specifiec and you want to to compile and/or run the same code across different devices and/or platforms.  The ti.sysbios.hal.Timer always has a proxy to the real Timer on the device.  In this case ti.sysbios.timers.timer64.Timer is the real Timer on the device.  In your particular case, I'd recommend to configure timer64.Timer directly.

    Looking at what you want to do, you need to understand. 1) On 6472, the first 6 timers are local to a core.  So Timer 0 can generate an interrupt to Core 0 but not to Cores 1-5.  Timer 1 can generate an interrupt to Core 1 but not Core 0,2,3-5, etc...  So the question I have is...Are you planning on creating a single executable file that configures all the Timers or multiple executables?  Are you planning on running on a single core or multiple cores?  Would you rather use shared timers (generates an interrupt to all cores) as opposed to local timers? If using shared timers makes sense, I would recommend moving to BIOS v6.30 or later because v6.21.00.13 does not have support for the shared timers (These would be Timers 6-11).  Having said that, here's how the configuration might look.

    var Clock = xdc.useModule("ti.sysbios.knl.Clock") ;

    Clock.timerId = 0;  // causes BIOS to use timer 0 (which is a good thing if you're planning on running on core 0).

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

    // Module wide config parameters for Timer

    Timer.timerSettings[2].mode = Timer.Mode_UNCHAINED; // puts timer2 in unchained mode
    Timer.timerSettings[2].master = true;                                        // tells core to release timer from reset

    Timer.timerSettings[3].mode = Timer.Mode_WATCHDOG;  // puts timer3 in watchdog mode
    Timer.timerSettings[3].master = true;                                        // tells core to release from reset

    // Instance config parameters for Timer

    var timerParams = new Timer.Params();  // create a new Timer params struct

    timerParams.period = 1000;                                                        // set to your period value here 
    timerParams.half = Timer.Half_LOWER;                                  // specify the lower half here
    timerParams.runMode = Timer.RunMode_CONTINUOUS;  // specify if continuous mode
    Timer.create(2, '&myFunc2lower', timerParams);                   // create timer id = 2, function and timer parameters

    timerParams.period = 1000;                                                       // set your period value here
    timerParams.half = Timer.Half_UPPER;                                  // specify upper half here
    timerParams.runMode = Timer.RunMode_CONTINUOUS; // specify continuous mode
    Timer.create(2, '&myFunc2upper', timerParams);                  // create timer id = 2, function, parameters

    timerParams.period = 1000;                                                 // set to your period value here 
    timerParams.runMode = Timer.RunMode_ONESHOT;  // specify if one shot or continuous mode
    Timer.create(3, '&myFunc3', timerParams);                      // create timer with id = 3, function and timer parameters

  • Ahh, that is quite enlightening.

    I had always misinterpreted the shared vs local timer on the 6472. Thanks for clearing that up. I had thought that each core had 6 local timers, not that here are 6, one for each core.

    At the moment I am planning on only using one core.

    That lack of shared timer support in 6.21, sounds odd to me. If 6.21 only supports local timers how do you have more than one timer function? or is it just the timer64 which does not support the shared timers? but the hal.timer and knl.clock does?

    Sounds like I do want to upgrade to 6.3 since I have to use the shared timers to access the external timer pins.

    Are there any drawbacks to upgrading to 6.3? One of my colleagues who is also coming up to speed with the tools and this part has mentioned that he had read that upgrading to 6.3 may be unwise.

  • BIOS v6.21 doesn't have the support for creating Timers 6-11 (Shared Timers) for timer64 which is the underlying Timer for hal.timer and knl.clock.  This support was added in BIOS v6.30.  What other packages are you using besides BIOS (like PSP, NDK, etc...)?  Upgrading to BIOS v6.30 should not be a problem but depends on what other packages you are using.  If you are using those other packages that are dependent on BIOS v6.21 then it could be a problem.  So let me know what the other packages you are using and their versions.  There aren't any drawbracks to upgrading to BIOS v6.30 as far as I know.

  • I am using the NDK, and we are working on developing a custom HPI driver.

    Is upgrading the NDK as simple as pointing it to the new version of bios and rebuilding? I have rebuilt the NDK before without problems.

    Are there going to be any  major issues with the custom HPI driver we are developing? We started with the ti.ipc.sdo.stream driver wizard.

  • If you are able to rebuild the NDK, moving to BIOS v6.30 should not be a problem.  Yes, you should be able to point the NDK to the new BIOS and rebuild it.  I dont forsee any problems moving to the later BIOS version.  Note:  You need to update your XDC tools to v3.20 or later.  The release note for the particular BIOS version tells you what XDC version you need.

  • OK, I have a pretty good handle on things now. I just have one more set of questions for my own understanding.

    If in previous versions of BIOS you could only have access to one timer, how did BIOS deal with multiple periodic functions? Does BIOS really only need one timer to deal with all PRD functions?

  • BIOS itself only needs one timer to deal with periodic functions.  Unless your application needs another timer, things would be okay.

    Having said that, this problem (not having support for shard timers) only exists for BIOS v6.0 to v6.2x.  Earlier versions of BIOS v5.x had this support and the current BIOS v6.3x has this support in it also.

    Furthermore, BIOS supports many devices and this problem only existed for homogeneous multi-core devices like C6472.  The original timer64/Timer module was meant for a single core initializing the Timer and so with the added Shared Timers, we had to add additional configuration to support this.

    In general, BIOS supports all timers available on each device.

  • Thanks for all the help and clarifications!

  • After some fighting with trying to get BIOS6.3 running I have come up with a blank. I rebuilt the NDK, and created a new cfg file for BIOS, and every time I go to run the program through the debugger it throws an exception. I have turned the exception print on, but it does not print the first 6 registers (I'm guessing)

    Console output:

     00008029, A7 =  00000000
    A8 =  00000000, A9 =  efefefef
    A10 = 00000000, A11 = 00000000
    A12 = 00000000, A13 = 00000000
    A14 = 00000000, A15 = 00000000
    A16 = 002776fc, A17 = deadbeef
    A18 = 00273700, A19 = 00003ff0
    A20 = 00083aaf, A21 = 00000000
    A22 = fffffffe, A23 = fff500a6
    A24 = 5b57021f, A25 = 03567e01
    A26 = 00000008, A27 = fff500a6
    A28 = 00000008, A29 = bffe4000
    A30 = d59f8072, A31 = 00000000
    B0 =  0084c0c8, B1 =  00000000
    B2 =  00000000, B3 =  00836600
    B4 =  00000000, B5 =  10000103
    B6 =  00000000, B7 =  00000001
    B8 =  00265488, B9 =  07d00000
    B10 = 00000000, B11 = 00000000
    B12 = 00000000, B13 = 00000000
    B14 = 00280e98, B15 = 0084a598
    B16 = 00000000, B17 = 00272e14
    B18 = 00897e04, B19 = 18c40000
    B20 = ffffffff, B21 = 00018c40
    B22 = ffffffff, B23 = 00631000
    B24 = ffffffff, B25 = ffffffff
    B26 = ffffffff, B27 = 40d10000
    B28 = ffffffff, B29 = d1000000
    B30 = 00000024, B31 = 00000090
    NTSR = 0001000f
    ITSR = 0000000d
    IRP  = 00846654
    SSR  = 00000000
    AMR  = 00000000
    RILC = 00000000
    ILC  = 00000000
    Exception abort!

     

    4857.bios6_test3.zip

  • add the following 2 lines to your .cfg file to increase the size of the default error buffer.   I guess we need to change the default (1024).

     

    var xdc_runtime_SysMin = xdc.useModule('xdc.runtime.SysMin');
    xdc_runtime_SysMin.bufSize = 2048;

  • Sorry.  Hit send too soon.

     

    After doing the above, you should get a more complete error message.   You are getting an exception.  The error message should give summary of the exception.  The 'NIRP' register should point at/near the instruction that triggered the exception.

  • Ahhhhhhh.... thanks for the tip. The exception was an Instruction fetch exception. and based on the IRP register and the disasembly, it occurred in the             ti_sysbios_family_c64p_Hwi_enable__E function. I don't think it helps me too much but hopefully you gurus have an idea on where to go next.

  • Just wanted to chime in a correction:  You should be looking at the "NRP" register not "IRP".  "NRP" is for exceptions.  "IRP" is for interrupts

  • The 'NIRP' is the register of most interest.  IRP is the interrupt return pointer.  NIRP is the "NMI Interrupt return pointer".   When and exception is caught, the PC vectors to NMI and stores the return address in NIRP.

    -Karl-

  • After expanding the size of the log i received the following dump:

    Exception_handler: EFR=0x2, NRP=0x0, mode=supervisor
    Internal exception: IERR=0x1
    Instruction fetch exception
    A0 =  00000000, A1 =  00000000
    A2 =  00000000, A3 =  00000000
    A4 =  00000000, A5 =  002739a0
    A6 =  00008029, A7 =  00000000
    A8 =  00000000, A9 =  efefefef
    A10 = 00000000, A11 = 00000000
    A12 = 00000000, A13 = 00000000
    A14 = 00000000, A15 = 00000000
    A16 = 00277afc, A17 = deadbeef
    A18 = 00273b00, A19 = 00003ff0
    A20 = 00000aaf, A21 = 0002f760
    A22 = fffffffe, A23 = fff50073
    A24 = 2f760000, A25 = 00000017
    A26 = 304f02bf, A27 = fffffffe
    A28 = 05eec000, A29 = 00004000
    A30 = d59f8072, A31 = 00000000
    B0 =  0084c0c8, B1 =  00000000
    B2 =  00000000, B3 =  00836600
    B4 =  00000000, B5 =  10000103
    B6 =  00000000, B7 =  00000001
    B8 =  00265888, B9 =  07d00000
    B10 = 00000000, B11 = 00000000
    B12 = 00000000, B13 = 00000000
    B14 = 00281298, B15 = 0084a598
    B16 = 00000000, B17 = 00273214
    B18 = ffffffff, B19 = 38800013
    B20 = ffffffff, B21 = 04000181
    B22 = ffffffff, B23 = 204c1800
    B24 = ffffffff, B25 = ffffffff
    B26 = ffffffff, B27 = 09830000
    B28 = ffffffff, B29 = 81306000
    B30 = ffffffff, B31 = 00000090
    NTSR = 0001000f
    ITSR = 0000000d
    IRP  = 00846654
    SSR  = 00000000
    AMR  = 00000000
    RILC = 00000000
    ILC  = 00000000
    Exception abort!

    I looked around for the NIRP register in the debugger, and could not find it. The NRP register is 0. so perhaps the code is jumping to address 0?

  • There is no "NIRP"...its just NRP.  NRP = 0 means the code is trying to execute address 0 as you suggested.

  • Probably.   Sorry about the NIRP reference.  NRP is right.  B3 is usually a return address.   Put B3 in a dissassembly window .   A few instructions above it will be a function call to the offending function.  The offending function is probably calling a function through a function pointer.   Lots of 0's in the A0-An registers above.

  • It looks like the offending function is ti_sysbios_knl_Task_exit__F. Based on that a Task is exiting, even though every task in this program is static and should never exit. I have ben having issues stepping since I swiched to 6.3, so I don' think BIOS has even fully started yet.

  • Another bit of odd behavior is when I insert a break point anywhere after BIOS Start, the device never seems to get that exception. I also never seems to run either. I can halt it, and tell it to run again, but it never seems to reach the "user" portion of my code.

  •  Are you using CCS for your builds?  If so, are you building with a "debug" profile?  This should allow source level debug.

  • I am using CCS Version: 4.2.0.10012, I am also using the Debug profile. 

    When I randomly halt and then run, the device always seems to stop in one of two locations:

    0 ti_sysbios_hal_Hwi_initStack() at Hwi_stack.c:86 0x00845f4c

    or

    0 ti_sysbios_family_c62_TaskSupport_start__F(void *, function *, function *, struct xdc_runtime_Error_Block *) at TaskSupport.c:109 0x0083ef4e

    Sometimes I can catch it in other BIOS module init functions, but I have ben letting it run for minutes at a time and then halting, and it is mostly the same stuff. When I run without stepping, or breakpoints, i wil hit the exception in seconds.

  • The Hwi_initStack() function is really early on.  Do you even get to main()?  If you don't, it means something is busted in the initialization.  If you do, it suggests that something is causing a restart.  I recommend putting a breakpoint on "ti_sysbios_family_c64p_Hwi0" which is the reset vector and also "ti_sysbios_family_c64p_Hwi1" which is the NMI vector (Exceptions are processed here).

  • So it does constantly cycle to HWI0. But why does it do that when I add a breakpoint else where in my code, but not when I run normallly?

  • You need to do a CPU reset between runs.  I think what's happening is that after you get an exception and restart the program without resetting the CPU, the state of the program thinks that you are still processing an exception and when another exception happens, it goes into the reset vector.

  • OK. When the debug sessions were getting stuck, I was not resetting the board properly. So that just leaves us with the exception that is occurring.

  • OK, now that I have made it past the 6.3 upgrade, I can ask some more timer related questions.

    It appears that the only timer mode for timer64 which will not error is Mode_UNCHAINED.

    When I have the following in my cfg file:

    var ti_sysbios_timers_timer64_Timer = xdc.useModule('ti.sysbios.timers.timer64.Timer');
    ti_sysbios_timers_timer64_Timer.timerSettings[0].mode = ti_sysbios_timers_timer64_Timer.Mode_WATCHDOG;
    ti_sysbios_timers_timer64_Timer.timerSettings[0].master = true;
    ti_sysbios_timers_timer64_Timer.timerSettings[0].ownerCoreId = 0;
    ti_sysbios_timers_timer64_Timer.timerSettings[6].mode = ti_sysbios_timers_timer64_Timer.Mode_UNCHAINED;
    ti_sysbios_timers_timer64_Timer.timerSettings[6].master = true;
    ti_sysbios_timers_timer64_Timer.timerSettings[6].ownerCoreId = 0;

    I get this error:

    Severity and Description    Path    Resource    Location    Creation Time    Id
    ti.sysbios.timers.timer64.Timer : Unsupported mode: 2 is specified for Timer: 0        bios6_test3    line 1097    1288271545379    1798

    I am also using the following clock resource:

    var ti_sysbios_knl_Clock = xdc.useModule('ti.sysbios.knl.Clock');
    ti_sysbios_knl_Clock.timerId = 6;
    var instti_sysbios_knl_Clock0Params0 = new ti_sysbios_knl_Clock.Params();
    instti_sysbios_knl_Clock0Params0.instance.name = "net_timer";
    instti_sysbios_knl_Clock0Params0.startFlag = true;
    Program.global.net_timer = ti_sysbios_knl_Clock.create("&llTimerTick", 10, instti_sysbios_knl_Clock0Params0);

    Is using knl.clock conflicting with timer64?

  • Timer64 does not support setting up your Timer in WATCHDOG mode.  It only supports chained and unchained mode.  For WATCHDOG, you will need to program the Timer directly.