Creating Circular Buffer lib

I've done this type of thing many times in embedded environments over the past few decades.
The thing to think about is what information needs to be in the Q.
For example, rather than have a token to indicate the function, it could be a pointer to the actual function.
Then does the function need any sort of context argument?
i.e. maybe you want to call the same function with some sort of context or instance information.

I finally ended up using function pointers and a void pointer as an argument to the function for each Q entry.
I also used a "magic" function pointer of -1 to indicate that the argument is a pointer to
an integer that should be increment rather being an argument to a function to be called.
There are some interesting things you can do with the mechanism especially if there is a timer/timeout
mechanism that uses the same Qs. (It allows easy timeout processing in foreground routines).

The thing to really weigh in the AVR environment is the trade off between RAM usage and flash usage
and the realtime needs of processing the Q.
For example, if the number of different functions to call is quite large and the Q contains a token,
then not only does it consume extra code but it can take additional time to do the translation
if a lookup table is not used. However, on the AVR if you use a lookup table, that consumes RAM by default.
RAM is quite precious on the AVR chips.
If you convert it to use PROGMEM instead, then it no longer uses RAM for the lookup but takes longer to perform the lookup.

If you don't use a token and use function pointers, then each entry needs 2 bytes per function pointer vs 1
when it is token. However, the processing time to get an entry from the Q and call the function will be
much shorter.
But if you have lots of entries in the Q, then the RAM use can be an issue.

It all comes down to trade-offs. What works "best" is really just a compromise that fits best into the
environment.

As far is getting the Q'ing code up and debugged. I'd write it and debug in on a bigger machine.
i.e. PC/MAC Unix/Linux machine where there are good debug tools. If the code is all in C it can be made
to be 100% portable and you will spend very little time (if any) having to fight logic/coding issues in the
Arduino environment (which has very limited debugging tools).

--- bill