Adithya
Adithya

Reputation: 43

error: 'type name' declared as function returning a function

I'm developing a small library for a PID controller using avr-gcc.In spite of declaring the function in the header file and defining it separately in a .c file the compiler is throwing the following errors:

Compiling C: pid.c
avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -                 
funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-  
adhlns=./pid.lst  -std=gnu99 -MMD -MP -MF .dep/pid.o.d pid.c -o pid.o 
pid.c:5: error: expected declaration specifiers or '...' before '(' token
pid.c:5: warning: function declaration isn't a prototype
pid.c:5: error: 'type name' declared as function returning a function
pid.c:5: error: conflicting types for 'PID_init'
pid.h:23: error: previous declaration of 'PID_init' was here
pid.c: In function 'PID_init':
pid.c:5: error: parameter name omitted

The header file contents of pid.h are as follows:

#include<avr/io.h>
#include<util/delay.h>

#ifndef PID_CONTROLLER
#define PID_CONTROLLER
struct PIDCONTROL

{

float error;
float prev_error;
float Kp;
float Ki;
float Kd;                       
float pid;
float P;
float I;
float D;
float setpoint;

};

void PID_init(float,float,float,float,struct PIDCONTROL*);

float PID(float,struct PIDCONTROL*);                        

#endif

The definitions for the declared functions have been made in pid.c which contains the code shown below:

#include<avr/io.h>
#include<util/delay.h>
#include "pid.h"

void PID_init(float SP,float Kp,float Ki,float Kd,struct PIDCONTROL *a)

{

a->Kp=Kp;

a->Ki=Ki;

a->Kd=Kd;

a->pid=0;

a->setpoint=SP;

a->prev_error=0;

}


float PID(float PV,struct PIDCONTROL *a)

{

a->error=(a->setpoint)-PV;

a->P=(a->Kp)*(a->error);

(a->I)+=(a->Ki)*(a->error)*1.024;

a->D=(a->Kd)*((a->error)-(a->prev_error))/1.024;

a->pid=(a->P)+(a->I)+(a->D);

a->prev_error=a->error;

return(a->pid);

}

I couldn't just figure out what's wrong with the code. Any help is appreciated.Thanks in advance.

Upvotes: 1

Views: 2313

Answers (1)

paxdiablo
paxdiablo

Reputation: 881633

The avr/io.h file also brings in avr/common.h which contains this little snippet:

/*
    Stack pointer register.
        AVR architecture 1 has no RAM, thus no stack pointer.
        All other architectures do have a stack pointer. Some devices have only
            less than 256 bytes of possible RAM locations (128 Bytes of SRAM
            and no option for external RAM), thus SPH is officially "reserved"
            for them.
*/

# ifndef SP
    # define SP _SFR_MEM16(0x3D)
# endif

(it's actually a bit more complicated than that, with multiple paths depending on your architecture, but that cut down example shows what the actual problem is, at least).

It's actually defining a pre-processor macro for SP which means, when you attempt to use that in your code with a function definition along the lines of:

void PID_init(float SP,float Kp,float Ki,float Kd,struct PIDCONTROL *a)

what you'll actually get is something like:

void PID_init(float _SFR_MEM16(0x3D),float Kp,float Ki,float Kd,struct PIDCONTROL *a)

which will cause the compiler phase to complain bitterly.

I'm actually a big believer in reasonably self-describing variable names so would generally choose something more verbose than SP but you'll probably find that, even if you make it mySP, it'll fix the immediate problem.

Upvotes: 2

Related Questions