Tickless with just one task broken?

I think I have found a bug/misfeature with tickless support. I have this example code (configured with a tick rate of 1024 Hz):
void task1(void *_)
{
    portTickType clock = xTaskGetTickCount();
    for (; ;)
    {
        printf("---onen");
        vTaskDelayUntil(&clock, 2000);
    }
}
void task2(void *_)
{
    portTickType clock = xTaskGetTickCount();
    vTaskDelayUntil(&clock, 1000);
    for (; ;)
    {
        printf("two---n");
        vTaskDelayUntil(&clock, 2000);
    }
}
xTaskHandle Task1, Task2;
int main(void)
{
    configureProcessor();
    initializeUART_STDOUT();
    xTaskCreate(
        task1,
        NULL,
        128,
        NULL,
        tskIDLE_PRIORITY + 1,
        &Task1);
    xTaskCreate(
        task2,
        NULL,
        128,
        NULL,
        tskIDLE_PRIORITY + 1,
        &Task2);
    vTaskStartScheduler();
    return 0;
}
This launches two tasks, each outputing every 2000 ticks. The second task is offset by 1000 ticks originally, so they’re half out of phase with each other, generating some sort of output between the two effectively every 1000 ticks. I placed a printf() in my sleep() function so I could see the amount of time being fed to it by FreeRTOS. For this case, it dutifully feeds it 1000 every time. And I can watch it emit the alternating ‘–one’ and ‘two–‘ reliably. However, if I #if 0 out the launch of the second task, things get unregular. Now it should just output every 2000 ticks. The first sleep time fed to the sleep function will be 2000. But the next sleep time will be 63535 (which is conveniently 0xFFFF – 2000). After that time is expired and tick is incremented, it will suddenly unwind a series of outputs all at once (basically all of the outputs that should have happened while asleep for the 63535 we were asleep). I’ll then get the overflow remainder amount with one regular output, and then the whole long delay (til the next overflow basically) again. That this particular case appears to be broken is particularly problematic, because it was my intent to use a simple example like this, driving a pin with a scope, to tune my sleep function for any skew. My theory, based on Richard Barry’s wonderful answers to my previous questions and perusing the code and how the blocked lists are managed, is that basically after the original sleep/tick, there is no blocked processes yet (because it hasn’t redelayed?) so the xNextWakeupTime has been set to the max overflow value. When there’s two processes, there’s always one in the queue to make sure we have a real delay computed, rather than the overflow point.

Tickless with just one task broken?

I placed a printf() in my sleep() function so I could see the amount of time being fed to it by FreeRTOS. For this case, it dutifully feeds it 1000 every time. And I can watch it emit the alternating ‘–one’ and ‘two–‘ reliably.
Remember that the sleep function is called by the idle task.  Printf() can (depending on how it is implemented) use masses of stack space.  The idle task stack size is configured by the configMINIMAL_STACK_SIZE FreeRTOSConfig.h setting – it is possible that you may need to increase the configMINIMAL_STACK_SIZE value . I will try and replicate this here by setting my system to use 16 bit ticks.  My experimentation with the SAM4L was using a single task though. Am I right in thinking you are running this on an AVR?  Will it run in the AVRStudio simulator?  If so I may ask for a copy of your code if I can’t find anything. Regards.

Tickless with just one task broken?

Ok I have replicated your system as closely as I can.  I have: 1) Taken my SAM4L project as a starting point.
2) Replaced my task with your task (cut from your post above).
3) Set configUSE_16_BIT_TICKS to 1
4) Set configTICK_RATE_HZ to 1000
5) Added “printf(”%drn”, xExpectedIdleTime);” to the start of the sleep function I found the task printed out once, and the expected idle time printed out once.  Then the stack overflow hook got hit (as per my previous post, the idle task stack is by default only large enough to do nothing).  So I: 6) Increased configMINIMAL_STACK_SIZE in FreeRTOSConfig.h Now I find everything is running as expected.  The print out (via a UART through the J-Link) looks as below.  Note I have chosen this section of the print out because it shows an overflow being managed:
1998
---one
1998
---one
1998
---one
1998
---one
1998
---one
1677
320
---one
1998
---one
1998
---one
1998
---one
1998
---one
1998
---one
1998
---one
1998
---one
1998
---one
1998
---one
Regards.

Tickless with just one task broken?

