问题
void __attribute__((__interrupt__, no_auto_psv)) _T1Interrupt(void) // 5 Hz
__attribute__
directive or macro is from GCC but __interrupt__
and no_auto_psv
is not , it's specific to a hardware. So, how does GCC Compiler understand __interrupt__
and no_auoto_psv
, I searched and didn't find any declaration in anywhere else.
So basically the _T1Interrupt
function takes no argument and return nothing but has the above attribute?
回答1:
In particular, these attributes are platform-specific extensions used in the Microchip XC16 compiler for 16-bit PIC24 and dsPICs.
Attributes are essentially extra information added to the parse tree of a compiler. They exist outside the C language semantics and are there to provide additional information that the compiler uses to act consistently with your expectations. In this case __interrupt__
tells it to treat the function as an ISR (with slightly different function prolog and epilog than a normal function: dsPIC ISRs use the RETFIE
return instruction, vs. RETURN
for normal functions), and no_auto_psv
controls whether the compiler sets the PSVPAG
register:
The use of the no_auto_psv attribute omits code that will re-initialize the PSVPAG value to the default for auto psv variables (const or those placed into space auto_psv). If your code does not modify the PSVPAG register either explicitly or using the compiler managed psv or prog qualifiers then the use of no_auto_psv is safe. Also, if your interrupt service routine (or functions called by your interrupt service routine) does not use any const or space auto_psv variables, then it is safe to use no_auto_psv.
(from http://www.microchip.com/forums/m394382.aspx)
回答2:
The documentation for __attribute__() says:
GCC plugins may provide their own attributes.
So perhaps that's how it's being used in your situation.
回答3:
What unwind said is true and the attritbutes are defined by the MPLAB extension for gcc. It's been a while since i've worked with microcontrollers so i can't provide more details on this front. However for your specific application (embedded c on pic micro-controller). The above is the proper way of declaring a function that is meant to implement an interrupt subroutine for timer 1. Interrupt subroutines rarely return anything, If you need to capture the value in the register i recommend you use the following structure as a global variable:
typedef struct T1OUT
{
int timer_register_value;
int flag;
} T1InteruptCapture;
The timer_register_value is the value you want out of your subroutine. While the flag value is memory lock that prevents the subroutine from over-writing your previous value. There are different ways of getting values out of your subroutine. I found this to be the easiest and the most time efficient. You can also look into implementing a mini-buffer. I recommend you avoid pointer with embedded C. I don't know if things have changed, in the last couple of years.
edit 1: MPLAB has some of the best documentation i've ever seen. I recommend you have a look at the one for your specific microcontroller. They provide sample code with great explanations.
edit 2: I not sure why you're using gcc. I would recommend you get the pic compiler from MPLAB. I believe it was called C30. and the associated .h file.
来源:https://stackoverflow.com/questions/17277822/what-does-attribute-interrupt-no-auto-psv-do