Skip to content

Timer Handling#

The timer component provides an interface to function executions initiated by a timer.

Module Context#

classDiagram
  CO_NODE o-- CO_TMR
  CO_TMR_ACTION o-- CO_TMR : APool, Acts
  CO_TMR_TIME o-- CO_TMR : TPool, Free, Use, Elapsed
  class CO_TMR {
    -uint32_t Max
    -uint32_t Freq
    +COTmrCreate(start, cycle, function, para) int16_t
    +COTmrDelete(action) int16_t
    +COTmrGetMinTime(unit) uint16_t
    +COTmrGetTicks(time, unit) int32_t
    +COTmrProcess()
    +COTmrService() int16_t
  }

Structure Data#

The class CO_TMR is defined within co_tmr.h and is responsible for the CANopen highspeed timer management. The following data members are in this class:

Data Member Type Description
Acts CO_TMR_ACTION* pointer to the root of free actions linked list
APool[] CO_TMR_ACTION timer action pool array
Elapsed CO_TMR_TIME* pointer to the root of elapsed timers linked list
Free CO_TMR_TIME* pointer to the root of free events linked list
Freq uint32_t timer ticks per second
Max uint32_t maximum nunber of timed actions
Node CO_NODE* pointer to parent node object
TPool[] CO_TMR_TIME timer event pool array
Use CO_TMR_TIME* pointer to the root of used events linked list

Note

The data within this structure must never be manipulated without the corresponding class member functions. This can lead to unpredictable behavior of the node.

Member Functions#

The following table describes the API functions of the CANopen timer module. With the listed functions we can define the execution of actions after a given time interval with or without a cycle time. The functions are implemented within the source files: co_tmr.c/h.

COTmrCreate()#

This function is used within the CANopen stack for timed actions. It is possible to use timed actions in the application, too.

Prototype

int16_t COTmrCreate(CO_TMR      *tmr,
                    uint32_t     start,
                    uint32_t     cycle,
                    CO_TMR_FUNC  function,
                    void        *para);

Arguments

Parameter Description
tmr pointer to timer object
start delta time in ticks for the first timer-event
cycle if != 0, the delta time in ticks for the cyclic timer events
function pointer to the action callback function
para pointer to the callback function parameter

Returned Value

  • >=0 : action identifier (successful operation)
  • <0 : an error is detected

Example

The following example installs a cyclic called function AppCyclicFunc() to the CANopen node AppNode. The timed function will be called the first time after 10ms and then every 25ms with the parameter: 0xcafe.

CO_TMR  *tmr;
int16_t  aid;
uint32_t start;
uint32_t cycle;
  :
tmr   = &AppNode.Tmr;
start = COTmrGetTicks(tmr, 10, CO_TMR_UNIT_1MS);
cycle = COTmrGetTicks(tmr, 25, CO_TMR_UNIT_1MS);
aid = COTmrCreate(tmr, start, cycle, AppCyclicFunc, 0xcafe);
if (aid >= 0) {

  /* tid holds the timer identifier */

} else {

  /* error during creation of timed action */

}
  :

Note

The example assumes, that the timer callback function AppCyclicFunc() is implemented with the correct prototype. The hardware timer is configured with sufficient timer clock frequency to achieve the 5ms resolution.

COTmrDelete()#

This function is used within the CANopen stack for timed actions. It is possible to use timed actions in the application, too.

Prototype

int16_t COTmrDelete(CO_TMR  *tmr,
                    int16_t  action);

Arguments

Parameter Description
tmr pointer to timer object
action action identifier, returned by COTmrCreate()

Returned Value

  • >=0 : action identifier (successful operation)
  • <0 : an error is detected

Example

The following calls a critical function AppCritFunc() and installs a function AppEmcyFunc() to the CANopen node AppNode to guarantee a maximum runtime of 150ms. The timed function will be called after 150ms and perform emergency handling with the parameter 0xdead. If the AppCritFunc() is finished before 150ms, the timed emergency function call will be removed.

CO_TMR     *tmr;
CPU_INT16S  aid;
uint32_t    max;
  :
