O''''Reilly Network For Information About''''s Book part 201 pps

5 63 0
O''''Reilly Network For Information About''''s Book part 201 pps

Đang tải... (xem toàn văn)

Thông tin tài liệu

// timerList.tick(); // // Acknowledge the timer interrupt. // gProcessor.pPCB->intControl.eoi = EOI_NONSPECIFIC; // // Clear the Maximum Count bit (to start the next cycle). // gProcessor.pPCB->timer[2].control &= ~TIMER_MAXCOUNT; } /* Interrupt() */ Of course, the tick method of the TimerList class does most of the work here. This method is mostly concerned with linked list manipulation and is not very exciting to look at. Briefly stated, the tick method starts by decrementing the tick count of the timer at the top of the list. If that timer's count has reached zero, it changes the state of the software timer to Done and removes it from the timer list. It also does the same for any timers that are set to expire on the very same tick. These are the ones at the new head of the list that also have a count of zero. After creating and starting a software timer, the application programmer can do some other processing and then check to see if the timer has expired. The waitfor method is provided for that purpose. This routine will block until the software timer's state is changed to Done by timerList.tick. The implementation of this method is as follows: /****************************************************************** **** * * Method: waitfor() * * Description: Wait for the software timer to finish. * * Notes: * * Returns: 0 on success, -1 if the timer is not running. * ****************************************************************** ****/ int Timer::waitfor() { if (state != Active) { return (-1); } // // Wait for the timer to expire. // while (state != Done); // // Restart or idle the timer, depending on its type. // if (type == Periodic) { state = Active; timerList.insert(this); } else { state = Idle; } return (0); } /* waitfor() */ One important thing to notice about this code is that the test while (state != Done) is not an infinite loop. That's because, as we just learned a few paragraphs back, the timer's state is modified by timerList.tick, which is called from the interrupt service routine. In fact, if we were being careful embedded programmers, we would have declared state as volatile. Doing so would prevent the compiler from incorrectly assuming that the timer's state is either done or not done and optimizing away the while loop. [3] The final method of the Timer class is used to cancel a running timer. This is easy to implement because we need only remove the timer from the timer list and change its state to Idle. The code that actually does this is shown here: /****************************************************************** **** * * Method: cancel() * * Description: Stop a running timer. * * Notes: * * Returns: None defined. * ****************************************************************** ****/ void Timer::cancel(void) { // // Remove the timer from the timer list. // if (state == Active) { timerList.remove(this); } // // Reset the timer's state. // state = Idle; } /* cancel() */ Of course, there is also a destructor for the Timer class, though I won't show the code here. Suffice it to say that it just checks to see if the software timer is active and, if so, removes it from the timer list. This prevents a periodic timer that has gone out of scope from remaining in the timer list indefinitely and any pointers to the "dead" timer from remaining in the system. For completeness, it might be nice to add a public method, perhaps called poll, that allows users of the Timer class to test the state of a software timer without blocking. In the interest of space, I have left this out of my implementation, but it would be easy to add such a routine. It need only return the current value of the comparison state == Done. However, in order to do this, some technique would need to be devised to restart periodic timers for which waitfor is never called. Watchdog Timers Another type of timer you might hear mentioned frequently in reference to embedded sy stems is a watchdog timer. This is a special piece of hardware that protects the system from software hangs. If present, the watchdog timer is always counting down from some large number to zero. This process typically takes a few seconds to complete. In the meantime, it is possible for the embedded software to "kick" the watchdog timer, to reset its counter to the original large number. If the counter ever does reach zero, the watchdog timer will assume that the software is hung. It then resets the embedded processor and, thus, restarts the software. This is a common way to recover from unexpected software hangs that occur after the system is deployed. For example, suppose that your company's new product will travel into space. No matter how much testing you do before deployment, the possibility remains that there are undiscovered bugs lurking in the software and that one or more of these is capable of hanging the system altogether. If the software hangs, you won't be able to communicate with it at all, so you can't just issue a reset command remotely. Instead, you must build an automatic recovery mechanism into the system. And that's where the watchdog timer comes in. The implementation of the watchdog timer "kick" would look just like the Blinking LED program in this chapter, except that instead of toggling the LED the watchdog timer's counter would be reset. Another potential feature of the Timer class is asynchronous callbacks. In other words, why not allow the creator of a software timer to attach a function to it. This function could then be called automatically—via timerList.tick —each time that timer expires. As you read the next section, be sure to think about how different the Blinking LED program would look if asynchronous callbacks were used instead. This is one type of application to which asynchronous function calls are particularly well suited. 7.4 Das Blinkenlights, Revisited Now that we have the Timer class at our disposal, it is possible to rewrite the book's very first example to make its timing more precise. Recall that in our original implementation, we relied on the fact that the length of a "decrement and compare" operation was fixed for a given processor and speed. We simply took a guess as to how long that might be and then revised our estimate based on empirical testing. By utilizing the Timer class, we can simultaneously eliminate this guesswork and increase the readability of the program. In the revised Blinking LED program below you will see that we can now simply start a periodic 500 ms software timer, toggle the LED, and then wait for the timer to expire before toggling the LED again. In the meantime, we could perform other processing tasks required by the application at hand. #include "timer.h" #include "led.h" /****************************************************************** **** * * Function: main() * * Description: Blink the green LED once a second. * * Notes: This outer loop is hardware-independent. However, it * calls the hardware-dependent function toggleLed(). * * Returns: This routine contains an infinite loop. * ****************************************************************** ****/ void main(void) { Timer timer; timer.start(500, Periodic); // Start a periodic 500 ms timer. while (1) { toggleLed(LED_GREEN); // Toggle the green LED. // Do other useful work here. timer.waitfor(); // Wait for the timer to expire. } } /* main() */ . 500 ms software timer, toggle the LED, and then wait for the timer to expire before toggling the LED again. In the meantime, we could perform other processing tasks required by the application. /****************************************************************** **** * * Method: waitfor() * * Description: Wait for the software timer to finish. * * Notes: * * Returns: 0 on success, -1 if. ****************************************************************** ****/ int Timer::waitfor() { if (state != Active) { return (-1); } // // Wait for the timer to expire. // while (state != Done); //

Ngày đăng: 07/07/2014, 08:20

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan