I am working on some code that impliments various features such as a PID controller, signal generator, etc.
My hardware provides various inputs and outputs. Just now I have a load of SWITCH statement to determine the source and destination of my calculations.
For example for the PID controller, there is a switch command every 100ms that decides which input to pass to the pid_calculate function, followed by another switch to decide what to do with the return value. As I have 32 analog inputs, as well as can, lin and serial as possible inputs, the switch statements are HUGE!
I would like to reference to, or a physical example of how something could be coded as a hardware independent (within the confines of the pic) function. I am sure that the answer lies with pointers, but I am new to C and not really sure where to begin with the pointers.
I envisage the function prototype being something like
int pid_init(*source,*destination)
Where the source is a pointer to the input, eg an ADC buffer, and the destination could be for example the pwm duty cycle register. Just now I have to switch each possible condition then load the data into the registers.
So to clarify, how would I impliment a function that allows it to be input and output independent, and how would I de-reference the pointers(assuming pointers are the correct way to do this)
I hope this makes sense, thanks in advance.
You can implement a kind of object oriented programming in C so long as you take a bit of care. In the ways that I have done it, I have used function pointers as well as structs with function pointers as members.
For instance to have a kind of data independence, you may have a function that like the quick sort (qsort) function is provided data long with a pointer to a function that operates on the data. Typically with this approach you end up using void pointers of various kinds to allow the use of pointers to any data type.
Another approach that I have used is to have what amounts to an abstract interface for the common operations that the various types of devices support and to then create a struct which provides a function pointer template for those operations. Then I will create an array of these structs and fill the array elements in by using function pointers to the particular function that implements that operation for a particular device.
For instance something like this very simple example is what I have used to provide a standard interface for several different devices. This interface hides the device differences by providing a standard interface.
At this point I can have a function that I call to obtain which of the devices I actually want to use. This function returns an index into the hardware list. So it might go something like this.
Or I might use a handle approach so that I would call a function which provides the handle to a device that is specified in some description which is passed to the function. Then any calls to my standard interface would specify the handle. Underneath, the handle is merely the index into the array of different devices.
And the function DeviceStdInput() would look like:
You will still need to implement the actual functions used for each of the devices however this provides a way to have a standard interface to several devices with common operations that you can then just use the standard interface within the rest of your code.
I have used this to provide a standard interface for output in which the output devices were a file, a printer, and a web service. The actual sink or output device was selected by the user. The code using the interface did not change. Adding more devices was pretty easy so long as the interface did not change. In some cases I would have devices that did not support a particular operation and that function would just return without doing anything.