Step #6: Dealing with Multiple
Object Instances
If we were using ordinary classes we would be ready now. But here each
instance of the timer class represents a physical HW-timer-peripheral.
Each HW-Timer has its own interrupt and register set to control it.
 |
| Listing
8. Header additions for multiple objects |
So that each object instance knows which registers to address, I
added pointers to the registers which the class now uses instead of the
fixed special-function-registers.
These pointers need to be set up in the constructor, depending on
which HW-timer is being used. The interrupt specific information
(priority, interrupt-channel)
is used and set in the same code section.
This is shown in Listing 8 above and Listing 9 below.
Just as I saved the object pointer globally (to be used in static
ISR) we now need to do this for each instance and add the static
ISRs
for all HW-Timers, that are to be supported.
 |
| Listing
9. Initialize correct HW, pointers to SFRs, second ISR |
Finally we create a second instance of the timer (in main.c) and use
the second timer. The test shows how well these two timers work.
Compare and contrast
Now it's the time to compare the initial and final projects with
respect to performance code size. For performance measurements I
decided to measure the time spent in the ISR (including calling the
callbacks). This is the time that reflects the amount of
processor time
used by the implementations. These results are shown in Table 1 below.
The differences in terms of SW-Design, ease of source code
maintenance can only be discussed qualitatively and individual
preferences will lead to different results. Personally, I prefer the OO
solution when I have more than one instance because I have only "one
instance" of source code and do not need to worry about keeping it in
sync.
 |
| Table
1. Comparison of code size and performance. |
These results are not surprising. The OO-solution needs an
additional this-pointer. Dereferencing member variables and passing the
additional parameter takes a little more time and consumes RAM. The
code size is also a little more but advantageous for the second
instance.
How useful are objects for real applications? Of course, the use of
two instances representing two HW-timers is not so obvious. But think
of applying this model to other applications. How about several
independent stepper-motor-drives that run entirely in HW. They run
synchronously due to the common oscillator clock.
I can also imagine applications where it would be very useful
to have
instances of a class that represent a group of identical or very
similar peripherals. Think of Bus-Couplers. Here you may have some
Bus-HW, that receives data on one end and copies (
possibly after
filtering) it to another Bus-HW of the same kind (
maybe at another bus
speed). Many MCUs have several identical communication
peripherals on
board that could well be implemented in this way.
Dirk Braun graduated from King's
College, University of London. His background ranges from software
design and development to the electronics of embedded systems. He has
recently developed a data centric RTOS
and can be contacted at dbraun@cleversoftware.de.