Timers

The implementation of timers has been slightly modified from the original uC/OS-II code to ensure ultra-low power operation. Contrary to the code supplied with uC/OS-II, the Dust Networks timer implementation does not use an internal periodic tick to count off the timer delays – the processor is truly idle while waiting for next timer to expire. 

While the interface to use the timers stays equivalent to the interface with the original uC/OS-II implementation, the following aspects are important to note.

Refer to the uC/OS-II Timers and associated 00-uc_timers sample application for an illustration of the concepts developed in this section.

Your application has two options for delaying the execution of one of your tasks:

  • Your task can call the OSTimeDly() function, which halts the execution of that task for the specified duration. The duration passed as a parameter is expressed in OS ticks. Note that, while your task is being delayed, the implementation of OSTimeDly() creates, then deletes a uC/OS-II semaphore. You need to take this constraint into account when accounting for the number of Event Control Blocks (ECBs) your application is using (see Resources). In the worst case, each of your tasks can be delayed by a call to the OSTimeDly() function at the same time. If this is a possibility in your application, you need to leave as many ECBs free as you have tasks in your application.
  • Alternatively, you can use the OSTmrCreate() function to create a timer (which can be periodic), and call OSTmrStart()to start it. When creating the timer, you also specify a callback function to be called when the timer expires. A number of "best practice" rules apply to what you are doing in the body of this callback function:
    • This callback function is called from the "timer task" (part of the 

      SmartMesh library

      ). This task is responsible for calling the callback function of all the timers expiring, including the ones created in the 

      SmartMesh network stack

      . Not unlike an Interrupt Service Routine, the execution of the callback should therefore be fast.
    • Since the callback function is called from within the "timer task", all the local variables of your callback function are placed onto the stack of this "timer task". Since the amount of available stack space of that task is limited, we recommend not to allocate large amounts of memory as local variables inside the callback function.
    • To satisfy those two constraints, typically, the callback function just posts a semaphore. The handling of the timer event is done in a separate task, which pends on the semaphore, and executes the handling routine when the semaphore is posted by the callback function. This is the behavior implemented in the 00-uc_timers sample application, and detailed in uC/OS-II Timers.