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.

Reading 64-Bit Timer Register in multithreaded application

Hi everybody,

i have a multithreaded application on a TI DM6437. Timers 1+2 are configured as
64Bit timer. Each thread should be able to read the current timer value which
means to read TIM12 and TIM34 as described in spru989.pdf. What would be the
correct way to do this?
1. Using IRQ-Disable/Enable

#define TIM12 *(volatile Uint32*)(0x01C21410)
#define TIM34 *(volatile Uint32*)(0x01C21414)
Uint64 getTimerVal()
{
unsigned int ret[2];

IRQ_DISABLE();
ret[0] = TIM12;
ret[1] = TIM34;
IRQ_ENABLE();
return *(Uint64*)ret;
}

2. Without IRQ-Disable/Enabel

#define TIM1234 *(volatile Uint64*)(0x01C21410)
Uint64 getTimerVal()
{
return TIM1234;
}

The first possibility seems to be save but the 2nd one is shorter and would not
need IRQ-Disable/Enable.
As I've seen in the disassembly, for reading the 64-Bit Register the LDDW
instruction is used, which would be an atomic operation. Spru989 says, that when
reading TIM12, TIM34 is copied to a shadow register. When reading TIM34 (a few
ns after TIM12), it is read from shadow register and I get the correct value.

What will the LDDW instruction do? Does it read first TIM12 and then TIM34 or
may it be the wrong order.

Thanks for your help,
Tobias
  • Hi Tobias,

    The way you have coded in case 2 would not work. It should be coded like you have in case 1 without IRQ_DISABLE () and IRQ_ENABLE().

    The LDDW uses a 64-bit bus to do the load so it would not work with the 2 32-bit timer registers.

    Thanks.

    Tai

     

     

  • Hi Tai,

    1. you say that case 1 should work without IRQ_DISABLE () and IRQ_ENABLE(). Why? What if a task switch occures between reading TM12 and TIM34 and the second thread also reads the timer register? I think when returning back to the first thread, the read of TIM34 will read either a wrong shadow register or a timer value which is 'later' than TIM12.


    2. the second case does read the two 32-bit timer registers, I tried it out. My problem is not, that I read invalid values. But I am not sure, if LDDW reads TIM12 and TIM34 in the correct order as described in spru989, chapter 2.4.1.2.

    Thanks,

    Tobias

  • Hi Tobias,

    You are right. In case 1, if there is no IRQ disabled and the second thread reads the timer then when you come back to the first thread and read the TIM34, it will have a wrong value. My assumption was the other threads do not read the timer registers.

    Regarding to the second part of your question, after further checking, I confirm that the LDDW does read the timer registers correctly. For the peri registers, they are 32-bit. When the LDDW is excuted, the bus controller will issue two 32-bit loads back to back (no interruption), one from the 0x01C21410 and then another from the 0x01C21414 since the DM6437 has only one CPU.

    Thanks,

    Tai