【问题标题】:Why is this function called with no body before being declared, and what exactly is the '2' doing?为什么在声明之前没有主体调用此函数,“2”到底在做什么?
【发布时间】:2021-01-26 22:10:50
【问题描述】:
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
}

我正在修改一些代码以在 PIC18F47Q10 上以从机模式运行 I2C。
该代码是为另一个类似的 PIC 编写的,但确实需要一些调整。
这是原始代码:https://github.com/texane/pic18f_i2c

在定义之前我不明白调用,我也不明白“2”是什么意思。
这是来自原版中发布的int.c 文件。任何帮助或解释表示赞赏。
现在我正在评论所有这些,并希望没有它也能正常工作。

看到的错误是:

"unexpected token: __interrupt

Unable to resolve identifier on_low_interrupt."

"error: expected function body after function declarator"

【问题讨论】:

  • 这不是电话,而是声明。
  • 确定是的。好点子,我的错。所以 XC8 编译器确实识别 __interrupt() 但在用户指南中它只出现在 void 之后。我只是不清楚意图是什么,以及是否应该以某种方式更正或者是否有必要。抱歉,我的信息太少了,但我就是这样。
  • PJ 我很欣赏你的评论。我不能就这样消失两年。我正在做一些事情,我正在学习 C。我几年前开始的。如果不在这里,我还能在哪里“被允许”问这样的问题?
  • 顺便说一句,这不是 XC8 代码。
  • 它的意思是(一个糟糕的)编译器扩展,它告诉函数应该安装为中断 2 的中断处理程序,不管这意味着什么。 CPU 将在中断发生时调用该函数。如果您不知道这一点,那么现在是前往例如 the Wikipedia 文章的好时机。

标签: c interrupt pic i2c sdcc


【解决方案1】:

在“C”中需要区分函数声明和函数定义。

函数声明基本上告诉编译器某处存在具有特定名称、参数类型和结果类型的函数,因此编译器可以从类型安全的角度检查该函数的调用是否正确,并可以生成正确的函数调用代码。声明是可选的,并且可能会调用未声明的函数,从而使编译器猜测有关被调用函数的详细信息,但是现在这被认为是不好的做法,并且很可能会导致警告。

函数声明通常位于头文件 (.h) 中。在你的代码函数声明是:

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
}

同一个函数可以声明任意次数,但只能定义一次。

我相信,__interrupt 2 表示该函数是低级中断号 2 的处理程序。低级中断是一个事件,通常由硬件触发,程序可能想要做出反应。 __interrupt 关键字是非标准的,可能特定于您正在使用的编译器。也许以下链接是相关的:http://downloads.ti.com/docs/esd/SPRUI04/the---interrupt-keyword-stdz0559860.html

【讨论】:

  • 此文档链接根本不相关。不是这个编译器
【解决方案2】:

为什么这个函数在被声明之前没有函数体调用

void on_low_interrupt(void) __interrupt 2; 不是function call,这是on_low_interrupt function declaration。下面是on_low_interrupt function definition 及其正文。

“2”到底在做什么?

前导两个下划线的标识符是为实现保留的,通常由编译器实现者使用。因此,因为2 位于带有两个下划线__interrupt 的标识符之后,所以它很可能在执行特定于编译器的操作,其含义也是特定于编译器的。

一个很好的猜测是代码是为sdcc 编译器编写的。您可以在第 44 页的 3.1. General Information 部分中的 sdcc manual 中阅读:

__interrupt 关键字后面的可选数字是此例程将服务的中断号。

所以2 代表例程要服务的硬件中断号。究竟什么是“中断号 2”的解释取决于设备。在您链接的存储库中,有一个 18f4550.lkr 文件 - 很可能是 pic18f4550 的链接器脚本。 datasheet for the device 可以指导您进一步了解数字。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-23
    • 2019-06-14
    相关资源
    最近更新 更多