Software Timer FreeRTOS

mangroove wrote on Friday, April 22, 2011:

How to implement software timer using freertos?

edwards3 wrote on Friday, April 22, 2011:

Read the timer documentation page, look at the timer API documentation  then copy the examples in the version seven code. Some effort is required, but very little.

mangroove wrote on Monday, April 25, 2011:

I have added the FreeRTOS/Source/timers.c source file to my project andefine the following constants in the applications FreeRTOSConfig.h header file.

/* Set variable for the software timer */

#define configUSE_TIMERS                        1
#define configTIMER_QUEUE_LENGTH                1
#define configTIMER_QUEUE_LENGTH                255
#define configTIMER_TASK_STACK_DEPTH            255

// Hier is a part of my main function
 /* An array to hold handles to the created timers. */
 xTimerHandle xTimers[ NUM_TIMERS ];
 
 /* An array to hold a count of the number of times each timer expires. */
 long lExpireCounters[ NUM_TIMERS ] = { 0 };
 
 /* Define a callback function that will be used by multiple timer instances.  
 The callback function does nothing but count the number of times the 
 associated timer expires, and stop the timer once the timer has expired
 10 times. */
 void vTimerCallback( xTIMER *pxTimer )
 {
 long lArrayIndex;
 const long xMaxExpiryCountBeforeStopping = 10;
 
     /* Optionally do something if the pxTimer parameter is NULL. */
     configASSERT( pxTimer );
     
     /* Which timer expired? */
     lArrayIndex = ( long ) pvTimerGetTimerID( pxTimer );
     
     /* Increment the number of times that pxTimer has expired. */
     lExpireCounters[ lArrayIndex ] += 1;
     /* If the timer has expired 10 times then stop it from running. */
     if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping )
     {
         /* Do not use a block time if calling a timer API function from a
         timer callback function, as doing so could cause a deadlock! */
         xTimerStop( pxTimer, 0 );
     }
 }
 
 void main( void )
 {
 long x;
 
     /* Create then start some timers.  Starting the timers before the scheduler
     has been started means the timers will start running immediately that
     the scheduler starts. */
     for( x = 0; x < NUM_TIMERS; x++ )
     {
         xTimers[ x ] = xTimerCreate(  "Timer",        /* Just a text name, not used by the kernel. */
                                       ( 100 * x ),    /* The timer period in ticks. */
                                       pdTRUE,         /* The timers will auto-reload themselves when they expire. */
                                       ( void * ) x,   /* Assign each timer a unique id equal to its array index. */
                                       vTimerCallback  /* Each timer calls the same callback when it expires. */
                                     );
                                     
         if( xTimers[ x ] == NULL )
         {
             /* The timer was not created. */
         }
         else
         {
             /* Start the timer.  No block time is specified, and even if one was
             it would be ignored because the scheduler has not yet been
             started. */
             if( xTimerStart( xTimers[ x ], 0 ) != pdPASS )
             {
                 /* The timer could not be set into the Active state. */
             }
         }
     }
        
     /* ...
     Create tasks here.
     ... */
     
     /* Starting the scheduler will start the timers running as they have already
     been set into the active state. */
     xTaskStartScheduler();
But is not work. What about the timers.h?  I am sorry for my bad englisch
Regards
     
     /* Should not reach here. */
     for( ;; );
 }

rtel wrote on Tuesday, April 26, 2011:

What is the timer queue length?  The code you have posted has two definitions for this, so I’m surprised it compiles without giving you a warning.

The two definitions you have are 1 and 255.  If it is using the value 1, then I would not expect the above code to work.  That is because the timer command queue is not processed until after the scheduler has been started.  With a queue length of 1, the first call to xTimerStart() will fill the timer command queue to it’s capacity, and all the other calls to xTimerStart() will fail.

Regards.

mangroove wrote on Tuesday, April 26, 2011:

Tanks you for your replay.
I am a student from germany and my englisch is so bad . I am sorry for that.
I got Waring message, when i compile my code. Please tell me how  to set the software timer.
I want to generate a software timer every 2 s und i use the EFM32890F128 from energy micro.
I read the documentation pages but i have some problem to set it s correctly. For example, the header " timers.h" is completls commented.
I bought your book “Using the freeRTOS Real Time Kernel” over there is nothing in there about software timer.
thank you for your help .
Regards

iamsaranvs wrote on Sunday, July 21, 2013:

