Modularizing Programs

Go To Last Post
17 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just read through the tutorial on modularizing C code, but there are a few things in my program not mentioned in the tutorial, nor can I find them specifically in "The C Programming Handbook".

I am trying to break my program apart by grouping functions perform certain operations within the program, for example the function which I use to control a gearbox are all in a source file called GearboxControl.c, all the functions that take in user inputs are in a source file called UserInputs.c etc...I also at this point have only a single header file as my program is big enough to break apart but not big enough to need multiple header files at the moment.

My problem is the following: the main while loop (Main.c) contains

while( 1 ){
	TriggerFlag = Fire( TriggerFlag );
	TriggerFlag = Stop_Firing( TriggerFlag );
	Run_Gearbox_Control( MagazineSize );
}

TriggerFlag and MagazineSize are defined within the scope of main (which of course main is located in the source file Main.c).

All function prototype declarations are located in Main.h

bool Fire( bool TriggerFlag );			
bool Stop_Firing( bool TriggerFlag );
void Run_Gearbox_Control( uint8_t MagazineSize );
uint8_t Set_Magazine_Size( uint8_t MagazineSize );
void Set_Motor_Speed(void);
void Run_In_Safe_Mode(void);
void Initialize(void);

The function definitions for Fire and Stop_Firing are located in GearboxControl.c, which has the proper include files for io, interrupts and main.h ect..

I am getting the following two errors:
../Main.h:45: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Fire'
../Main.h:46: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Stop_Firing'

What exactly is going on? At first I was thinking that I needed to declare Fire and Stop_Firing (GearboxControl.c) as extern because they are returning TriggerFlag which is defined within the scope of Main, but passed into and out of both functions. However MagazineSize is defined within the scope of main as well as passed into and out of Set_Magazine_Size(UserInputs.c) and there are no compile errors present with that functions.

The only difference is that TriggerFlag is called TF within the scope of Fire and Stop_Firing, which I don't think should make any difference since is pass by value. Thanks for you help in advance.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How is the definition of the variable TriggerFlag ?

It seems like it could be that one.

/Bingo

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
int main(){
....
....
/* Description:	Local Variables */
	bool TriggerFlag = true; 
	uint8_t MagazineSize=0;
....
....
   while( 1 ){
     .....
   }

   return 0;
}

TriggerFlag is defined within the scope of main, but used in Fire and Stop_Firing. I could move it to GearboxControl.c since only those two functions use it and both are in the same source file, however I should be able to pass it between the functions, so I am trying to figure out why I'm getting this error.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

is it because the c compiler doesn't know what a bool is?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BTW I also have two inline functions defined in Inline.c with their prototypes in Main.h and they are used in GearboxControl.c, but the compiler is giving me the following warnings(10 total, since that is in how many places they are used):
../Main.h:61: warning: inline function 'Stop_PWM1' declared but never defined
../Main.h:60: warning: inline function 'Start_PWM1' declared but never defined

What I don't understand is why it says they are not defined when they clearly are in Inline.h. Do I need to actually define them in Main.h like I do with #Define's that are used in more than one source file?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't think that is the issue, I have many boolean variables (which are used for flag bits) within various functions throughout, that is the only one to have any issues. Also the program works fine and without compile errors when everything was set up in a single source file.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ThEThInG wrote:
I don't think that is the issue, I have many boolean variables (which are used for flag bits) within various functions throughout, that is the only one to have any issues. Also the program works fine and without compile errors when everything was set up in a single source file.
No, lagger is correct; the C compiler >doesn't< know what a bool is (at least, not with the default "gnu99" compiler switch); that's a C++ feature. If you have modules that appear to allow "bool" as a datatype, it's only because they include some header file that defines it. And the module that provides main() apparently isn't pulling in that header.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

