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.

CLK and PRD misses timer interrupts?

Hi all,

I'm hunting a big problem in one of our video applications on a DM642 customized board using CCS 3.0, BIOS 4.90, CGT 5.0  (yes, the project is frozen to this old versions).

We have implemented a software clock, wich is updated by a CLK or PRD handler function every 1ms. The clock is synchronized via network using the SNTP protocol. Everything is fine, the time is very accurate. But under some circumstances the clock time is too slow: using a SNTP sync every 1s I see differences up to 300ms!

My idea is that somebody blocks the interrupts globally or especially the timer 0 interrupt. Tracking down some suspects I found nothing! But one thing I saw: we use the DEV functions, especially in this special test-case very often (dynamic device create/destroy). Removing the DEV functions the time error reduces significantly, nearly 33%. But there is still too much remaining.

My question is: is it possible that there are BIOS functions which may influence the CLK/PRD accurancy? Or are there hardware blocks doing this (on initialization time? Maybe the video port hardware?)

Any ideas? Please tell me!

Kind regards,
Andi

 

  • Andreas,

    I didn't totally understand your problem description, but here are a few thoughts...

    It isn't clear to me whether your PRD is based on the real time clock, or whether you are using an external signal to call PRD_tick().  If you are calling PRD_tick from an interrupt function, you should make sure that this HWI is properly implemented with the HWI dispatcher or HWI_enter/exit() calls so that the BIOS scheduler functions properly.

    The PRD is called form the context of a SWI thread, so it can be prempted by other SWIs running at the same priority or by hardware interrupts.  You should make sure that the PRD SWI is running at the highest priority possible and that any other SWIs you are using run at a lower priority.  Also, you should look at your interrupts to make sure that the BIOS scheduler is not disabling SWIs for any extended period of time.

    Not sure what else to suggest...

  • David,

    thank you for your response. I will try to clearify some issues. We use a standard CDB file configuration, CLK and PRD are configured within the CDB file. CLK is configured to use timer 0 with an interrupt every 1ms. PRD depends on CLK. SWI: we have no additions or changes in SWI, KNL_swi is on priority 0 and PRD_swi is on priority 1.

    You see, we have no own implementations for CLK, PRD, SWI. Our application is a set aof TSK's only. Of course some interrupt handler are in use, for video port handling and other hardware dependend stuff.

    For most of all use cases everything is well, but for som special cases it look like CLK and PRD increments are lost or forgotten. I have found nothing in our application parts yet, therefore I am afraid about some special cases inside system libraries. As discribed in my original post, I saw an effect on removing calls to the DEV module in high frequency.

    For the moment I'm not able to isolate this problem to a simple test application...

    Kind regards,
    Andi

  • Ok, in the meantime I found one troublemaker! Using DEV_createDevice(), not only the init function (via function pointer parameter) is called. Additionally, the mdBindDev() function in the video port driver is called, with GIE disabled. And our implementation for VP init requires long waiting loops because on reset delays... Nevertheless, it is in my area!

    This is not the only one, there must be other troublemakers. I must find them one by one.

    Kind regards,
    Andi

  • Today I checked the system for another troublemaker. I found a problem using memset() on large blocks (> ~300kB)! It looks like memset() influences the CLK/PRD updates or interrupts! I'm trying to isolate this to a clean and small example, but does somebody know an issue about memset and PRD ticks?

    Andi

     

  • Finally, I think I got it. We use a lot of memset() call at instance initialization for large memory blocks, i.e. video frame buffer. memset() is very well optimized, using a full piplined kernel loop. I found this information (Source: http://processors.wiki.ti.com/index.php/Interrupts_Disabled_by_C6000_Compiler):

    "Inside a software pipeline loop, things are quite different. On C6000, during the execution of a branch and its delay slots, 5 cycles total, interrupts are disabled. And with 8-way parallelism, lots of instructions can be scheduled in those 5 cycles. It is common for a software pipeline loop to be completely contained within the the delay slots of the branches. Casual scheduling of such a loop leads to interrupts being disabled during the entire time the loop is running."

    What a Pitfall! Thats the reason why CLK/PRD interrupts are lost! Is there any documentation for BIOS or RTS functions where such side-effects can be found? I'm now a little bit puzzled...

    Andi

  • The C6000 compiler supports generating code for loops that can be interrupted. See the user's guide, such as, http://focus.ti.com/lit/ug/spru187o/spru187o.pdf, Section 2.12. You can then rebuild the RTS library using whatever options you want following the documentation in the user's guide Section 8.5 or outlined on the wiki: http://processors.wiki.ti.com/index.php/How_to_rebuild_the_C6000_RTS

    Mark

  • Thanks for the hint. For the case one don't want to recompile the RTS, is there a list of "dangerous" functions or pitfalls?

  • Well, any RTS function which contains a loop could cause problems.  It is better to rebuild the RTS library with an appropriate -mi value.  

    I'll add a bit to the RTS rebuild instructions, just to get you on your way that much faster.  Edit "Makefile".  Make a change similar to this one ...

    OPT_CMDLINE = -mi=1000

    Change the value 1000 to how many CPU cycles you are willing to be disabled from taking an interrupt.  Then invoke your make utility similar to this ...

    % gmake rts64plus.lib

    Change rts64plus.lib to the name of the RTS library you are using now.  The new library will be created in the temporary directory where you are doing all this work.

    Hope this helps ...

    -George