TNeoKernel  v1.03
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Data Structures | Typedefs | Functions
tn_timer.h File Reference

Detailed Description

Timer is a kernel object that is used to ask the kernel to call some user-provided function at a particular time in the future, based on the system timer tick.

If you need to repeatedly wake up particular task, you can create semaphore which you should wait for in the task, and signal in the timer callback (remember that you should use tn_sem_isignal() in this callback, since it is called from an ISR).

If you need to perform rather fast action (such as toggle some pin, or the like), consider doing that right in the timer callback, in order to avoid context switch overhead.

The timer callback approach provides ultimate flexibility.

In the spirit of TNeoKernel, timers are as lightweight as possible. That's why there is only one type of timer: the single-shot timer. If you need your timer to fire repeatedly, you can easily restart it from the timer function by the tn_timer_start(), so it's not a problem.

When timer fires, the user-provided function is called. Be aware of the following:

Consequently:

See TN_TimerFunc for the prototype of the function that could be scheduled.

Implementation of timers

Although you don't have to understand the implementation of timers to use them, it is probably worth knowing, particularly because the kernel have an option TN_TICK_LISTS_CNT to customize the balance between performance of tn_tick_int_processing() and memory occupied by timers.

The easiest implementation of timers could be something like this: we have just a single list with all active timers, and at every system tick we should walk through all the timers in this list, and do the following with each timer:

This approach has drawbacks:

The latter is probably not so critical in the embedded world since large amount of timers is unlikely there; whereas the former is actually notable.

So, different approach was applied. The main idea is taken from the mainline Linux kernel source, but the implementation was simplified much because (1) embedded systems have much less resources, and (2) the kernel doesn't need to scale as well as Linux does. You can read about Linux timers implementation in the book "Linux Device Drivers", 3rd edition:

This book is freely available at http://lwn.net/Kernel/LDD3/ .

So, TNeoKernel's implementation:

We have configurable value N that is a power of two, typical values are 4, 8 or 16.

If the timer expires in the next 1 to (N - 1) system ticks, it is added to one of the N lists (the so-called "tick" lists) devoted to short-range timers using the least significant bits of the timeout value. If it expires farther in the future, it is added to the "generic" list.

Each N-th system tick, all the timers from "generic" list are walked through, and the following is performed with each timer:

At every system tick, all the timers from current "tick" list are fired unconditionally. This is an efficient and nice solution.

The attentive reader may want to ask why do we use (N - 1) "tick" lists if we actually have N lists. That's because, again, we want to be able to modify timers from the timer function. If we use N lists, and user wants to add new timer with timeout equal to N, then new timer will be added to the same list which is iterated through at the moment, and things will be mixed up.

If we use (N - 1) lists, we are guaranteed that new timers can't be added to the current "tick" list while we are iterating through it. (although timer can be deleted from that list, but it's ok)

The N in the TNeoKernel is configured by the compile-time option TN_TICK_LISTS_CNT.

Definition in file tn_timer.h.

Go to the source code of this file.

Data Structures

struct  TN_Timer
 Timer. More...
 

Typedefs

typedef void( TN_TimerFunc )(struct TN_Timer *timer, void *p_user_data)
 Prototype of the function that should be called by timer. More...
 

Functions

enum TN_RCode tn_timer_create (struct TN_Timer *timer, TN_TimerFunc *func, void *p_user_data)
 Construct the timer. More...
 
enum TN_RCode tn_timer_delete (struct TN_Timer *timer)
 Destruct the timer. More...
 
enum TN_RCode tn_timer_start (struct TN_Timer *timer, TN_Timeout timeout)
 Start or restart the timer: that is, schedule the timer's function (given to tn_timer_create()) to be called later by the kernel. More...
 
enum TN_RCode tn_timer_cancel (struct TN_Timer *timer)
 If timer is active, cancel it. More...
 
