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.

TimestampProvider get64() jumps back

Other Parts Discussed in Thread: SYSBIOS, AM3359

Hi,

I'm facing a problem in using the ti.sysbios.family.arm.a8.TimestampProvider module on AM3359 chip. Sometimes, when using the get64() function, the upper 32-bits miss an increment and effectively all timestamps from that moment "jump" back (get a shift). Though I bumped into this issue in our software, I've succeeded in preparing a simple example reproducing the problem.

Reproduction scenario:

1. Connect to AM3359 target.
2. Reset CPU. Load program.
3. Put a breakpoint where indicated.
4. Run and see that it stops there after some time (typically 10-30min on my setup, but can take a few hours sometimes).

I looked into the Timestamp module code, but I fail to find the reason for this behaviour. Will appreciate your help.

Example: 4670.TimestampJump.rar

Best regards,
Vasili

  • Which version of SYS/BIOS are you using?

    Older versions of SYS/BIOS require you to call Timestamp_get32/64 often enough that the rollover is detected between successive calls. A convenient mechanism for this is to add a periodic Clock function that goes off more often than the 32 bit rollover period.

    Newer versions of SYS/BIOS automatically install a Clock function for this purpose if the Timestamp module is used.

    Alan

  • Hi Alan,

    My tools are:
    xdctools_3_30_04_52
    bios_6_40_03_39

    I'm aware of the requirement for successive calls to be frequent enough. But find it hard to believe that can be the cause for the problem I demonstrated.

    If you look into the example code I posted, it has nothing except a single task which calls the get64() function infinitely in a loop.

    On 720Mhz CPU, the hardware CCNT overflows once every: 2^32 / 720MHz = ~6 seconds.

    Can you suggest any reason for this task to be delayed for THAT long? I don't see one.

    Do I miss something here?

    Best,
    Vasili

  • Sorry for the delayed response.

    The code looks good.

    I'll have to check into this more closely ASAP.

    I noticed that you have the timer frequency check disabled. Why is that?

    Alan

  • I was able to successfully import and build your CCS project.

    I've got it running on my local beaglebone now and am waiting for it to hit the breakpoint.

    Meanwhile I'm studying the code to see if I can find the hole in the logic...

    Alan

  • Hello Alan,

    1. I hope you succeeded in reproducing the issue.
    2. The frequency check is disabled because the Timer module performs this check before main(). In case the code is loaded through CCS, there is no bootloader configuring the timer module clocks and this check fails. In any case, this shall not be related to the issue I describe here.
    3. I looked at the code prior contacting you. I failed finding any hole in the logic... It looks as if the CPU just don't set the overflow flag. But maybe I miss something.

    Best,
    Vasili

  • Vasili,

    I did recreate the problem, however I was out of the office last week so I wasn't able to analyze it.

    I'll take a closer look this week.

    Alan

  • Hi Alan,

    I'm glad you succeeded in recreating the behaviour. Any further news?

    This is quite an issue for us and we would appreciate your help on solving this. Is that something that we are doing wrong?

    Best Regards,
    Vasili

  • Vasili,

    I'm sorry to take so long on this. I filed this bug to track the problem: "SDOCM00114079 A8 TimestampProvider 64 bit timestamps jump backwards sometimes". Sadly, its taking a long time for the bug to become visible on the public bug tracking site.

    I think the problem is in the bold code below:

    Void TimestampProvider_get64(Types_Timestamp64 *result)
    {
        UInt hwiKey;

        result->lo = (Bits32)TimestampProvider_get32();

        hwiKey = Hwi_disable();

        if (TimestampProvider_getOverflowCCNT() != 0) {
            result->lo = (Bits32)TimestampProvider_get32();
            ++TimestampProvider_module->upper32Bits;
        }

        result->hi = TimestampProvider_module->upper32Bits;

        Hwi_restore(hwiKey);
    }

    If an interrupt comes in between those two statements, the hi value will not match with lo value just fetched. I've modified the code to disable interrupts before reading the lo value as show below and the test seems to run indefinitely now.


    Void TimestampProvider_get64(Types_Timestamp64 *result)
    {
        UInt hwiKey;

        hwiKey = Hwi_disable();

        result->lo = (Bits32)TimestampProvider_get32();

        if (TimestampProvider_getOverflowCCNT() != 0) {
            result->lo = (Bits32)TimestampProvider_get32();
            ++TimestampProvider_module->upper32Bits;
        }

        result->hi = TimestampProvider_module->upper32Bits;

        Hwi_restore(hwiKey);
    }


    In order for you to try this yourself, make the change to your BIOS installation in this file:

         packages/ti/sysbios/family/arm/a8/TimestampProvider.c

    Add this to your .cfg file:

        BIOS.libType = BIOS.LibType_Custom;


    Then rebuild and run your testcase and your application.

    Please let me know if this resolves the problem for you.

    Alan

  • The proposed fix, while necessary, does not resolve the issue. It turns out that we are victims of an A8 core bug described in this errata:

    To avoid condition #3, I've modified the getOverflowCCNT() function in ti/sysbios/family/arm/a8/TimestampProvider_asm_gnu.sv7a as follows to only write to the status register when there is actually an overflow condition:

    ti_sysbios_family_arm_a8_TimestampProvider_getOverflowCCNT__I:
        mrc     p15, #0, r0, c9, c12, #3
        ands    r0, r0, #0x80000000
        beq     skip
        mcr     p15, #0, r0, c9, c12, #3
    skip:
        bx      lr

    I'm running your test case now with the change above. So far so good.

    Alan

  • Hi,

    Thank you very much! We'll test it too.

    Best,
    Vasili

  • As the errata mentions, a write to ANY CP14/CP15 register when the count rolls over can suppress the rollover status bit from being set. Consequently, the solution I provided removes the getOverflowCCNT function from the list of culprits but it doesn't eliminate ALL the places in the code that might be writing to the CP14/15 registers at just the right moment. A better solution is for the rollover to be detected without checking the rollover bit. I modified the design accordingly and the new code is included in the 6.40.04 release due out today some time. Look for it in the usual place. It will also be included in the upcoming 6.41.01 release.


    Alan