Why is this function called with no body before being declared, and what exactly is the '2' doing?

132 views Asked by At
void on_low_interrupt(void) __interrupt 2;    

void on_low_interrupt(void) __interrupt 2
{
#ifdef CONFIG_ENABLE_I2C
  i2c_handle_interrupt();
#endif

#ifdef CONFIG_ENABLE_SERIAL
  serial_handle_interrupt();
#endif
}

I'm adapting some code to run I2C in slave mode on a PIC18F47Q10.
The code was written for another similar PIC but it does need some adapting.
This is the original code: https://github.com/texane/pic18f_i2c

I don't understand the call before being defined, I also don't get what the '2' is meant to do.
This is from the int.c file posted in the original. Any help or explanation is appreciated.
For now I'm commenting all of this out and hoping it works without it.

The errors seen are:

"unexpected token: __interrupt

Unable to resolve identifier on_low_interrupt."

"error: expected function body after function declarator"
2

There are 2 answers

0
KamilCuk On BEST ANSWER

Why is this function called with no body before being declared

The void on_low_interrupt(void) __interrupt 2; is no function call, this is the on_low_interrupt function declaration. Below is found the on_low_interrupt function definition with it's body.

and what exactly is the '2' doing?

Identifiers with leading two underscores are reserved for implementations and are usually used by compilers implementators. So because the 2 is after an identifier with two underscores __interrupt it is most probably doing something compiler specific and it's meaning is also compiler specific.

A good guess would be that the code was written for sdcc compiler. You may read on page 44 in section 3.1. General Information in sdcc manual that:

The optional number following the __interrupt keyword is the interrupt number this routine will service.

So the 2 represents the hardware interrupt number the routine is meant to service. The interpretation of what exactly is "interrupt number 2" is dependent on the device. In the repository you linked, there's a 18f4550.lkr file - most probably a linker script for pic18f4550. The datasheet for the device may guide you further on your quest on understanding the number.

1
Mikhail Vladimirov On

In "C" one needs to distinguish function declaration and function definition.

Function declaration basically tells the compiler that a function with certain name, parameter types, and result type exists somewhere, so the compiler may check whether invocations of this function are correct from type-safety point of view, and can generate proper function calling code. Declaration is optional, and one may call undeclared functions, thus making the compiler to guess details about the function being called, however this is considered bad practice nowadays and would most probably lead to a warning.

Function declarations usually reside in header (.h) files. In your code function declaration is:

void on_low_interrupt(void) __interrupt 2;

Function definition tells compiler what function actually does, i.e. contains the code of the function. In your code function definition is:

void on_low_interrupt(void) __interrupt 2
{
#ifdef CONFIG_ENABLE_I2C
  i2c_handle_interrupt();
#endif

#ifdef CONFIG_ENABLE_SERIAL
  serial_handle_interrupt();
#endif
}

The same function can be declared arbitrary number of times, but can be defined only once.

I believe, that __interrupt 2 means that the function is a handler for low-level interrupt number 2. Low-level interrupt is an event, usually triggered by hardware, a program may want to react. The __interrupt keyword is non-standard and probably specific to the compiler you are using. Maybe the following link is relevant: http://downloads.ti.com/docs/esd/SPRUI04/the---interrupt-keyword-stdz0559860.html