The AVR printf is pretty lightweight (relatively speaking), but I did increase the MINIMAL_STACK_SIZE to 384 just to be sure. It doesn’t change the behavior for me.
Am I right in thinking you are running this on an AVR?  Will it run in the AVRStudio simulator?  If so I may ask for a copy of your code if I can’t find anything.
The target is the AVR xmega256a3 found inside of an LSResearch SiFLEX02 radio module. We’ve been using avr-gcc provided for OSX by the CrossPack folks. So I don’t really know how well it compiles with AVRStudio or if it runs in the simulator. But we’re fully prepared (obligated even) to publish our port. Just been trying to get these bugs fixed. I was going to despair that we seem to be getting different results. And then… I had a spark of inspiration…. What do you have USE_PREEMPTION set to? Mine was set to 0. I’m betting yours is 1, because when I changed mine to 1, then things started working as expected. Nice regular two second pauses! If that’s not it, perhaps the port code affected by that setting is to blame? Our tick ISR looks like this:
#if configUSE_PREEMPTION == 1
    /*
     * Tick ISR for preemptive scheduler.  We can use a naked attribute as
     * the context is saved at the start of vPortYieldFromTick().  The tick
     * count is incremented after the context is saved.
     */
    ISR(RTC_OVF_vect)
    {
        vPortYieldFromTick();
    }
#else
    /*
     * Tick ISR for the cooperative scheduler.  All this does is increment the
     * tick count.  We don't need to switch context, this can only be done by
     * manual calls to taskYIELD();
     */
    ISR(RTC_OVF_vect)
    {
        vTaskIncrementTick();
    }
#endif
and
/*
 * Context switch function used by the tick.  This must be identical to 
 * vPortYield() from the call to vTaskSwitchContext() onwards.  The only
 * difference from vPortYield() is the tick count is incremented as the
 * call comes from the tick ISR.
 */
void vPortYieldFromTick( void ) __attribute__ ( ( naked ) );
void vPortYieldFromTick( void )
{
    portSAVE_CONTEXT();
    vTaskIncrementTick();
    vTaskSwitchContext();
    portRESTORE_CONTEXT();
    asm volatile ( "ret" );
}

Tickless with just one task broken?

Yes, I have preemption on. What do you have configIDLE_SHOULD_YIELD set to? I think, without actually trying it, if you have preemption off then you should get something like this: - Enter the sleep function.
- You next interrupt occurs in 2 seconds, the interrupt will call the increment tick function, but its actions will be held pending because the sleep function called with the scheduler locked.
- After the interrupt has executed your sleep function will also exit.
- When you leave the sleep function the scheduler is unlocked, and the tick will get incremented.  Incrementing the tick will move the task that runs every two seconds out of the Blocked state and into the ready state – but the task won’t run because preemption is off.
- The Idle task (from which the sleep function was called) will loop back around and if configIDLE_SHOULD_YIELD is set to 1 call taskYIELD because there is a task of higher priority than itself in the ready state.  The yield should then make your unblocked task run. Regards.

Tickless with just one task broken?

This is the configuration that creates the stall:
#define configUSE_PREEMPTION        0
#define configUSE_IDLE_HOOK         0
#define configUSE_TICK_HOOK         0
#define configCPU_CLOCK_HZ          ( ( unsigned long ) 33554432 )
#define configTICK_RATE_HZ          ( ( portTickType ) 1024 )
#define configMAX_PRIORITIES        ( ( unsigned portBASE_TYPE ) 10 )
#define configMINIMAL_STACK_SIZE    ( ( unsigned short ) 250 )
#define configTOTAL_HEAP_SIZE       ( (size_t ) ( 2048 ) )
#define configMAX_TASK_NAME_LEN     ( 1 ) 
#define configUSE_TRACE_FACILITY    0
#define configUSE_16_BIT_TICKS      1
#define configIDLE_SHOULD_YIELD     1
#define configQUEUE_REGISTRY_SIZE   0
#define configUSE_MUTEXES           1
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES       0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet        0
#define INCLUDE_uxTaskPriorityGet       0
#define INCLUDE_vTaskDelete             0
#define INCLUDE_vTaskCleanUpResources   0
#define INCLUDE_vTaskSuspend            1
#define INCLUDE_vTaskDelayUntil         1
#define INCLUDE_vTaskDelay              1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define portSUPPRESS_TICKS_AND_SLEEP( xIdleTime ) sleepXmega( xIdleTime )

Tickless with just one task broken?

Well I turned preemption off but it’s still running fine. If you are able to get your code running in the simulator then let me know and I can try it out to see if I can find the cause.  I think you can build the code externally, then load it into the simulator (provided it is build using the debug info the simulator expects), provided you tell the simulator where to find the source files. Regards.