hello edwards,
      can u pls post the link of timer documentation page

woops_ wrote on Sunday, July 21, 2013:

http://www.freertos.org/RTOS-software-timer.html

iamsaranvs wrote on Monday, July 22, 2013:

thank u   woops_……

iamsaranvs wrote on Monday, July 22, 2013:

Hiiii, This is my sample code…for traffic light (RED,Green,YELLOW),  i want to add timer to it, without addding timer the code runs well but when i add the timer it shows the following errors, 

linking…
.\Output\Example008.axf: Error: L6218E: Undefined symbol configASSERT (referred from main1.o).
.\Output\Example008.axf: Error: L6218E: Undefined symbol listGET_ITEM_VALUE_OF_HEAD_ENTRY (referred from main1.o).
.\Output\Example008.axf: Error: L6218E: Undefined symbol traceTIMER_COMMAND_RECEIVED (referred from main1.o).
.\Output\Example008.axf: Error: L6218E: Undefined symbol traceTIMER_COMMAND_SEND (referred from main1.o).
.\Output\Example008.axf: Error: L6218E: Undefined symbol traceTIMER_CREATE (referred from main1.o).
.\Output\Example008.axf: Error: L6218E: Undefined symbol traceTIMER_CREATE_FAILED (referred from main1.o).
.\Output\Example008.axf: Error: L6218E: Undefined symbol traceTIMER_EXPIRED (referred from main1.o).
.\Output\Example008.axf: Error: L6218E: Undefined symbol uxListRemove (referred from main1.o).
.\Output\Example008.axf: Error: L6218E: Undefined symbol vQueueWaitForMessageRestricted (referred from main1.o).
.\Output\Example008.axf: Error: L6218E: Undefined symbol xTaskGetSchedulerState (referred from main1.o).
Target not created

also i am new to RTOS, kindly please help me,

below i pasted my code and also i have configured timer in freeRTOSconfig.h

#define configUSE_TIMERS                        1
#define configTIMER_TASK_PRIORITY                1
#define configTIMER_QUEUE_LENGTH                255
#define configTIMER_TASK_STACK_DEPTH            255

/* FreeRTOS includes. */

#include “FreeRTOS.h”

#include “task.h”

#include “timers.c”

#include “basic_io.h”

#define NUM_TIMERS 3
/* The three task functions. */
void vTask1( void *pvParameters );
void vTask2( void *pvParameters );
void vTask3( void *pvParameters );

/* Used to hold the handle of Task1,2,3. */
xTaskHandle xTask1Handle;
xTaskHandle xTask2Handle;
xTaskHandle xTask3Handle;

// /* An array to hold handles to the created timers. */
  xTimerHandle xTimers;

//  /* An array to hold a count of the number of times each timer expires. */
  long lExpireCounters = { 0 };
void vTimerCallback( xTimerHandle pxTimer )
  {
   long lArrayIndex;
   const long xMaxExpiryCountBeforeStopping = 10;

//      /* Optionally do something if the pxTimer parameter is NULL. */
configASSERT( pxTimer );

//      /* Which timer expired? */
      lArrayIndex = ( long ) pvTimerGetTimerID( pxTimer );

//      /* Increment the number of times that pxTimer has expired. */
      lExpireCounters += 1;

//      /* If the timer has expired 10 times then stop it from running. */
      if( lExpireCounters == xMaxExpiryCountBeforeStopping )
      {
//          /* Do not use a block time if calling a timer API function from a
//          timer callback function, as doing so could cause a deadlock! */
         xTimerStop( pxTimer, 0 );
      }
  }

int main( void )
{
long x;

for( x = 0; x < NUM_TIMERS; x++ )
      {
  xTimers = xTimerCreate(  “Timer”, ( 100 * x ),pdTRUE, ( void * ) x, NULL  );
                  
                    
            if( xTimers == NULL )
          {
              vPrintString(“Timer not created”);
          }
          else
          {
//              /* Start the timer.  No block time is specified, and even if one was
//              it would be ignored because the RTOS scheduler has not yet been
//              started. */
              if( xTimerStart( xTimers, 0 ) != pdPASS )
              {
//                  /* The timer could not be set into the Active state. */
              }
          }
      }
// //
/* Create the first task at priority 2.  This time the task parameter is
not used and is set to NULL.  The task handle is also not used so likewise
is also set to NULL. */
xTaskCreate( vTask1, “Red”,240, NULL, 1, &xTask1Handle );
         /* The task is created at priority 2 ^. */

/* Create the second task at priority 1 - which is lower than the priority
given to Task1.  Again the task parameter is not used so is set to NULL -
BUT this time we want to obtain a handle to the task so pass in the address
of the xTask2Handle variable. */
xTaskCreate( vTask2, “Green”, 240, NULL, 0, &xTask2Handle );
        /* The task handle is the last parameter ^^^^^^^^^^^^^ */

/* Start the scheduler so our tasks start executing. */
xTaskCreate( vTask3, “yellow”,240, NULL, 0, &xTask3Handle );
        /* The task handle is the last parameter ^^^^^^^^^^^^^ */

/* Start the scheduler so our tasks start executing. */
vTaskStartScheduler();

for( ;; );
}

