FreeRTOS software timer stops without turning it of

rudy93 wrote on Friday, May 04, 2018:

Hey all,

I am running FreeRTOS on a Cortex M4 from NXP the MKE14F512. I made one task that runs always and does some controlling of the system. Than I have two timers, one every 200 ms and one every 5 seconds that reads out some sensor values. This goes very well for a few minutes but at random times the timers will not execute anymore. I have set the timer priotiry already higher than the main task but this doesn’t help, after a few minutes it will stop. I run the code inside the timer interrupt, is this wrong? Anyone else experienced something like this?

Thanks!
Regards,
Rudy

heinbali01 wrote on Friday, May 04, 2018:

Hi Rudy, maybe you want to show some code?

I run the code inside the timer interrupt

Mind you that (most) normal FreeRTOS API’s may not be called from within an ISR. You can only use the xxxFromISR() versions

rudy93 wrote on Friday, May 04, 2018:

Hi Hein,

Thanks for your fast response, underneath some of the code:

//Code inside the timer interrupt:
static void vSensorTimerCallback(TimerHandle_t Timer)
{
ReadTemperature();
ADCMeasurement();
switchled();
}

//Task schedular:

TimerHandle_t xSensorTimer = NULL;
TimerHandle_t xFlowTimer = NULL;
TimerHandle_t xDebug_PrintTimer = NULL;

/* Create the queue used by the queue send and queue receive tasks. */
xQueue = xQueueCreate(/* The number of items the queue can hold. */
                      mainQUEUE_LENGTH,
                      /* The size of each item the queue holds. */
                      sizeof(uint32_t));

xDebug_PrintTimer = xTimerCreate(/* A text name, purely to help
                                       debugging. */
                                         "Debug_Print_Timer",
                                         /* The timer period, in this case
                                         1000ms (1s). */
                                         DEBUG_PRINT_TIMER_PERIOD_MS,
                                         /* This is a periodic timer, so
                                         xAutoReload is set to pdTRUE. */
                                         pdTRUE,
                                         /* The ID is not used, so can be set
                                         to anything. */
                                         (void *)2,
                                         /* The callback function */
                                         vDebug_PrintTimerCallback);

xSensorTimer = xTimerCreate(/* A text name, purely to help
                                   debugging. */
                                     "SensorTimer",
                                     /* The timer period, in this case
                                     1000ms (1s). */
                                     SENSOR_TIMER_PERIOD_MS,
                                     /* This is a periodic timer, so
                                     xAutoReload is set to pdTRUE. */
                                     pdTRUE,
                                     /* The ID is not used, so can be set
                                     to anything. */
                                     (void *)1,
                                     /* The callback function */
                                     vSensorTimerCallback);
if( xSensorTimer != NULL )
	{
		xTimerStart( xSensorTimer, mainDONT_BLOCK );
	}


xFlowTimer = xTimerCreate(/* A text name, purely to help
                                   debugging. */
                                     "FlowTimer",
                                     /* The timer period, in this case
                                     5000ms (5s). */
                                     FLOW_TIMER_PERIOD_MS,
                                     /* This is a periodic timer, so
                                     xAutoReload is set to pdTRUE. */
                                     pdTRUE,
                                     /* The ID is not used, so can be set
                                     to anything. */
                                     (void *)0,
                                     /* The callback function */
                                     vFlowTimerCallback);

xTaskCreate(/* The function that implements the task. */
            prvQueueModuleTask,
            /* Text name for the task, just to help debugging. */
            "Module",
            /* The size (in words) of the stack that should be created
            for the task. */
            configMINIMAL_STACK_SIZE + 166,
            /* A parameter that can be passed into the task.  Not used
            in this simple demo. */
            NULL,
            /* The priority to assign to the task.  tskIDLE_PRIORITY
            (which is 0) is the lowest priority.  configMAX_PRIORITIES - 1
            is the highest priority. */
            mainQUEUE_MODULE_TASK_PRIORITY,
            /* Used to obtain a handle to the created task.  Not used in
            this simple demo, so set to NULL. */
            NULL);

/* Start the created timers.  A block time of zero is used as the timer
command queue cannot possibly be full here (this is the first timer to
be created, and it is not yet running). */
//xTimerStart(xFlowTimer, 0);
xTimerStart(xSensorTimer, 0);
//xTimerStart(xDebug_PrintTimer,0);
/* Start the tasks and timers running. */
vTaskStartScheduler();

/* The program should never enter this while loop */
while(1)
{
	;
}

}

heinbali01 wrote on Friday, May 04, 2018:

I run the code inside the timer interrupt, is this wrong?

Ah sorry, I understood you wrong: when a timer function is being called, the CPU is not in an ISR context.

Now 'm curious about what prvQueueModuleTask() is doing? Does it sleep ( block ) from time to time?
Otherwise I wouldn’t see a reason why the timer stops calling you handlers.

rudy93 wrote on Monday, May 07, 2018:

It runs alot of code, no sleep stuf that I know of. So a timer has always a higher priority as a task? What happens when a second timer calls the CPU? Will it first finish the earlier timer task?

heinbali01 wrote on Monday, May 07, 2018:

You have called xTimerCreateTimerTask(), which will start-up the timer task. Your timer functions will be called from this task sequentially. The call-back takes place in prvProcessReceivedCommands(), by calling the user function pxCallbackFunction.

The timer task is sleeping most of the time. It runs at a configurable task priority of configTIMER_TASK_PRIORITY.

It runs alot of code, no sleep stuf that I know of.

“no sleep stuf” ? It should have sleeps!

Roughly spoken in a multitasking system, a task-switch will only take place if:

- Another task has a higher priority
- Another task has the same priority and time-slicing is enabled

Pre-emption is also important: if enabled a task can loose the CPU at any moment, also before it yields.

Sleeping means that a task doesn’t eat up CPU time. Sleeping is very important, except for tasks that have the lowest priority.

Now suppose that you have a task that spins without sleeping, and suppose that configTIMER_TASK_PRIORITY is low, then the timer-task wil starve, it won’t get CPU time anymore.

So a timer has always a higher priority as a task?

Do you mean the timer task prvTimerTask in timers.c ?

That is your design decision, you may or you may not.

What happens when a second timer calls the CPU?

As you have seen, the timer task will call your handlers in a sequential way. I would advice to keep the code short and not have it block.

Will it first finish the earlier timer task?

It is not really a task but a application hook. And yes, hook 2 will only be called once hook 1 has returned.