Step #3 : Convert all Functions to
class methods (except ISRs)
As shown in Listing 5 below,
all old forward declarations become protected member functions.
Just move them into the private section of the header file. All so
far published functions become public members. In the implementation
just prefix all these functions with Timer.This step is quite simple.
So far we have a class with methods but no data. All class methods
use global data.
 |
| Listing
5. Additional methods. |
Step #4: Turn the ISR into a class
member
Interrupt-Service-Functions differ from ordinary functions in that they
are being called by the hardware which simply jumps to the address
saved in the interrupt vector table.
Of course, the hardware does not supply a "this" pointer. So an
Interrupt-Vector is a pointer to the ISR and a unique resource. This is
why the class function has to be static ("static function in OO" means
"a function that doesn't have a this pointer").
But how does the function know which object it should refer to?
(Congratulations if you were just asking this yourself!) Well, it
doesn't, and I'll start worrying about this when it comes to having
more than one instance of the timer. Let's just get on for now.
1. Remove the forward
declaration in timer.cpp
void TimerTx_ISR
(void) __irq;
and declarestatic
void
Tx_ISR (void) __irq;
in the protected section of the class
declaration in the header
instead.
2. Change the function name
in the .cpp file accordingly
void
Timer::Tx_ISR (void) __irq
3. Then adjust the
interrupt vector to point to the new function
SET_VIC_VECT_ADDR(TIMER_ILVL, Tx_ISR)
Step #5: Global variables become
protected member variables
All right. Do what it says and see what happens. Cut and paste the
global vars from timer.cpp to the protected section of class Timer. Try
to compile: All works fine. It is just the ISR that complains:
"nonstatic reference must be
relative to a specific object".
I admit, this "let's worry later" of Step 4 didn't last long here.
This is because the ISR uses member-variables now (instead of global
vars). Consequently it wants a this-pointer and cannot be
static. So,
here I want the ISR both to be non-static (so it knows the object's
state) and static (so it can
be an ISR) at the same time.
 |
| Listing
6. Static and non-static ISR |
Really I need two functions:
1. The static real ISR. It
has to somehow know the object instance
and call.
2. the non-static member
ISR-Handler function.
This means that I have to save the object instance pointer globally
somewhere so that the ISR can refer to it. The best place to do this
saving is the constructor. The additional changes required are listed
in Listing 6 above and Listing 7 below.
In this step I also changed the variable prefixes g_ (for global
var) to m_ (for member var).
 |
| Listing
7. Store object pointer globally and call "class ISR" |