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.

AM2634-Q1: Alternative of ClockP_usleep

Part Number: AM2634-Q1

Hi BU, 

When using ClockP_usleep in interrupt service routine, the program may stall since the RTI0 interrupt is lowest priority and gClockCtrl.ticks will not increase. Do we have alternative for ClockP_usleep ? 

BR, 

Will 

  • Hi Will,

    The other function that I see in the SDK is ClockP_sleep. However, I would assume that it has the same priority level and run into the same issue. You can give that a try while I find an SDK expert to comment on this.

    Best,

    Daniel

  • Hi Will,

    Have you tried increasing the priority of RTI interrupt? 

    Regards,

    Prasad

  • ClockP_usleep is not meant for use in ISR. In RTOS systems they are supposed to be called from task context and in nortos (baremetal) system they are meant to be called only from background main processing loop.  I want to understand the usage scenario for use of ClockP_usleep in ISR. Can you explain why the need arises. ISR cannot block. 

  • Hi Daniel, 

    Thanks for your comments, but ClockP_sleep is also based on ClockP_sleepTicks (RTI0). 

    BR, 

    Will 

  • Hi Prasad, 

    That means I need to modify the SDK source codes, do we recommend to do so? 

    BR, 

    Will 

  • Hi Badri, 

    My customer wants to wait a couple of us in ISR to meet the time sequencing requirement in their application. 

    BR, 

    Will 

  • If you want accurate timing relying on sleep is wrong. Create a RTI timer instance in oneshot mode. RTI oneshot mode will expire and trigger an interrupt. You cannot wait in an ISR for another ISR to trigger. If you want to wait for 2us in ISR I feel you should reorganize the ISR into two parts

    1. Part 1 : Complete Pre 2us action . At end arm the 2us one shot RTI interrupt

    2. Part 2: RTI one shot mode callback on 2us expiry. 

    If you think this is too much complexity for such a short duration and you are okay with ISR busy looping (not recommended) you can use CycleProfileP which ticks at CPU frequency to loop until 2us elapses.

    Below is sample code

    #define __NOP  asm (" NOP ")
    
    #define NOP5   do { __NOP; __NOP; __NOP; __NOP; __NOP; } while (0)
    
    #define NOP10  NOP5; \
                   NOP5
    
    #define NOP50  NOP10; \
                   NOP10; \
                   NOP10; \
                   NOP10; \
                   NOP10
    
    /* Second to nanosecs conversion factor */
    #define ENET_OSAL_DFLT_SEC2NANOSEC                (1000000000ULL)
    static uint32_t EnetOsalDflt_convertNanosec2Ticks(uint32_t delayInNsecs)
    {
        return (((uint64_t)delayInNsecs*gEnetOsalDflt_selfFreqHz) / ENET_OSAL_DFLT_SEC2NANOSEC);
    }
    
    void EnetOsalDflt_delay(uint64_t delayInNsecs)
    {
       uint64_t delayTicks = EnetOsalDflt_convertNanosec2Ticks(delayInNsecs);
       uint64_t currentTick = (uint64_t)CycleprofilerP_getTimeStamp();
       const uint64_t endTick = currentTick + (uint64_t)delayTicks;
    
       while (currentTick < endTick)
       {
           NOP50;
           currentTick = (uint64_t)CycleprofilerP_getTimeStamp();
           if ((currentTick < endTick) &&
               ((endTick - currentTick) > delayTicks))
           {
               currentTick += ENET_OSAL_DFLT_TIMESTAMP_MAX + 1ULL;
           }
       }
    }