Ahren
Ahren

Reputation: 3

How to implement separate static variables for a given function called with different parameters

I am currently working on a microcontroller project in C that requires several timed functions to take place. I am a using a hardware timer to produce an interrupt every millisecond, and variables as counters to produce the appropriate time intervals. The hardware details are not important.

As an example, for a particular function, the following code would be executed on every tick of the 1ms counter, resulting in Function() being called every 10ms.

if (count < 10)
{
    count++;
}
else
{
    Function();
    count = 0;
}

I would like to implement a wrapper function to avoid rewriting the counter code for every different interval, i.e:

TimerWrapper(required interval 1, Function 1 pointer)
TimerWrapper(required interval 2, Function 2 pointer)

and call it on every tick of the timer. For this to work, each different function called by the wrapper needs to have a separate count variable that needs to persist between calls of TimerWrapper(). I would like to keep all of the implementation details separate from my main program and introduce as few variables into my main program as possible.

Is it possible to do what I am asking, or is there a simpler/better way to achieve the same effect? I know how I would do this with an object oriented language but my skills are lacking in plain C.

Upvotes: 0

Views: 88

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 754590

I would think in terms of a structure along the lines of:

struct interrupt_responder
{
    int count;
    int rep_count;
    void (*handler)(void);
};

You then create as many such structures as you have different counters, appropriately initialized:

static struct interrupt_responder c1 = { 0, 10, Function };

You arrange to call a function with the responder:

void time_wrapper(struct interrupt_responder *r)
{
    if (++r->count >= r->max_count)
    {
        r->count = 0;
        (*r->handler)();
    }
}

The function called in response to an interrupt then simply needs to know how to dispatch calls to time_wrapper with the appropriate argument each time.

void millisecond_interrupt_handler(void)
{
    time_wrapper(&c1);
    …
}

Or you can have an array of the interrupt responders, and the millisecond interrupt handler can loop over the array, calling the time wrapper function.

You would have a set of file scope variables for the interrupt responders, but they'd not need to be visible outside the file. If you need different argument lists for the handler functions, life is trickier — avoid that if you possibly can. However, it seems from a comment that it won't be a problem — the embedded functions pointers will always be void (*handler)(void).

Upvotes: 8

Related Questions