try pasting your entire header file here.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
/******************************************************************************
** Description:			Sensor definitions
******************************************************************************/
#define TRIGGER (PINC&_BV(PINC1))		
#define GEAR_SENSOR (PINC&_BV(PINC3))
#define BOLT_SENSOR (PINC&_BV(PINC4))
#define	BB_SENSOR (PINC&_BV(PINC5))	
#define	MAG_SENSOR (PINC&_BV(PINC2))
#define	MOTOR_ON (PINB&_BV(PINB1))
#define BRAKE_ON (PINB&_BV(PINB0))
#define	SW6	(PIND&_BV(PIND7))

	
/******************************************************************************
** Description:			Output Definitions
******************************************************************************/
#define TURN_ON_MOTOR PORTB |= (1<<PINB1);
#define TURN_OFF_MOTOR PORTB &= ~(1<<PINB1);
#define TURN_ON_BRAKE PORTB |= (1<<PINB0);
#define TURN_OFF_BRAKE PORTB &= ~(1<<PINB0);
#define TURN_ON_LED1 PORTD |= (1<<PIND0);
#define TURN_OFF_LED1 PORTD &= ~(1<<PIND0);
#define TURN_ON_LED2 PORTD |= (1<<PIND1);
#define TURN_OFF_LED2 PORTD &= ~(1<<PIND1);


/******************************************************************************
** Description:			Timer/PWM	Definitions
******************************************************************************/
#define	ENABLE_TIMER0_INT TIMSK0 |= (1 << OCIE0A);
#define	DISABLE_TIMER0_INT TIMSK0 &= ~(1 << OCIE0A);
#define	START_TIMER0 TCCR0B |= (1<<CS00);								/*(1<<CS02) |*/
#define	STOP_TIMER0 TCCR0B &= ~(1<<CS00);								/*(1<<CS02) &*/
#define CLEAR_TIMER0_INT_FLAGS TIFR0 &= ~((1<<OCF0B) & (1<<OCF0A));
#define TC0_PRESTART_DELAY 50											/* 10=1uS, 50=5uS */
#define TC0_SOFT_START_DURATION 100										/* 10=1uS, 100=10uS */


/******************************************************************************
** Description:			Function Prototypes
** Notes:				Fire and Stop_Firing functions are declared external
**						because they return a value which is defined in Main.c
******************************************************************************/
/* GearboxControl.c */
bool Fire( bool TriggerFlag );			
bool Stop_Firing( bool TriggerFlag );
void Run_Gearbox_Control( uint8_t MagazineSize );

/* UserInputs.c */
uint8_t Set_Magazine_Size( uint8_t MagazineSize );
void Set_Motor_Speed(void);

/* SafeMode.c */
void Run_In_Safe_Mode(void);

/* Initialize.c */
void Initialize(void);


/***********************************************************************************
** Function name: 	Start_PWM1
**
** Descriptions:	Responsible for performing operations to properly start PWM
** 					Fpwm = Fclock / 2*N*TOP, where TOP=number of bits, N=Clock Div
**
** Parameters:		None
** Returned value:	None
************************************************************************************/
inline void Start_PWM1(void){
	TCCR1A |= (1<<COM1A1);		/* set for non-inverted PWM */
	TCCR1B |= (1<<CS12); 		/* set Fpwm = 39.215kHz */	
}


/***********************************************************************************
** Function name: 	Initialize
**
** Descriptions:	Responsible for performing operations to properly stop PWM
** 					
** Parameters:		None
** Returned value:	None
************************************************************************************/
inline void Stop_PWM1(void){
	TCCR1B &= ~(1<<CS12);		/* clear clock select bits to stop PWM */
	TCCR1A &= ~(1<<COM1A1);		/* clear COM bits to restore control to PORTB */
	TURN_OFF_MOTOR;
}

I have #include in both source files, Main.c which calls the functions Fire and Stop_Firing and GearboxControl.c which defines the functions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
/******************************************************************************
** Description:			Sensor definitions
******************************************************************************/
#define TRIGGER (PINC&_BV(PINC1))		
#define GEAR_SENSOR (PINC&_BV(PINC3))
#define BOLT_SENSOR (PINC&_BV(PINC4))
#define	BB_SENSOR (PINC&_BV(PINC5))	
#define	MAG_SENSOR (PINC&_BV(PINC2))
#define	MOTOR_ON (PINB&_BV(PINB1))
#define BRAKE_ON (PINB&_BV(PINB0))
#define	SW6	(PIND&_BV(PIND7))

	
/******************************************************************************
** Description:			Output Definitions
******************************************************************************/
#define TURN_ON_MOTOR PORTB |= (1<<PINB1);
#define TURN_OFF_MOTOR PORTB &= ~(1<<PINB1);
#define TURN_ON_BRAKE PORTB |= (1<<PINB0);
#define TURN_OFF_BRAKE PORTB &= ~(1<<PINB0);
#define TURN_ON_LED1 PORTD |= (1<<PIND0);
#define TURN_OFF_LED1 PORTD &= ~(1<<PIND0);
#define TURN_ON_LED2 PORTD |= (1<<PIND1);
#define TURN_OFF_LED2 PORTD &= ~(1<<PIND1);