enum TN_RCode tn_timer_set_func (struct TN_Timer *timer, TN_TimerFunc *func, void *p_user_data)
 Set user-provided function and pointer to user data for the timer. More...
 
enum TN_RCode tn_timer_is_active (struct TN_Timer *timer, BOOL *p_is_active)
 Returns whether given timer is active or inactive. More...
 
enum TN_RCode tn_timer_time_left (struct TN_Timer *timer, TN_Timeout *p_time_left)
 Returns how many system timer ticks (at most) is left for the timer to expire. More...
 

Typedef Documentation

typedef void( TN_TimerFunc)(struct TN_Timer *timer, void *p_user_data)

Prototype of the function that should be called by timer.

When timer fires, the user-provided function is called. Be aware of the following:

Consequently:

  • It's legal to call interrupt services from this function;
  • The function should be as fast as possible.
Parameters
timerTimer that caused function to be called
p_user_dataThe user-provided pointer given to tn_timer_create().

Definition at line 197 of file tn_timer.h.

Function Documentation

enum TN_RCode tn_timer_create ( struct TN_Timer timer,
TN_TimerFunc func,
void *  p_user_data 
)

Construct the timer.

id_timer field should not contain TN_ID_TIMER, otherwise, TN_RC_WPARAM is returned.

attr_call_task.png
attr_call_int.png
(refer to Legend for details)

Parameters
timerPointer to already allocated struct TN_Timer
funcFunction to be called by timer, can't be NULL. See TN_TimerFunc()
p_user_dataUser data pointer that is given to user-provided func.
Returns
enum TN_RCode tn_timer_delete ( struct TN_Timer timer)

Destruct the timer.

If the timer is active, it is cancelled first.

attr_call_task.png
attr_call_int.png
(refer to Legend for details)

Parameters
timertimer to destruct
Returns
enum TN_RCode tn_timer_start ( struct TN_Timer timer,
TN_Timeout  timeout 
)

Start or restart the timer: that is, schedule the timer's function (given to tn_timer_create()) to be called later by the kernel.

See TN_TimerFunc().

It is legal to restart already active timer. In this case, the timer will be cancelled first.

attr_call_task.png
attr_call_int.png
(refer to Legend for details)

Parameters
timerTimer to start
timeoutNumber of system ticks after which timer should fire (i.e. function should be called). Note that timeout can't be TN_WAIT_INFINITE or 0.
Returns
enum TN_RCode tn_timer_cancel ( struct TN_Timer timer)

If timer is active, cancel it.

If timer is already inactive, nothing is changed.

attr_call_task.png
attr_call_int.png
(refer to Legend for details)

Parameters
timerTimer to cancel
Returns
enum TN_RCode tn_timer_set_func ( struct TN_Timer timer,
TN_TimerFunc func,
void *  p_user_data 
)

Set user-provided function and pointer to user data for the timer.

Can be called if timer is either active or inactive.

attr_call_task.png
attr_call_int.png
(refer to Legend for details)

Parameters
timerPointer to timer
funcFunction to be called by timer, can't be NULL. See TN_TimerFunc()
p_user_dataUser data pointer that is given to user-provided func.
Returns
enum TN_RCode tn_timer_is_active ( struct TN_Timer timer,
BOOL p_is_active 
)

Returns whether given timer is active or inactive.

attr_call_task.png
attr_call_int.png
(refer to Legend for details)

Parameters
timerPointer to timer
p_is_activePointer to BOOL variable in which resulting value should be stored
Returns
enum TN_RCode tn_timer_time_left ( struct TN_Timer timer,
TN_Timeout p_time_left 
)

Returns how many system timer ticks (at most) is left for the timer to expire.

If timer is inactive, 0 is returned.

attr_call_task.png
attr_call_int.png
(refer to Legend for details)

Parameters
timerPointer to timer
p_time_leftPointer to TN_Timeout variable in which resulting value should be stored
Returns