tmr = &AppNode.Tmr;
max = COTmrGetTicks(tmr, 150, CO_TMR_UNIT_1MS);
aid = COTmrCreate(tmr, max, 0, AppEmcyFunc, 0xdead);
if (aid >= 0) {
  AppCritFunc();
  err = COTmrDelete(tmr, aid);
  if (err < 0) {

    /* error during deleting the timed action */

  }
} else {

  /* error during creation of timed action */

}
  :

Note

The example assumes, that the timer callback function AppEmcyFunc() and the application function AppCritFunc() are implemented with the correct prototype. The hardware timer is configured with sufficient timer clock frequency to achieve the 50ms resolution.

COTmrGetMinTime()#

This function returns the time interval in the given unit, which represents a single configured timer tick.

Prototype

uint16_t COTmrGetMinTime(CO_TMR   *tmr,
                         uint32_t  unit);

Arguments

Parameter Description
tmr pointer to timer object
unit unit of given time (CO_TMR_UNIT_1MS or CO_TMR_UNIT_100US)

Returned Value

  • >0 : time value in the given time interval for a single timer tick
  • =0 : a single given time interval unit is not possible with the used timer

Example

The following example calculates the smallest possible time interval in 100us.

CO_TMR  *tmr;
uint32_t min_100us;
  :
tmr = &AppNode.Tmr;
  :
min_100us = COTmrGetMinTime(tmr, CO_TMR_UNIT_100US);
if (min_100us == 0) {

  /* timer is not configured */

} else {

  /* you can use time intervals with multiple of min_100us */

}
  :

COTmrGetTicks()#

This function is used within the CANopen stack for calculating timeouts, event-times and other needed time intervals.

Prototype

int32_t COTmrGetTicks(CO_TMR   *tmr,
                      uint16_t  time,
                      uint32_t  unit);

Arguments

Parameter Description
tmr pointer to timer object
time time interval as a value of given units
unit unit of given time (CO_TMR_UNIT_1MS or CO_TMR_UNIT_100US)

Returned Value

  • >0 : timer ticks for the given time interval
  • =0 : given time interval is not possible with the used timer

Example

The following example calculates the number of ticks for 10.7ms and for 2.5s.

CO_TMR  *tmr;
uint32_t tick_10_7ms;
uint32_t tick_2500ms;
  :
tmr = &AppNode.Tmr;
  :
tick_10_7ms = COTmrGetTicks(tmr, 107, CO_TMR_UNIT_100US);
if (tick_10_7ms == 0) {

  /* time interval 10.7ms is not possible */

} else {

  /* you can use the time interval 10.7ms */

}
  :
tick_2500ms = COTmrGetTicks(tmr, 2500, CO_TMR_UNIT_1MS);
if (tick_2500ms == 0) {

  /* time interval 2.5s is not possible */

} else {

  /* you can use the time interval 2.5s */

}
  :

Note

The example assumes that the CANopen node is already initialized with CONodeInit() because the specified frequency in the specification structure is the foundation for these calculations.

COTmrProcess()#

The function is used decouple the generation of the periodic time base and the timed action processing.

Prototype

void COTmrProcess(CO_TMR *tmr);

Arguments

Parameter Description
tmr pointer to timer object

Returned Value

  • none

Example

The timed action processing must be called cyclic. Due to the timer management, the calling sequence is irrelevant. Therefore the function may be called in the background loop of the application:

void main(int argc, char *argv[])
{
    :
  while (1) {
      :
    COTmrProcess(&(AppNode.Tmr));
      :
  }
}

COTmrService()#

The function is used to generate a periodic time base and must be called cyclic.

Prototype

int16_t COTmrService(CO_TMR *tmr);

Arguments

Parameter Description
tmr pointer to timer object

Returned Value

  • =0 : no timer is elapsed
  • >0 : at least one timer is elapsed
  • <0 : an error is detected

Example

The following interrupt service function generates the time base for the CANopen timed actions with periodic calls of the function COTmrService(). When using an RTOS, the return value may be used to decide of triggering a separate timer task to process the elapsed events.

void HardwareTimerISR(void)
{
    int16_t num;

    num = COTmrService(&(AppNode.Tmr));
    if (num > 0) {

        /* post an event to the timer processing task */

    }
}