I'm receiving the undefined symbols error on XC8 for two struct arrays declared as externs in file io.h. Why is this happening?
#ifndef _IO_H_ #define _IO_H_
#include <pic16f872.h> #include <string.h> #include "../var.h" #define DEBOUNCE_LOW 50000 #define DEBOUNCE_HIGH 50000 #define DEBOUNCE_HOLD 4000000 #define TOTAL_INPUTS 3 typedef struct { unsigned char press : 1; unsigned char hold : 1; } Input; typedef struct { unsigned int low; unsigned int high; unsigned long hold; } Debounce; extern Input input[TOTAL_INPUTS]; //<== The variables declaration extern Debounce debounce[TOTAL_INPUTS]; // <== #define BT_UP input[0] #define BT_DOWN input[1] #define BT_UP_PIN PORTCbits.RC1 #define BT_DOWN_PIN PORTCbits.RC3 #define LED1 PORTBbits.RB1 #define LED2 PORTBbits.RB2 void setupIo( void ); void initIo( void ); void resetIo( char input ); void taskIo( void ); void readIo( void ); void writeIo( void ); #endif // _IO_H_
and the io.c:
#include "io.h"; void initIo( void ){ for( int in = 0; in < TOTAL_INPUTS; in++ ){ input[in].hold = false; input[in].press = false; resetIo( in ); } }
void resetIo( unsigned char input){
debounce[input].low = DEBOUNCE_LOW;
debounce[input].high = DEBOUNCE_HIGH;
debounce[input].hold = DEBOUNCE_HOLD;
}void taskIo( void ){
if( !BT_UP_PIN ){ //botão up pressionado if( debounce[0].low > 0) debounce[0].low--; if( !debounce[0].low ){ if( debounce[0].hold > 0 ) debounce[0].hold--; if( !debounce[0].hold){ input[0].hold = true; } } } else if( !debounce[0].low ){ // botão solto if( debounce[0].high > 0) debounce[0].high--; if( !debounce[0].high ){ input[0].press = true; resetIo( 0 ); } } if( !BT_DOWN_PIN ){ //botão up pressionado if( debounce[1].low > 0) debounce[1].low--; if( !debounce[1].low ){ if( debounce[0].hold > 0 ) debounce[0].hold--; if( !debounce[1].hold){ input[1].hold = true; } } } else if( !debounce[1].low ){ // botão solto if( debounce[1].high > 0) debounce[1].high--; if( !debounce[1].high ){ input[1].press = true; resetIo( 1 ); } }
}
compiler error:
CLEAN SUCCESSFUL (total time: 125ms) make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf make1: Entering directory 'C:/Users/User/Google Drive/Desenvolvimento/Projetos/Microchip/Fonte Chaveada/FonteChaveada.X' make -f nbproject/Makefile-default.mk dist/default/production/FonteChaveada.X.production.hex make2: Entering directory 'C:/Users/User/Google Drive/Desenvolvimento/Projetos/Microchip/Fonte Chaveada/FonteChaveada.X' "C:\Program Files (x86)\Microchip\xc8\v1.41\bin\xc8.exe" --pass1 --chip=16F872 -Q -G --double=24 --float=24 --opt=+asm,+asmfile,-speed,+space,-debug,-local --addrqual=ignore --mode=free -P -N255 --warn=0 --asmlist -DXPRJ_default=default --summary=default,-psect,-class,+mem,-hex,-file --output=default,-inhx032 --runtime=default,+clear,+init,-keep,-no_startup,+osccal,-resetbits,-download,-stackcall,+clib --output=-mcof,+elf:multilocs --stack=compiled:auto:auto "--errformat=%f:%l: error: (%n) %s" "--warnformat=%f:%l: warning: (%n) %s" "--msgformat=%f:%l: advisory: (%n) %s" -obuild/default/production/main.p1 main.c "C:\Program Files (x86)\Microchip\xc8\v1.41\bin\xc8.exe" --pass1 --chip=16F872 -Q -G --double=24 --float=24 --opt=+asm,+asmfile,-speed,+space,-debug,-local --addrqual=ignore --mode=free -P -N255 --warn=0 --asmlist -DXPRJ_default=default --summary=default,-psect,-class,+mem,-hex,-file --output=default,-inhx032 --runtime=default,+clear,+init,-keep,-no_startup,+osccal,-resetbits,-download,-stackcall,+clib --output=-mcof,+elf:multilocs --stack=compiled:auto:auto "--errformat=%f:%l: error: (%n) %s" "--warnformat=%f:%l: warning: (%n) %s" "--msgformat=%f:%l: advisory: (%n) %s" -obuild/default/production/drivers/io/io.p1 drivers/io/io.c hw_config.h:22: warning: (162) #warning: "Sistema configurado como DEBUG!" "C:\Program Files (x86)\Microchip\xc8\v1.41\bin\xc8.exe" --chip=16F872 -G -mdist/default/production/FonteChaveada.X.production.map --double=24 --float=24 --opt=+asm,+asmfile,-speed,+space,-debug,-local --addrqual=ignore --mode=free -P -N255 --warn=0 --asmlist -DXPRJ_default=default --summary=default,-psect,-class,+mem,-hex,-file --output=default,-inhx032 --runtime=default,+clear,+init,-keep,-no_startup,+osccal,-resetbits,-download,-stackcall,+clib --output=-mcof,+elf:multilocs --stack=compiled:auto:auto "--errformat=%f:%l: error: (%n) %s" "--warnformat=%f:%l: warning: (%n) %s" "--msgformat=%f:%l: advisory: (%n) %s" --memorysummary dist/default/production/memoryfile.xml -odist/default/production/FonteChaveada.X.production.elf build/default/production/main.p1 build/default/production/drivers/io/io.p1
Microchip MPLAB XC8 C Compiler (Free Mode) V1.41 Build date: Jan 24 2017 Part Support Version: 1.41 Copyright (C) 2017 Microchip Technology Inc. License type: Node Configuration:: warning: (1273) Omniscient Code Generation not available in Free mode main.c:88: warning: (764) mismatched comparison :0: error: (500) undefined symbols: _debounce(dist/default/production\FonteChaveada.X.production.obj) _input(dist/default/production\FonteChaveada.X.production.obj) (908) exit status = 1 nbproject/Makefile-default.mk:141: recipe for target 'dist/default/production/FonteChaveada.X.production.hex' failed make2: Leaving directory 'C:/Users/User/Google Drive/Desenvolvimento/Projetos/Microchip/Fonte Chaveada/FonteChaveada.X' nbproject/Makefile-default.mk:84: recipe for target '.build-conf' failed make1: Leaving directory 'C:/Users/User/Google Drive/Desenvolvimento/Projetos/Microchip/Fonte Chaveada/FonteChaveada.X' nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed make2: * [dist/default/production/FonteChaveada.X.production.hex] Error 1 make1: * [.build-conf] Error 2 make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 1s)
and my main.c file as well:
#include "hw_config.h";
/=====================================================================================\
======= INTERRUPÇÔES =========
*=====================================================================================*/void interrupt interruptFuction( void ){
if( INTCONbits.T0IF ){
INTCONbits.T0IF = 0;return; } if( PIR1bits.TMR2IF ){ PIR1bits.TMR2IF = 0; return; }
}
void main( void ){
int pwm = 0; initHw(); while( true ){ LED1 = ~LED1; taskIo(); if( BT_UP.press ){ // input.press if( pwm < PWM_MAX ) pwm++; CCPR1L = (char) pwm; CCPR1H = pwm >> 8; LED2 = ~LED2; } if( BT_DOWN.press ){ if( pwm >= 1 ) pwm--; CCPR1L = (char) pwm; CCPR1H = pwm >> 8; LED2 = ~LED2; } } //end while
} //end main
void initHw( void ){
/=====================================================================================\
======= SETUP SFFRs =========
*=====================================================================================/
ADCON0 = 0b00000000; // Desalibilita pull-ups ou ADC não lembro
ADCON1 = 0b00000111;
OPTION_REG = 0b10000011;
INTCON = 0b10100000; //Habilita interrupções
// T1CON = 0b10000000; //Habilita e configura Timer 1
PIE1 = 0b00000110; // Habilita CCPIE e TMR2IE inerrupts para PWM
T2CON = 0b00000100; //Habilita e configura Timer 2 (1:1)
PR2 = 5;
/ Para PWM é utilizável somente o preScaler (bits 1-0):
* 00= 1:1;
* 01=1:4;
* 1x=1:16;
*/
CCP1CON = 0b00001111; //Habilita PWM
CCPR1H = 0b0000000; //Ciclo alto do Duty do PWM
CCPR1L = 0b00000000; //Ciclo baixo do Duty do PWM/*-------------------------------------------------------------------------- * Limpeza dos SFRs. *-------------------------------------------------------------------------*/ TMR0 = 0; TMR2 = 0; /*-------------------------------------------------------------------------- * Limpeza dos PORTS e LATS. *-------------------------------------------------------------------------*/ PORTA = 0; PORTB = 0; PORTC = 0; /*-------------------------------------------------------------------------- * Configuração da direção dos pinos de I/O's. *-------------------------------------------------------------------------*/ // 76543210 TRISA = 0b11111111; //entrada TRISB = 0b11111001; //saída TRISC = 0b00001010; //saída
}
I've tried to mark de Xc8 Linker option buts its not enabled for this device.
Best Answer
There's a difference between declaring a variable and defining it. You've declared that
debounce[]
andinput[]
exist somewhere else by using theextern
keyword, but you've not actually defined them anywhere (at least that we can see from the code provided).To simply fix the error, you can define the arrays in your io.c file. But as far as I can tell,
debounce[]
andinput[]
are not used anywhere else in your program, so there's no need to expose them in the header file (i.e. define them in the io.c file and remove theextern
declarations from the io.h file).