Example code to explain what I mean by a hierarchical set of pointer to functions. pfint() is the lowest level call back pointer, and pframp() is a higher level call back pointer. In this example the call back pointer for startramp() is passed as a parameter. A function could also be used to set the call back pointer pfint() via a parameter.
(Note - in the case of that floppy tape driver I worked on, there were 5 levels of pointers, for example, rewind() was high level, it would start a rewind operation, then call waitforready(), which in turn would call getstatus(). getstatus() would go through it's 10 interrupt sequence and then call back the function passed from waitforready(). The next step in waitforready() would keep repeating the interrupt driven sequence until ready or an error was detected, then waitforready would return to the call back function passed from rewind(), which would in turn call back the function passed to rewind() as a parameter.)
Code:
typedef void (*PFUN)(void); /* typedef for generic pointer to function */
void unexpected(void); /* unexpected interrupt handler */
void rstep0(void); /* lowest level sequence */
void rstep1(void);
void rstep2(void);
void ramp0(void); /* higher level sequence */
void ramp1(void);
PFUN pfint = unexpected; /* ptr to call back for interrupt */
PFUN pframp = unexpected; /* ptr to call back for ramp up */
void interrupt(void) /* interrupt handler */
{
pfint();
}
void startramp(PFUN callback)
{
pframp = callback; /* set callback ptr */
pfint = rstep0; /* set ptr for next rstep */
/* ** start ramp sequence */
}
void rstep0(void) /* rstep 0 handler */
{
pfint = rstep1; /* set ptr for next rstep */
/* ... ** handle this rstep */
}
void rstep1(void) /* rstep 1 handler */
{
pfint = rstep2; /* set ptr for next rstep */
/* ... ** handle this rstep */
}
void rstep2(void) /* rstep 2 handler */
{
pfint = unexpected; /* not expecting another interrupt */
/* ... ** handle this rstep */
pframp(); /* call the call back handler */
}
void ramp0(void) /* start a ramp up */
{
startramp(ramp1);
}
void ramp1(void)
{
/* ** ramp up is done */
}