my project is almost working but i get 1
Warning:
"implicit declaration of function 'init_phase_correct' [-Wimplicit-function-declaration]"
have have the function called in my main
int main(void)
{
volatile char start_flag=0;
uart0_Init ( MYUBRRF );
DDRB |=(1<<PB7);
sei(); //enable global interrupt
initAdc();
data = 'a';
ADCSRA |=(1<<ADIE);
init_phase_correct();
and init_phase_correct is included i the top in
#include "PWM.h"
that links to
/*
* IncFile1.h
*
* Created: 23-04-2015 11:30:38
* Author: Martin Egsdal
*/
#ifndef INCFILE1_H_
#define INCFILE1_H_
extern void init_fastPWM();
extern void init_phase_correct();
extern void init_ph_frPWM();
extern void init_phase_correct_alt();
#endif /* INCFILE1_H_ */
and in the C file it is:
void init_phase_correct(){
TCCR0A|=(1<<COM0A1)|(1<<WGM00); //Clear OC0A on Compare Match when up-counting. Set OC0A on Compare Match when down-counting
TCCR0B =(1<<CS01); //prescalling by 8
OCR0A =102; //40 duty cycle
TCNT0= 0;
DDRB |= (1<<DDB7);// configure OC0A pin for output
}
when i rightclick init_phase_correct() in my main i can see the 2 implentations - so why is it "Wimplicit-function-declaration"?
I see, that your header file, which contains declaration of init_phase_correct() is wrapped with include guard with some auto-generated name (INCFILE1_H_).
Also, you did not specify, whether init_phase_correct() is declared inside PWM.h or maybe another file, that is included by PWM.h.
Without more code, I cannot say for sure, but my clairvoyance skill tells me, that INCFILE1_H_ may be used as include guard in another file - either PWM.h itself or another, that is being included before file, that contains declaration of init_phase_correct().
Related
I am using STM32F103 and and Keil for the Compiler. Here is my summary code:
There is a header file like abc.h and abc file has a static variable. abc.h is like that:
static uint8 a;
And there is a function in another header file which named abcd.h and that changes the a' s value.
abcd.h header file is like that.
include "abc.h"
void foo()
{
a = 0x0A;
}
My issue is that:
When I call the "foo" fuction in main "a" is turn to zero even if I assign the "a" variable to 0x0A in "foo()" function. By the way, If I define the "a" variable with extern and the problem does not occured. I mean "a" is get 0x0A value.
Is there anyone the help me why does this problem occur.
Some rules of thumb:
Never declare global variables. (extern ones)
Never declare variables inside header files.
static variables are per definition not global, but could be "file scope" - that is, visible to the file they are declared inside. Or more accurately, visible inside the translation unit they are declared inside, a translation unit meaning a specific .c file and all the headers that .c file includes.
So if you declare a static variable in a header, which is included by two different .c files, then you end up with multiple local copies of the variable. If you are lucky, you get a linker error, but the linker may as well attempt some internal "name mangling". The very meaning of static is to prevent access to the variable by other files.
The best solution to this is to use setter/getter functions:
// abc.h
#ifndef ABC_H // always use "header guards"
#define ABC_H
uint8_t get_a (void);
void set_a (uint8_t n);
#endif
-
// abc.c
#include "abc.h"
static uint8_t a;
uint8_t get_a (void)
{
return a;
}
void set_a (uint8_t n)
{
a = n;
}
That is how you should be doing in the vast majority of cases. Using extern should be avoided, but for the rare cases when you have to use it, then use it like this:
// abc.h
#ifndef ABC_H // always use "header guards"
#define ABC_H
extern uint8_t a;
#endif
-
// abc.c
#include "abc.h"
uint8_t a;
It seems that my compiler does not willing to build the firmware in stepper_motor.c and as you can see below, it throws this error, which I am unable to solve.
I have created a stepper_motor.c source where all my functions and variables are placed, and a stepper_motor.h header where all the #defines and function prototypes are. In main.c I just include the stepper_motor.h header and use the functions. As you can see from shell log data, it does not compile and tells that 4 x variables are defined multiple times. Those ones are used in ISR() routine for a timer, so they need to be also volatile.
Any information would be highly appreciated on this issue.
this is my main.c includes: --------
#include <avr/io.h>
#include <Hardware_Bay.h>
#include <util/delay.h>
#include <USART.h>
#include <string.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdbool.h>
#include <avr/interrupt.h>
#include <scale16.h>
#include <stepper_motor.h>
const uint8_t motor_Phases[] = {
(1 << COIL_B1), // full step
(1 << COIL_B1) | (1 << COIL_A2), // half step
(1 << COIL_A2), // full step
(1 << COIL_A2) | (1 << COIL_B2), // half step
(1 << COIL_B2), // full step
(1 << COIL_B2) | (1 << COIL_A1), // etc..
(1 << COIL_A1),
(1 << COIL_A1) | (1 << COIL_B1),
};
volatile uint8_t stepPhase = 0;
volatile uint16_t stepCounter = 0;
volatile int8_t direction = FORWARD;
ISR(TIMER0_COMPA_vect) { // Timer/Counter-0 Compare match interrupt vector enable
stepPhase += direction; // take step in right direction
stepPhase &= 0b00000111; // keep the stepPhase in range (0 - 7)
STEPPER_PORT = motor_Phases[stepPhase]; // write phase out to motor COIL-1 A/B
HALL_PORT = motor_Phases[stepPhase]; // write phase out to motor COIL-2 A/B
stepCounter ++;
}
------------------------------header file -----------------------------------------------
#ifndef STEPPER_MOTOR_H_INCLUDED
#define STEPPER_MOTOR_H_INCLUDED
#endif // STEPPER_MOTOR_H_INCLUDED
#define FORWARD 1
#define BACKWARD -1
#define TURN 200
#define MAX_DELAY 255
#define MIN_DELAY 10
#define ACCELERATION 16
#define RAMP_STEPS (MAX_DELAY - MIN_DELAY) / ACCELERATION
void stepperDrive(uint8_t number_of_steps, uint8_t delay);
void trapezoidDrive_Stepper(int16_t number_of_steps);
PS D:\Users\Arhitect\Documents\C_Programs\Physalis_Banshee\Physalis_GEO_version_3.6> make flash
avr-gcc -Wl,-Map,Physalis_GEO_version_3.6.map -Wl,--gc-sections -mmcu=atmega1284p fuse.o main.o stepper_motor.o USART.o -o Physalis_GEO_version_3.6.elf
stepper_motor.o: In function `stepperDrive':
D:\Users\Arhitect\Documents\C_Programs\Physalis_Banshee\Physalis_GEO_version_3.6/stepper_motor.c:50: multiple definition of `stepCounter'
main.o:(.bss.stepCounter+0x0): first defined here
stepper_motor.o:(.data.direction+0x0): multiple definition of `direction'
main.o:(.data.direction+0x0): first defined here
stepper_motor.o:(.rodata.motor_Phases+0x0): multiple definition of `motor_Phases'
main.o:(.rodata.motor_Phases+0x0): first defined here
stepper_motor.o: In function `stepperDrive':
D:\Users\Arhitect\Documents\C_Programs\Physalis_Banshee\Physalis_GEO_version_3.6/stepper_motor.c:50: multiple definition of `stepPhase'
main.o:(.bss.stepPhase+0x0): first defined here
make: *** [Physalis_GEO_version_3.6.elf] Error 1
PS D:\Users\Arhitect\Documents\C_Programs\Physalis_Banshee\Physalis_GEO_version_3.6>
Really the error messages tell you all you need to know - you have defined these symbols in two places - main.c and setpper_motor.c.
You have defined stepCounter at line 50 of stepper_motor.c and also as shown in main.c. Similarly for stepPase and motor_Phases.
If they are independent and should not be visible externally then
both should be declared static so that they are visible only in
their respective translation units.
If it is intended that the symbol refers to the they are the same object, then one of them needs to be declared extern to indicate to the compiler its type and name, but that it is defined elsewhere..
If they are independent but "need" to be global (because you cannot
think of a better solution), then they cannot have the same name.
If you do not reference them in main.c, then they should in any event be removed from there. It seems odd that you would define them here when they clearly relate to stepper motor control and should probably be encapsulated in stepper_motor.c.
Avoiding the use of globals in the fist place is a much better solution see https://www.embedded.com/a-pox-on-globals/
I have headers in my microcontroller program
#ifndef __IRQ_HANDLER__
#define __IRQ_HANDLER__
#ifdef __cplusplus
volatile tU32 ticks = 0; // <- with that variable i have problem
extern "C" {
#endif
void interrupt2(void);
#ifdef __cplusplus
}
#endif
#endif //__IRQ_HANDLER__
Then file.c
#include <lpc2xxx.h>
#include "interrupt.h"
void interrupt2(void) {
ticks++;
T1IR = 0xff;
VICVectAddr = 0x00;
}
Every time when i'm trying to use variable ticks. I got an error :
'ticks' undeclared ( first use in this function ).
Have you any clue what might be wrong ?
Greetings !
Note: in the following code example, I stripped all the unrelated statements
1) do not declare variables in a header file. if necessary, use the 'extern' modifier in the header file.
2) Declare the variable in a source file, like main.c
3) any symbol name beginning with underscore+capital letter Or two underscores are 'reserved' for the system. Therefore strongly suggest replacing all instances of __IRQ_HANDLER__ with the (typical) INTERRUPT_H
an example code:
file: interrupt.h
#ifndef INTERRUPT_H
#define INTERRUPT_H
#ifdef __cplusplus
extern "C" {
#endif
extern volatile unsigned int ticks;
void interrupt2(void);
#ifdef __cplusplus
}
#endif
#endif // INTERRUPT_H
file: interruptHandler.c
#include "interrupt.h"
volatile unsigned int ticks = 0;
void interrupt2(void)
{
ticks++;
}
There needs to be a third file that declares the variable: ticks
and if declared in the file global space,
it will automatically be initialized to 0
It is necessary to also treat the code in the third file that accesses the ticks variable as a 'critical section. Probably by:
disable the interrupts
copying ticks to a local variable
enable the interrupts
I'm aware of the declaration of C header files with #ifdef and the meaning of extern before variables and functions. But recently I've got a third party library for an embedded device with the following scheme:
/* "lib.h" */
#ifndef LIB_H_
#define LIB_H_
#ifdef LIB_C
void function1();
/* ... */
#else
extern void function1();
/* ... */
#endif
#endif /* LIB_H_ */
And additionally I've got a corresponding C source file:
/* lib.c */
#define LIB_C
#include "lib.h"
void function1()
{
/* ... */
}
/* ... */
So here I am and a bit confused. What is the reason to declare all functions twice in the header in this way?
It's either an affectation, or a compatibility hack for some non-conforming or ancient compiler. You don't need the extern version, but using it is also fine, because function declarations are extern by default.
In other words, it's cruft, but maybe someone needs that cruft. We can't know for sure.
From linux kernel code
struct gpio_desc {
struct gpio_chip *chip;
unsigned long flags;
/* flag symbols are bit numbers */
#define FLAG_REQUESTED 0
#define FLAG_IS_OUT 1
#define FLAG_EXPORT 2 /* protected by sysfs_lock */
#define FLAG_SYSFS 3 /* exported via /sys/class/gpio/control */
#define FLAG_ACTIVE_LOW 6 /* value has active low */
#define FLAG_OPEN_DRAIN 7 /* Gpio is open drain type */
#define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */
#define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */
#define FLAG_IS_HOGGED 11 /* GPIO is hogged */
/* Connection label */
const char *label;
/* Name of the GPIO */
const char *name;
};
what is the reason to place defines into the body of structure?
With #define it doesn't matter too much where you put them (so long as it is higher up in the file than where it is first used). Most likely those constants are used only within that structure, so it was put there so logically they would be easier to find. They could have been put anywhere above the first place they were used, but they were grouped together because of similar purpose.
It's meaningless, other than to try and define them close to the point of first use.
By the time the compiler actually sees the code, the preprocessor will have stripped those lines out of it.
In this particular example, they would be better off with a typedef'd enum for the flags and using that enum to declare the field.
There is no impact.
But in the example, for readability sake they maintained/added near to the variable declared.
They want use those "#define" for the variable "unsigned long flags;".
Below is simple example and proves no impact on the class/struct by declaring the "#Define" inside.
//gcc 4.9.3
#include <stdio.h>
struct gpio_desc {
#define FLAG_REQUESTED 0
} test;
int main()
{
printf("%d",FLAG_REQUESTED);
}
The out put is zero.