//  /* Define a callback function that will be used by multiple timer instances.
//  The callback function does nothing but count the number of times the
//  associated timer expires, and stop the timer once the timer has expired
//  10 times. */
 

/*---------------------------------------*/

void vTask1( void *pvParameters )
{
unsigned portBASE_TYPE uxPriority;

  uxPriority = uxTaskPriorityGet( NULL );

for(;:wink:
   {

/* Print out the name of this task. */
  vPrintString( “RED” );

vTaskPrioritySet( xTask2Handle, ( uxPriority + 1 ) );

/* Task1 will only run when it has a priority higher than Task2.
Therefore, for this task to reach this point Task2 must already have
executed and set its priority back down to 0. */
}
}

/*---------------------------------------*/

void vTask2( void *pvParameters )
{
unsigned portBASE_TYPE uxPriority;

/* Task1 will always run before this task as Task1 has the higher priority.
Neither Task1 nor Task2 ever block so will always be in either the
Running or the Ready state.

Query the priority at which this task is running - passing in NULL means
“return our own priority”. */
uxPriority = uxTaskPriorityGet(  xTask2Handle );

for(;; )
{
/* For this task to reach this point Task1 must have already run and
set the priority of this task higher than its own.
    Print out the name of this task. */

vPrintString( “GREEN” );
vTaskPrioritySet( xTask2Handle, ( uxPriority - 2 ) );
//vTaskPrioritySet(xTask3Handle, ( uxPriority + 3 ) );
vTaskPrioritySet(xTask3Handle, ( uxPriority + 0 ) );
}
}

/*---------------------------------------*/

void vTask3( void *pvParameters )
{
unsigned portBASE_TYPE uxPriority;

/* Task1 will always run before this task as Task1 has the higher priority.
Neither Task1 nor Task2 ever block so will always be in either the
Running or the Ready state.

Query the priority at which this task is running - passing in NULL means
“return our own priority”. */
uxPriority = uxTaskPriorityGet( xTask3Handle );

for( ;:wink:
   {
/* For this task to reach this point Task1 must have already run and
set the priority of this task higher than its own.

Print out the name of this task. */

vPrintString( “YELLOW” );

vTaskPrioritySet(xTask3Handle, ( uxPriority - 2 ) );
//vPrintString( “About to raise the Task2 priority\n” );
//vTaskPrioritySet( xTask2Handle, ( uxPriority + 3) );
  vTaskPrioritySet (xTask1Handle, (uxPriority - 1));
}
}

/*---------------------------------------*/

void vApplicationMallocFailedHook( void )
{
/* This function will only be called if an API call to create a task, queue
or semaphore fails because there is too little heap RAM remaining - and
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. */
for( ;; );
}

/*---------------------------------------*/

void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )
{
/* This function will only be called if a task overflows its stack.  Note
that stack overflow checking does slow down the context switch
implementation and will only be performed if configCHECK_FOR_STACK_OVERFLOW
is set to either 1 or 2 in FreeRTOSConfig.h. */
for( ;; );
}

/*---------------------------------------*/

void vApplicationIdleHook( void )
{
/* This example does not use the idle hook to perform any processing.  The
idle hook will only be called if configUSE_IDLE_HOOK is set to 1 in
FreeRTOSConfig.h. */
}
/*---------------------------------------*/

void vApplicationTickHook( void )
{
/* This example does not use the tick hook to perform any processing.   The
tick hook will only be called if configUSE_TICK_HOOK is set to 1 in
FreeRTOSConfig.h. */

}

rtel wrote on Monday, July 22, 2013:

You have #included timers.c instead of timers.h.

Regards.