What does __attribute__((__interrupt__, no_auto_psv)) do?

落爺英雄遲暮 提交于 2021-02-06 06:28:01

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!