/******************************************************************************
** Description:			Timer/PWM	Definitions
******************************************************************************/
#define	ENABLE_TIMER0_INT TIMSK0 |= (1 << OCIE0A);
#define	DISABLE_TIMER0_INT TIMSK0 &= ~(1 << OCIE0A);
#define	START_TIMER0 TCCR0B |= (1<<CS00);								/*(1<<CS02) |*/
#define	STOP_TIMER0 TCCR0B &= ~(1<<CS00);								/*(1<<CS02) &*/
#define CLEAR_TIMER0_INT_FLAGS TIFR0 &= ~((1<<OCF0B) & (1<<OCF0A));
#define TC0_PRESTART_DELAY 50											/* 10=1uS, 50=5uS */
#define TC0_SOFT_START_DURATION 100										/* 10=1uS, 100=10uS */


/******************************************************************************
** Description:			Function Prototypes
** Notes:				Fire and Stop_Firing functions are declared external
**						because they return a value which is defined in Main.c
******************************************************************************/
/* GearboxControl.c */
bool Fire( bool TriggerFlag );			
bool Stop_Firing( bool TriggerFlag );
void Run_Gearbox_Control( uint8_t MagazineSize );

/* UserInputs.c */
uint8_t Set_Magazine_Size( uint8_t MagazineSize );
void Set_Motor_Speed(void);

/* SafeMode.c */
void Run_In_Safe_Mode(void);

/* Initialize.c */
void Initialize(void);


/***********************************************************************************
** Function name: 	Start_PWM1
**
** Descriptions:	Responsible for performing operations to properly start PWM
** 					Fpwm = Fclock / 2*N*TOP, where TOP=number of bits, N=Clock Div
**
** Parameters:		None
** Returned value:	None
************************************************************************************/
inline void Start_PWM1(void){
	TCCR1A |= (1<<COM1A1);		/* set for non-inverted PWM */
	TCCR1B |= (1<<CS12); 		/* set Fpwm = 39.215kHz */	
}


/***********************************************************************************
** Function name: 	Initialize
**
** Descriptions:	Responsible for performing operations to properly stop PWM
** 					
** Parameters:		None
** Returned value:	None
************************************************************************************/
inline void Stop_PWM1(void){
	TCCR1B &= ~(1<<CS12);		/* clear clock select bits to stop PWM */
	TCCR1A &= ~(1<<COM1A1);		/* clear COM bits to restore control to PORTB */
	TURN_OFF_MOTOR;
}

I have #include in both source files, Main.c which calls the functions Fire and Stop_Firing and GearboxControl.c which defines the functions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BTW I seem to have fixed the issue with the inline functions by defining them in Main.h as with the #define's.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you include your header before , at the moment of compilation of those two lines the compiler doesn't know what is bool (provided that bool is defined in stdbool.h - I don't know, I don't care).

Mind, #include is only a literal inclusion performed by the preprocessor, and the compiler works then on that "merged" result.

Besides, the standard boolean type in C99 is _Bool

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Or just try adding to the problem files.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That must not be the problem, I just looked at the code and I have the header file stdbool included in the relevant source files and it is before Main.h

Any other ideas?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Without spending any time analyzing the code, I just pasted in the entirety of the CODE block from your last post into a blank AStudio GCC project, added an "#include " and the "#include " file you say you're using at the top, and the result compiled without error.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can't see anything wring with the header file itself, but the problem lies with the header file used in conjunction with GearboxControl.c and Main.c. I'll have to take a closer look and see if I can see anything going on in there, if not I'll post both those source files on here. Perhaps something strange is going on with my install of studio.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Or you have a "non visible" character in the source , that gcc doesn't like.

I once had that , and searched for a long time.

Then i rewrote that paragraph , and all was fine.

/Bingo