Embedded Systems September 2000 Vol13_10

Issue link:

Contents of this Issue


Page 163 of 229

Decrementing hundreds of timer counters at each lOms interrupt seems like a bad idea. Instead, we will use the well-known technique of a delta list. The implementation of TMR_ FIGURE J / ( '-------- ~ task / ---- 11 Delta Queue consists of running timers Application ----ยท~ Application task 3"\ j Process is simple. Internally, it will use the TMR_PutEvent and TMR_GetEvent functions, familiar to us from the dis- cussion of the event-driven tasks. See Listing 11. A data/ event flow diagram in somewhat simplified RT / SASD nota- tion is shown in Figure 3. You have already guessed that the '! Notes: 1 ,2,3 - Application-provided timeout handler functions (e.g. blinking cursor) 4,5 - Application tasks have read and write access to the delta queue via calls to TMR_Start and TMR_Stop 6 - Write via TMR_putEvent 7 - Read via TMR_GetEvent 8,9,10- Application timeout handler functions are called directly from TMR_process 11 - Thick green line separates application code from system code 10ms interrupt is, in our case, the only provider of the timers into the expired timers ring buffer. As we can have hundreds of software timers run- ning at any given time, we should implement this part of our system in a slightly more intelligent way. Decrementing hundreds of timer counters at each 10ms interrupt seems like a bad idea. Instead, we will use the well-known technique of a delta list. The timers are inserted in the delta queue based on their time- out values. Only the timer that is next due to expire is decremented in the interrupt routine. For example, if we have timers that are set to expire in 10, 60, and 200 clock ticks, our delta queue looks like: -----------------------' 10 50 (equals 60 minus 10) 140 (equals 200 minus 60) And the only one decrementing is the timer with 10 ticks left. The slight drawback of this tech- main control loop will become long and messy. So we must find a neater solution. You may have noticed a call to TMR_Process in the main control loop. This is the only non-user-defined task in our system. In our implementation, the TMR_Pr ocess task itself is an event- driven task, and works exactly as the user-defined event-driven tasks described in this article. Internally, the timer task could use something like the structures in Listing 9 to define the timer task input event queue. We use the Parameter field to add some flexibility to our module. The application may choose to use it for a variety of purposes, or simply ignore it. The software timer module in Listing 10 provides the three essential functions for use by the application tasks. Before calling TMR_Start and TMR_Stop functions, a user-defined timeout function for each timer must be installed. This is done by calling TMR_InstaLLTi meoutHandler with two parameters: a unique timer ID and a pointer to a timeout function. After this, a timer can be started and stopped by using the TMR_Start and TMR_Stop functions. 162 SEPTEMBER 2000 Embedded Systems Programming nique is the fact that we need to do a bit more processing when we add or remove a timer to/ from the delta queue. Plus, there is a tricky case of two timers due to expire at the same time (some delta queue implementa- tions cheat and add an extra tick to avoid this situation). So what happens when the 10ms interrupt routine decrements the head of the delta queue to zero? Of course, it doesn't call the timeout han- dler directly, as this would take a large, application-determined amount of time and can't be executed with inter- rupts disabled. Instead, it removes it

Articles in this issue

Archives of this issue

view archives of EETimes - Embedded Systems September 2000 Vol13_10