Difference between revisions of "GTIMER"

From uGFX Wiki
Jump to: navigation, search
(Created page with "µGFX comes with it's own timer abstraction module. The GTimer module provides high level, simple and hardware independend timers. The timers are meant to be used in different...")
 
(API reference)
 
(27 intermediate revisions by the same user not shown)
Line 1: Line 1:
µGFX comes with it's own timer abstraction module. The GTimer module provides high level, simple and hardware independend timers. The timers are meant to be used in different µGFX modules and are not very accurate.
+
µGFX comes with its own timer abstraction module. The GTIMER module provides high level, simple and hardware independent timers. Due to their nature of being virtual (software) timers they are not very accurate. However, the accuracy is more than enough for any GUI requirements.
  
The reason why µGFX has it's own timer abstraction is because virtual timers provided by the most RTOS are interrupt context only. While great for what they are designed for, they make coding of the input drivers much more complex. For non-performance critical drivers like these input drivers, it would also hog an in-ordinate amount of critical (interrupt locked) system time. This contrary to the goals of a real-time operating system. So a user-land (thread based) timer mechanism is also required.
+
The reason why µGFX has it's own timer abstraction is because virtual timers provided by most RTOSs are interrupt context only. While great for what they are designed for, they make coding of the input drivers much more complex. For non-performance critical drivers like these input drivers, it would also hog an in-ordinate amount of critical (interrupt locked) system time. This contrary to the goals of a real-time operating system. So a user-land (thread based) timer mechanism is also required.
  
Even if GTimer is originally meant for internal use only, you can still use it yourself. This might become handy in some applications. To use the GTimer module, you first have to tell your gfxconf.h that you'd like to use GTimer:
+
Even if GTIMER is originally meant for internal use only, you can still use it yourself. This might become handy in some applications.
  
