This is an old revision of the document!
Timers in OSA are used to simplify writing time-depended code. Using timers you can allocate quantum of time for task, or make delays or timeouts in functions that are not tasks. Timing in OSA is making by OS_Timer service. When calling this service, all active timers incremented by 1. If any timer will overflow, then corresponding timeout bit will be set.
There are two types of timers in OSA: dynamic and static. Main difference between them is that dinamic timers can be created and deleted in real-time and static are created once on compilation stage and can not be deleted.
The advantage of dinamic timers is that they can be declared in any place of program, thus they can be used in independed program modules. The disadvantage is that they use more RAM and ROM and work slowest than static timers.
The advantage of static timers is that they are fast and use little RAM and ROM. The disadvantage is that their number is fixed and must be set on project stage in OSAcfg.h.
In addition, important difference is that static timer after overflow stops, and dinamic continue counting.
To use dinamic timers in your program you have to define constant in OSAcfg.g:
#define OS_ENABLE_DTIMERS
This will include functions for working with dynamic timers in you code. Variables of dynamic timers are declared using OST_DTIMER type:
OST_DTIMER mytimer;
Variable mytimer contains timer counter, timer's state flags and pointer to next timer in list. Size of timer counter for dynamic timers is set by OS_DTIMER_SIZE constant in OSAcfg.h (By default this constant is equal to OS_TIMER_SIZE).
Dynamic timer can be in one of 4 states:
Not created (or deleted) | The timer is not in list of active timers. The system does not know about it and does not work with it |
Active | The timer was created by service OS_Dtimer_Create and was put into list of active timers. |
Counting | Every call of OS_Timer service timer's counter will increment by 1. To start counting you can use one of services: OS_Dtimer_Run or OS_Dtimer_Continue. |
Stopped | The timer was stopped by OS_Dtimer_Stop service. It is still present in list of active timers, but not counting. |
Here is small example of using dynamic timer to generate pulse of given length and with frequency filling. (It supposed that system tick = 1 ms):
OST_SMSG smsg; void Task1 (void) { for (;;) { ... OS_Smsg_Send(smsg, 200); // We need 200 ms pulse ... } } void Task2 (void) { OST_SMSG msg; static OST_DTIMER myTimer; RB0 = 0; OS_Dtimer_Create(myTimer); // Create dynamic timer for (;;) { OS_Smsg_Wait(smsg, msg); // Wait for message to start pulse OS_Dtimer_Run(myTimer, msg); // Run timer with given value do { RB0 ^= 1; // Generate meander OS_Delay(5); // Filling frequency = 100 Hz } while (!OS_Dtimer_Check(myTimer)); // Wait for timeout RB0 = 0; } }
To use static timers in your program you need to set number of timers you want to use in OSAcfg.h:
#define OS_STIMERS 5
In this example array of 5 timers will be cteated. The size of static timers is set by OS_STIMER_SIZE constant in OSAcfg.h:
#define OS_STIMER_SIZE 2
(By default this constant is equal to OS_TIMER_SIZE).
The most significant bit of every static timer shows current timers state: =1 - counting, =0 - stopped. Thus size of counter of static timer is 1 bit less then size of OS_STIMER_SIZE. For example, if OS_STIMER_SIZE = 2 bytes, then timer's counter size is 15 bits. You should to notice it when forming delays.
To work with static timers we provide all services by timer's identification number as parameter. It is comfortable to enumerate all static timers through enum:
enum OSA_STIMERS_ENUM { ST_TIMER0, ST_TIMER1, ST_TIMER2, ST_TIMER3 }
Static timers can be applied to forming delays in low-RAM controllers. For example, we run 6 tasks under PIC10F222 and only 2 of them use service OS_Delay. If we use task's timers, then 4 variables (timers in four of si tasks) are not used. Thus we lose 4 (or more) bytes of memory. Using static timers we can avoid losing RAM. We can to declare only 2 static timers (one for each task). In this case we get the advantage of speed (OS_Timer will work with two timers instead 6), RAM (four task timers are deleted) and ROM (functions for task timers are deleted).
Note: this substitution is possible for forming delays only. Static timers can't be used for events waiting with timeouts.
Here is example of forming delay in task using static timer:
// OAScfg.h #define OS_STIMERS 1 enum OS_STIMERS_ENUM { ST_MyTimer // Static timer's ID } ------------------------------------------------------------ // Fragment of program (it is supposed that system tick = 1 ms) void Task1 (void) { for (;;) { ... OS_Stimer_Delay(ST_MyTimer, 100); // 100 ms delay ... } }
Here are maximum possible time intervals that static timers can count for most often system ticks used:
OS_Timer's period | 1 byte | 2 bytes | 4 bytes |
---|---|---|---|
Range: | 0-128 | 0-32768 | 0-2147483648 |
1 ms | 128 ms | 32 sec | 24 days |
10 ms | 1.2 sec | 5 min | 245 days |
18.2 ms | 4.6 sec | 9 min | 450 days |
256 us | 65 ms | 8 sec | 6 days |
1024 us | 260 ms | 33 sec | 25 days |
8192 us | 2 sec | 4 min | 200 days |
Service | Arguments | Description | Properties |
---|---|---|---|
Creating/Deleting | |||
OS_Dtimer_Create | (dtimer) | Add dynamic timer in list of active timers | ![]() ![]() |
OS_Dtimer_Delete | (dtimer) | Delete dynamic timer from list of active timers | ![]() ![]() |
Menagement | |||
OS_Dtimer_Run | (dtimer, newtime) | Start counting with given newtime. Timeout flag is cleared. | ![]() |
OS_Dtimer_Stop | (dtimer) | Stop/pause dynamic timer. Timeout flag remain unchanged. | ![]() |
OS_Dtimer_Pause | (dtimer) | Same as OS_Dtimer_Stop | ![]() |
OS_Dtimer_Break | (dtimer) | Stop dynamic timer. Timeout flag became set. | ![]() |
OS_Dtimer_Continue | (dtimer) | Continue dinamic timer's counting after pause. Timeout flag remain unchanged. | ![]() |
OS_Dtimer_Update | (dtimer, time) | Re-run static timer for time time since last overflow. Timeout flag is cleared. | ![]() |
OS_Dtimer_Add | (dtimer, addtime) | Increase time of dinamic timer counter. Timeout flag remain unchanged. | ![]() |
Checking | |||
_OST_DTIMER OS_Dtimer_Get | (dtimer) | Get dinamic timer's remaining time. | ![]() |
bool OS_Dtimer_Check | (dtimer) | Check for dynamic timer overflowed | ![]() |
bool OS_Dtimer_IsActive | (dtimer) | Check for dynamic timer present in list of active timers | ![]() |
bool OS_Dtimer_IsStopped | (dtimer) | Check for dynamic timer is stopped | ![]() |
bool OS_Dtimer_IsRun | (dtimer) | Check for dynamic timer is counting | ![]() |
Waiting | |||
OS_Dtimer_Wait | (dtimer) | Wait for dynamic timer overflowed | ![]() ![]() ![]() |
OS_Dtimer_Delay | (dtimer, delay) | Delay current task using dynamic timer | ![]() ![]() ![]() |
Service | Arguments | Description | Properties |
---|---|---|---|
Menagement | |||
OS_Stimer_Run | (stimer_id, time) | Start counting static timer | ![]() |
OS_Stimer_Stop | (stimer_id) | Stop/pause static timer. Timeout flag is set. | ![]() |
OS_Stimer_Pause | (stimer_id) | Same as OS_Stimer_Stop | ![]() |
OS_Stimer_Continue | (stimer_id) | Continue counting after pause | ![]() |
Checking | |||
_OST_STIMER OS_Stimer_Get | (stimer_id) | Get static timer's remaining time | ![]() |
bool OS_Stimer_Check | (stimer_id) | Check for static timer overflowed | ![]() ![]() |
bool OS_Stimer_IsRun | (stimer_id) | Check for static timer is counting | ![]() ![]() |
Waiting | |||
OS_Stimer_Wait | (stimer_id) | Wait for static timer overflowed | ![]() ![]() ![]() |
OS_Stimer_Delay | (stimer_id, delay) | Delay current task using static timer | ![]() ![]() ![]() |