ptoni2000 - 2008-04-10

Hi, i have a project on a pic18f4620 with some interrupt functions,
most of them with declaration and function in main.c, one in a separate c file.

The problem is: when i declare the interrupt with the macro:

    DEF_HANDLER(SIG_INT0, _int0_handler)

on the main.c and the function with:

    SIGHANDLER(_int0_handler)

on the ir_in.c file the compiler give me the message:

    tv_main.asm:234:Error [113] Symbol not previously defined (__int0_handler).

The only solution i have found is adding to main.c before the DEF_...END_DEF declarations the two lines:

    SIGHANDLER(_int0_handler);
    volatile void (* dummy)()= _int0_handler;

The first one is the prototipe declaration for the interrupt function present in ir_in.c, the second line is an assignement to a dummy function pointer.
This is a waste of 3 bytes on the dummy() declaration but make the compiler happy.

This is the right solution or there is a better one?

This is a compilable demo code for testing this:

====== main.c ======

#include <pic18fregs.h>
#include <usart.h>
#include <stdbool.h>
#include <signal.h>

SIGHANDLER(_int0_handler);
//volatile void (* dummy)()= _int0_handler;

/* interrupts handlers */
DEF_INTHIGH(high_int)            /* interrupt dispatch table for high priority interrupts */
DEF_HANDLER(SIG_TMR2, _tmr2_handler)    /* define a handler for the timer2 */
DEF_HANDLER(SIG_RC,   _rx_handler)    /* define a handler for serial rx */
DEF_HANDLER(SIG_INT0, _int0_handler)    /* define a handler for external int 0 */
DEF_HANDLER(SIG_INT1, _int1_handler)    /* define a handler for external int 1 */
DEF_HANDLER(SIG_INT2, _int2_handler)    /* define a handler for external int 2 */
END_DEF                    /* end the declaration of the dispatch table. */

SIGHANDLER(_tmr2_handler)
{
    PIR1bits.TMR2IF = 0;    /* Clear timer interrupt flag */
}

SIGHANDLER(_rx_handler)
{
    char c;

    c = usart_getc();
}

SIGHANDLER(_int2_handler)
{
    INTCON3bits.INT2IF = 0;
}

SIGHANDLER(_int1_handler)
{
    INTCON3bits.INT1IF = 0;
}

void main (void)
{
    // Main loop, neverending...
    while (true)
    {

    }
}

====== ir_in.c ======

#include <pic18fregs.h>
#include <signal.h>

SIGHANDLER(_int0_handler)
{
    INTCONbits.INT0IF = 0;    // clear interrupt flag
}

====== Makefile ======

# Makefile for compilation w sdcc
PIC=18f4620
SDCC=sdcc
GPASM=gpasm
GPLINK=gplink

INCLUDE=-I. -I/usr/share/sdcc/include/pic16
LDFLAGS=-m -w -I/usr/share/sdcc/lib/pic16 -c -s /usr/share/gputils/lkr/$(PIC).lkr
#CFLAGS=-V -S
CFLAGS= -S

# startup code with initialisation
LIBS=crt0i.o libsdcc.lib libc18f.lib pic$(PIC).lib libio$(PIC).lib

PROCESSOR_FLAGS=-mpic16 -p$(PIC)

SOURCES= ir_in.c tv_main.c
PROJECT=tv_driver.hex

OBJS = $(SOURCES:.c=.o)

all: $(PROJECT)

%.o: %.c
    $(SDCC) $(INCLUDE) $(PROCESSOR_FLAGS) $(CFLAGS) $<
    $(GPASM) -c $*.asm

$(PROJECT): $(OBJS)
    $(GPLINK) $(LDFLAGS) -o $(PROJECT) $(OBJS) $(LIBS)

clean:
    rm -f *.cof *.adb *.asm *.cod *.lst *.hex *.p *.d *.lnk *.map *.o *~