How do I obtain the address of Foo()

What is the arduino way of obtaining a function pointer? I want to pass a proceedure address to a function. the form and purpose is "job queue" for an ISR. While I could use switch case statements it would definitely not be extensible, nor polymorphic. The queue is so I can dynamically share process time with different functions of the overall machine. Time delgations would vary over the course of operation.

What is the arduino way of obtaining a function pointer?

The Arduino way IS the C way. The & operator returns the address of it's operand, whether that is a variable or a function.

Thanks Paul.
lptrProcb = &Foo()?
I presume then calling lptrProcb() will then be Foo()

lptrProcb = &Foo()?

Depends on how you define lptrProcb. Typically, when you pass a pointer to a function to a function, a typedef statement is used to define the prototype that the function needs to have (return type, arguments, etc.). The pointer type itself is void *.

Such as:
#define lptrProcB();
If like the Foo() and had no parameters or like the following if it has 2 long integers and a character array
#define lptrProcB(long,long,char[]);

ajofscott:
Such as:
#define lptrProcB();
If like the Foo() and had no parameters or like the following if it has 2 long integers and a character array
#define lptrProcB(long,long,char[]);

Macros aren't functions.

Can you lend me an example?

You can borrow this:

"polymorphic"? Sounds awesome but I failed to see why passing pointers to functions is related to it. I thought it is a property of OOP.

Also be careful defining functions that take pointers to functions as parameters. Arduino has some trouble making automatic declarations for them.

Polymorphic means it can have different purposes based on what it is sent as arguements.

ajofscott:
I want to pass a proceedure address to a function. the form and purpose is "job queue" for an ISR.

I'm not sure I would want to do pre-emptive multi-tasking on this processor.

Perhaps we should step back and ask why you want to do this?

I have various reciever tasks to perform and other telemetry tasks, the latter being of lesser priority than inbound control. My theory, not coded practice of yet, is to que low priority telemetry updates for when the majority of the basic 5 axises of flight control are more or less static. Option B is an outbound core and an inbound core that occasionally talk to each other.

I am a web language programmer, in an environment with abundant memory, who has done very little in C other than read its code on occasion and get a rough idea of what it is doing. Obeject references are handled quite differently in VB, especially on a Win32 system. For now I acknowledge I am ignorant in C, but I don't plan on remaining that way. I may ask seemingly annoying questions at times, my goal isn't to accelerate development of acid reflux on your part. I am really looking for a way to emulate a collection object so I can ieterate collected events rather than stopping immediately to process them through, as some events as I earlier indicated are of greater importance than others.

Here's an extracted sample where a function passes a time value and function pointer to a scheduling function:

typedef void (*fptr_t)(void);          /* Function pointer type               */

:
:

/*----------------------------------------------------------------------------*/
/* Log pressure, temperature, and counts at regular intervals (background)    */
/*----------------------------------------------------------------------------*/
void recd(void)
{  rec(NULL);                          /* Output a regular log entry          */
   while ((log_t += log_i) <= mst());  /* Determine next scheduled log time   */
   while (schd(log_t,recd)) idle();    /* Schedule next regular log entry     */
}

schd() saves the time and execution address in an ordered list element so that another function named dispatch() can invoke recd() at time log_t.

Here's a prototype for schd():

int schd(time_t when,fptr_t what);

And here is the entire dispatch function:

/*----------------------------------------------------------------------------*/
/* Execute all "ripe" pending events and recycle queue elements               */
/*----------------------------------------------------------------------------*/
void dispatch(void)
{  fptr_t what;                        /* Pointer to scheduled function       */
   event *e;                           /* Pointer to scheduled event element  */
   while ((e = pend) && (e->when <= mst()))  /* While there are ripe elts     */
   {  what = e->what;                  /* Get event execution address         */
      pend = e->next;                  /* Remove element from pending list    */
      e->next = idle;                  /* Link to 1st elt of idle list        */
      idle = e;                        /* Make this the new 1st idle element  */
      what();                          /* Execute the callback function       */
   }                                   /*  end: while ripe elements queued    */
}

Many thanks AlreayTaken, this is exactly what I want to do.

ajofscott:
I may ask seemingly annoying questions at times, my goal isn't to ...

They are not annoying. I'm just trying to help. :slight_smile:

I'm not sure why you need to store function addresses in an ISR. It seems simpler to me that, if an event occurs (there aren't that many that can on a microprocessor) you simply set a flag.

Then in the main loop, you check the flags (one per relevant event) in the order you choose (ie. the priority you wish) and call the relevant function.

Just setting a flag isn't always the best way to go (and can lead to flag-based spaghetti code nightmares!) For example, I'm doing periodic logging of pressure, temperature, and radiation counts at an interval that depends on operating context - while I'm concurrently doing sequenced opening and closing of valves where I want to allow time for one valve to close before I open another - while I may also be concurrently sending pulses to a stepper at different intervals - all whilst I'm watching sensors like a hawk to ensure I don't have a reactor runaway...

It turned out to be fairly easy to have the data logging function schedule itself for re-execution after the logging interval and then simply return control.

The same approach (and scheduler) is used with the stepper. Each step (except the last) schedules the next, and there's an added benefit of being able to use the scheduler to effect ramping (start stepping slowly so as to not undershoot (lose steps) and accelerate smoothly to max speed, then decelerate so as not to overshoot the stopping point).

The actual scheduling is only a matter of inserting an element containing execution time and function pointer into a list in execution-time order, so that the dispatcher only needs to compare the first element's execution time to the current time to determine if it has work to do. It's a simple, fast way to get the job done.

Function pointers are just another standard data type, and there's no reason not to use them when they make sense.

Very good, if that is required by the situation. My post on page 1 shows how you can use function pointers so I am not totally opposed to them.

I find that sometimes people try to find a complicated solution to a simple problem, so if possible I steer them towards a simpler solution, if that will fit their requirements. Sometimes it doesn't.

I try to have more than one avenue of escape, so showing me the other doors isn't a bad thing.

Can the dot notation and the port to notation (->) be used interchangably? Or does it require a different way of contructing the typedef statement? I am more accustomed to the dot notation to the point it is second nature. I know &Foo is a reference to Foo and that to access a member I would use a=foo.bar(elementofSuprise) assuming bar wanted elementofSuprise...humor laugh with me...

If foo is a class then you use dot to get to a class element.

eg.

myClass foo;
foo.bar = 42;

If foo is a pointer to a class then you use the "point to" notation.

eg.

myClass * foo = new myClass;
foo->bar = 42;