#define GFX_USE_GTIMER TRUE
+
== API reference ==
+
The API reference of the GTIMER module can be found [http://api.ugfx.org/group___g_t_i_m_e_r.html here].
== Precision ==
+
GTimers are software timers and therefore their precision is totally unpredictable. The precision depends on how many threads and with which priority are currently running on the system. You can modify the GTimer thread priority and stack size in your gfxconf.h:
+
  
 +
== Usage ==
 +
A new GTimer job (from here on refered to as ''a timer'') can be created using <code>gtimerInit()</code>. Creating a new timer doesn't start it yet, it just initializes the <code>GTimer</code> object. A timer is started by using <code>gtimerStart()</code>. The function parameters specify the the timer interval, whether it's a single-shot or a periodic timer and the callback function. When the timer fires, the callback function will be executed.
 +
 +
Timers can be stopped at any time using <code>gtimerStop()</code>. Calling <code>gtimerJab()</code> will cause the timer period to expire immediately.
 +
 +
The callback function needs to have the following signature:
 +
<syntaxhighlight lang=c>
 +
void myCallback(void* param);
 +
</syntaxhighlight>
 +
 +
== Theory of operation ==
 +
When the GTIMER module has been enabled in the [[Configuration|configuration file]], a new thread will be created upon calling <code>gfxInit()</code>. The GTIMER thread maintains a list of all created timers. It iterates through that list periodically. When a timer period has expired the callback function that has been registered with that timer will be executed.
 +
 +
=== Precision ===
 +
GTimers are software timers and therefore their precision is totally unpredictable. The precision depends on how many threads and with which priority are currently running on the system. You can modify the GTimer thread priority and stack size in your [[Configuration|configuration file]]:
 +
 +
<syntaxhighlight lang=c>
 
#define GTIMER_THREAD_PRIORITY HIGH_PRIORITY
 
#define GTIMER_THREAD_PRIORITY HIGH_PRIORITY
#define GTIMER_THREAD_WORKAREA_SIZE 1024
+
</syntaxhighlight>
+
  
==Example==
+
See [[GOS#Thread_priority|threading]] for more information about thread priorities.
The API reference of GTimer should explain how to use it. But here's a simple, self explanatory example of how GTimer can be used:
+
 
 +
=== Stack size ===
 +
All GTimer jobs are executed in the same thread. This means that the GTimer thread needs to have a sufficient stack size to execute the callback function with the largest stack requirements. The default stack size for the GTimer thread is 2048 bytes to provide enough stack for the GTimer jobs used internally by some of the uGFX modules.
 +
<syntaxhighlight lang=c>
 +
#define GTIMER_THREAD_WORKAREA_SIZE 2048
 +
</syntaxhighlight>
 +
 
 +
== Example ==
 +
The following is a simple, self explanatory example of how a GTimer can be used. For more features, please have a look at the corresponding [[GTIMER#API_reference|api reference]].
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include "gfx.h"
 
#include "gfx.h"
 
   
 
   
GTimer GT1, GT2;
+
GTimer GT1;
 +
GTimer GT2;
 
   
 
   
void callback1(void* arg) {
+
void callback1(void* arg)
 +
{
 
     (void)arg;
 
     (void)arg;
  
Line 27: Line 51:
 
}
 
}
 
   
 
   
void callback2(void* arg) {
+
void callback2(void* arg)
 +
{
 
     (void)arg;
 
     (void)arg;
  
Line 33: Line 58:
 
}
 
}
 
   
 
   
int main(void) {  
+
int main(void)
 +
{  
 
     /* initialize µGFX and the underlying system */
 
     /* initialize µGFX and the underlying system */
 
     gfxInit();
 
     gfxInit();
Line 47: Line 73:
 
     gtimerStart(&GT2, callback2, NULL, FALSE, 1000);
 
     gtimerStart(&GT2, callback2, NULL, FALSE, 1000);
 
   
 
   
     while(TRUE) {
+
     while (TRUE) {
 
         gfxSleepMilliseconds(500);
 
         gfxSleepMilliseconds(500);
 
     }   
 
     }   
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
 +
 +
[[Category:Module]]

Latest revision as of 15:51, 4 February 2016

µGFX comes with its own timer abstraction module. The GTIMER module provides high level, simple and hardware independent timers. Due to their nature of being virtual (software) timers they are not very accurate. However, the accuracy is more than enough for any GUI requirements.

The reason why µGFX has it's own timer abstraction is because virtual timers provided by most RTOSs are interrupt context only. While great for what they are designed for, they make coding of the input drivers much more complex. For non-performance critical drivers like these input drivers, it would also hog an in-ordinate amount of critical (interrupt locked) system time. This contrary to the goals of a real-time operating system. So a user-land (thread based) timer mechanism is also required.

Even if GTIMER is originally meant for internal use only, you can still use it yourself. This might become handy in some applications.

API reference

The API reference of the GTIMER module can be found here.

Usage

A new GTimer job (from here on refered to as a timer) can be created using gtimerInit(). Creating a new timer doesn't start it yet, it just initializes the GTimer object. A timer is started by using gtimerStart(). The function parameters specify the the timer interval, whether it's a single-shot or a periodic timer and the callback function. When the timer fires, the callback function will be executed.

Timers can be stopped at any time using gtimerStop(). Calling gtimerJab() will cause the timer period to expire immediately.

The callback function needs to have the following signature:

void myCallback(void* param);

Theory of operation

When the GTIMER module has been enabled in the configuration file, a new thread will be created upon calling gfxInit(). The GTIMER thread maintains a list of all created timers. It iterates through that list periodically. When a timer period has expired the callback function that has been registered with that timer will be executed.

Precision

GTimers are software timers and therefore their precision is totally unpredictable. The precision depends on how many threads and with which priority are currently running on the system. You can modify the GTimer thread priority and stack size in your configuration file:

#define GTIMER_THREAD_PRIORITY			HIGH_PRIORITY

See threading for more information about thread priorities.

Stack size

All GTimer jobs are executed in the same thread. This means that the GTimer thread needs to have a sufficient stack size to execute the callback function with the largest stack requirements. The default stack size for the GTimer thread is 2048 bytes to provide enough stack for the GTimer jobs used internally by some of the uGFX modules.

#define GTIMER_THREAD_WORKAREA_SIZE		2048

Example

The following is a simple, self explanatory example of how a GTimer can be used. For more features, please have a look at the corresponding api reference.

#include "gfx.h"
 
GTimer GT1;
GTimer GT2;
 
void callback1(void* arg)
{
    (void)arg;
 
    palTogglePad(GPIOD, GPIOD_LED3);
}
 
void callback2(void* arg)
{
    (void)arg;
 
    palSetPad(GPIOD, GPIOD_LED4);
}
 
int main(void)
{ 
    /* initialize µGFX and the underlying system */
    gfxInit();
 
    /* initialize the timers */
    gtimerInit(&GT1);
    gtimerInit(&GT2);
 
    /* continious mode - callback1() called without any argument every 250ms */
    gtimerStart(&GT1, callback1, NULL, TRUE, 250);
 
    /* single shot mode - callback2() called without any argument once after 1s */
    gtimerStart(&GT2, callback2, NULL, FALSE, 1000);
 
    while (TRUE) {
        gfxSleepMilliseconds(500);
    }   
}