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.

RTOS: HOw to implement microseconds wait function



Tool/software: TI-RTOS

I am using AM572x evm and running TI RTOS in Cortex M4.

We need a blocking microsecond wait function and we want to achieve the microsecond wait for around 10 microseconds with accuracy + 1 or 2 microseconds.

we have referred the following links and used the example code.

https://e2e.ti.com/support/embedded/tirtos/f/355/t/413946

https://e2e.ti.com/support/embedded/tirtos/f/355/t/464329

But the API Task_disable() [to disable TASKS so we cant's get preempted by a higher TASK]

and Task_restore(task_restore_key)  [for restore TASK's to their Previous state]

itself take 60 microseconds.

Please let me know in which way i can achieve microsecond wait function.

  • Vinay,

    Have you tried using a dedicated timer peripheral?

    Based on the Technical Reference Manual, you should be able to configure a timer to use a 27 MHz clock. This will provide a resolution of 37 nanoseconds per clock cycle.

    If you configure a one-shot timer, you will be able to block using a semaphore which is unblocked in a IRQ from the timer. If you want this delay to block a context switch, you can use a while loop which reads the interrupt status register for your interrupt instead.

    Derrick


  • Hi,
    Yes we tried using timer. But it is also taking more time and not able to achieve 10 microsecond delay.
    The function call, timer creation, semaphore call and timer ISR call and unblock semaphore is more taking time and not able to achieve 10 micro second delay.
  • Vinay,

    I recommend you setup a dedicated timer peripheral at the beginning of your application, not when the delay is needed. That way, when you wish to delay, you can call something like Timer_Enable(baseAddress). Immediately after, you can use a while loop to read the timer interrupt status register.

    This will get you very close to a 10 microsecond delay, but the calling task will block execution all other execution. This blocking doesn't apply to other Swi and Hwi functions present in your application.

    Derrick
  • Vinay,

    Give the following a try. I've not tried this on an AM572x, so I don't know that latency to expect. But I hope it is low enough for you. If not, you might need to write an assembly function.

    xdc.useModule('xdc.runtime.Timestamp');
    xdc.useModule('xdc.runtime.Types');
    
    #include <xdc/runtime/Timestamp.h>
    #include <xdc/runtime/Types.h>
    #include <ti/sysbios/hal/Hwi.h>
    
    /*
     *  ======== User_delay ========
     */
    void User_delay(UInt32 usec)
    {
        UInt key;
        Bits32 start, now;
        Bits32 count;
        Types_FreqHz freq;
    
        key = Hwi_disable();
    
        /* latch the start timestamp */
        start = Timestamp_get32();
    
        /* compute delay in timestamp counts */
        Timestamp_getFreq(&freq);
        count = (freq.lo / 1000000) * usec;
    
        /*  Note that Modulo-32 math will guarantee correct behavior.
         *  Bits32 guarantees the type is exactly 32-bits wide. So, if
         *  start is latched just before rollover (e.g. FFFF_FFFE) and
         *  now is latched just after rollover (e.g. 0000_0004) the
         *  subtraction result will be the correct delta.
         *
         *      0000_0004   (now)
         *    - FFFF_FFFE   (start)
         *   ------------
         *              6   (delta = 6 ticks)
         */
    
        do {
            now = Timestamp_get32();
        } while ((now - start) < count);
    
        Hwi_restore(key);
    }

    Let us know how this goes.

    ~Ramsey