CMP EMBEDDED.COM

Login | Register     Welcome Guest  
HOME DESIGN PRODUCTS COLUMNS E-LEARNING CONFERENCES CODE FORUMS/BLOGS NEWSLETTERS CONTACT FEATURES RSS RSS

A six step process for migrating embedded C into a C++ object-oriented framework



Embedded.com

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.

1 | 2 | 3 | 4

Rate this article: Low High
Current rating
  • .
Embedded.com Career Center
Looking for a new job?
SEARCH JOBS

Browse all jobs

SPONSOR
RECENT JOB POSTINGS





 :