4
void __attribute__((__interrupt__, no_auto_psv)) _T1Interrupt(void) // 5 Hz

__attribute__指令或宏来自 GCC,但不是,它特定于硬件__interrupt__no_auto_psv那么,GCC 编译器如何理解__interrupt__no_auoto_psv,我搜索并没有在其他任何地方找到任何声明。

所以基本上这个_T1Interrupt函数没有参数并且什么都不返回但具有上述属性?

4

3 回答 3

4

特别是,这些属性是用于 16 位 PIC24 和 dsPIC 的 Microchip XC16 编译器中特定于平台的扩展。

属性本质上是添加到编译器解析树的额外信息。它们存在于 C 语言语义之外,用于提供编译器用来与您的期望保持一致的附加信息。在这种情况下__interrupt__,告诉它将函数视为 ISR(函数 prolog 和 epilog 与普通函数略有不同:dsPIC ISR 使用RETFIE返回指令,而不是RETURN普通函数),并no_auto_psv控制编译器是否设置PSVPAG寄存器:

no_auto_psv 属性的使用省略了将 PSVPAG 值重新初始化为 auto psv 变量(const 或放置在空间 auto_psv 中的变量)的默认值的代码。如果您的代码没有显式修改 PSVPAG 寄存器或使用编译器管理的psvprog限定符,则使用 no_auto_psv 是安全的。此外,如果您的中断服务程序(或中断服务程序调用的函数)不使用任何 const 或空格 auto_psv 变量,那么使用 no_auto_psv 是安全的。

(来自http://www.microchip.com/forums/m394382.aspx

于 2015-04-08T17:51:14.700 回答
2

的文档__attribute__()说:

GCC 插件可以提供自己的属性。

所以也许这就是它在你的情况下的使用方式。

于 2013-06-24T14:25:50.833 回答
1

unwind 说的是真的,属性由 gcc 的 MPLAB 扩展定义。自从我使用微控制器已经有一段时间了,所以我无法提供这方面的更多细节。但是对于您的特定应用程序(在 pic 微控制器上嵌入 c)。以上是声明一个函数的正确方法,该函数旨在实现定时器 1 的中断子程序。中断子程序很少返回任何内容,如果您需要捕获寄存器中的值,我建议您使用以下结构作为全局变量:

typedef struct T1OUT
{
    int timer_register_value;
    int flag;

} T1InteruptCapture;

timer_register_value 是您想要从子例程中取出的值。而标志值是内存锁,可防止子例程覆盖您以前的值。有不同的方法可以从子程序中获取值。我发现这是最简单和最省时的。您还可以考虑实现一个迷你缓冲区。我建议您避免使用嵌入式 C 的指针。我不知道在过去几年中情况是否发生了变化。

编辑 1:MPLAB 有一些我见过的最好的文档。我建议您查看适用于您特定微控制器的那个。他们提供了带有很好解释的示例代码。

编辑 2:我不确定你为什么使用 gcc。我建议您从 MPLAB 获取 pic 编译器。我相信它被称为C30。以及相关的 .h 文件。

于 2013-06-24T16:14:01.283 回答