problem with crDELAY (delay start reference?)

dcraw101 wrote on Friday, December 14, 2007:

This may be how crDELAY is intended to operate, but it looks like this macro is not delaying a consistent amount of time.  The following code is in the body of my coroutine:

    static uint16_t tick1, tick2, elapsed;
    tick1 = xTaskGetTickCount();
    _delay_ms(15);
    _delay_ms(15);
    _delay_ms(15);
    _delay_ms(15);
    _delay_ms(15);
    _delay_ms(15);
    crDELAY(xHandle, 9); //portTICK_RATE_MS is 100
    tick2 = xTaskGetTickCount();
    elapsed = tick2 - tick1;

If I comment out crDELAY and only have the busy waits then the elapsed ticks are 9.  If I comment out the busy waits and just have the crDELAY then the elapsed ticks are also 9.  But if I have both the busy waits followed by the crDELAY then the elpased ticks is still 9 (I would have expected 18).  It appears that the timer for the crDELAY starts as soon as the coroutine becomes active, whereas I would expect the timer to not start until crDELAY is called.

davedoors wrote on Monday, December 17, 2007:

I dont know much about coroutines but a quick look at the code shows that his would be the expected behavior which does not look too good.  The coroutine tick count is only incremented when the coroutine schedule function is called.  This behavior could be changed easily enough.

davedoors wrote on Monday, December 17, 2007:

I have added the change request.

"The coroutine tick count is only incremented during the coroutine schedule function meaning it remains unchanged during parts of the coroutine application code.  It would be better then for the coroutine delay function to use the RTOS tick as its base time when calculating a wake time rather than the coroutine time time."

rtel wrote on Tuesday, December 18, 2007:

In croutine.c, there is a function vCoRoutineAddToDelayedList().  At the top of this you will find the line:

xTimeToWake = xCoRoutineTickCount + xTicksToDelay;

If you change this to:

xTimeToWake = xTaskGetTickCount() + xTicksToDelay;

Then the behaviour should change so the delay is relative to the current real time, rather than the co-routine time.

Caveat:  I have not actually tried this myself yet, nor analysed in detail the effect of changing this.  I think it should be fine, the place to take special care is the case where an overflow in times occurs although this should be handled automatically.

Regards.