1

正如我们所知,我们编写Embedded C程序是为了task management, memory management, ISR, File system一切。
我想知道如果一些task or process is running和同时是一个interrupt occurred,那么how SW or process or system comes to know that, the interrupt has occurred?pauses当前的task executionstarts serving ISR

假设我会写下面的代码:

// Dummy Code
void main()
{
    for(;;)
        printf("\n forever");
}

// Dummy code for ISR for understanding
void ISR()
{
    printf("\n Interrupt occurred"); 
}

在上面的代码中,如果一个external interrupt(ISR) occurs,那么如何main()知道中断发生了?所以它会首先开始为 ISR 服务?

4

7 回答 7

4

主要不知道。您必须在设置代码(可能在主代码中)中执行一些与系统相关的函数,该函数将中断处理程序注册到硬件中断例程/向量等。

中断代码是否可以直接执行 C 函数变化很大;中断过程的运行时约定并不总是遵循应用程序代码的运行时约定。通常,从中断例程获取信号到您的 C 代码会涉及到一些间接问题。

于 2012-06-12T12:27:03.877 回答
3

您的问题:我理解您的回答。但我想知道何时发生中断当前任务执行如何停止/暂停以及 ISR 开始执行?

以及 Rashmi 来回答您在下面阅读的查询,

当微控制器检测到中断时,在执行当前指令后停止程序的执行。然后它将PC(程序计数器)压入堆栈并用该中断的向量位置加载PC,因此,程序流被引导到中断服务程序。完成 ISR 后,微控制器再次从堆栈中弹出存储的程序计数器并将其加载到 PC 上,因此程序执行再次从下一个停止位置恢复。这是否回复了您的查询?

于 2012-06-14T06:43:54.593 回答
2

这取决于你的目标。

例如,ATMEL mega 系列使用预处理器指令向中断向量注册 ISR。当发生中断时,相应的中断标志会在相关状态寄存器中产生。如果产生全局中断标志,则程序计数器在调用 ISR 之前存储在堆栈中。这一切都发生在硬件中,主要功能对此一无所知。

为了让 main 知道是否发生了中断,您需要在中断例程和 main 函数之间实现共享数据资源,并且 RTOS 编程中的所有规则都适用于此。这意味着由于 ISR 可以随时执行,因此从 main 读取共享资源而不首先禁用中断是不安全的。

在 ATMEL 目标上,这可能如下所示:

volatile int shared;

int main() {
  char status_register;
  int buffer;
  while(1) {
    status_register = SREG;
    CLI();
    buffer = shared;
    SREG = status_register;
    // perform some action on the shared resource here.
  }
  return 0;
}

void ISR(void) {
  // update shared resource here.
}

请注意,此处未将 ISR 添加到向量表中。检查您的编译器文档以获取有关如何执行此操作的说明。

此外,要记住的重要一点是 ISR 应该非常短且执行速度非常快。

于 2012-06-12T13:04:54.473 回答
1

在大多数嵌入式系统上,硬件都有一些特定的内存地址,当硬件条件指示需要中断时,指令指针将移动到该地址。

当指令指针位于该特定位置时,它将开始执行那里的代码。

在许多系统上,程序员只会在这个位置放置一个 ISR 的地址,这样当中断发生并且指令指针移动到特定位置时,它就会跳转到 ISR

尝试在“中断向量”上进行谷歌搜索

于 2012-06-12T12:59:33.943 回答
1

中断处理对于正在运行的程序是透明的。处理器会根据事件自动跳转到先前配置的地址,该地址是相应的 ISR 功能。当从中断返回时,一条特殊指令恢复被中断的程序。

实际上,大多数情况下,您永远不会希望程序被中断知道它已被中断。如果您需要了解此类信息,程序应改为调用驱动程序函数。

于 2012-06-12T13:28:02.817 回答
1

中断是硬件而不是软件。当中断信号到达处理器时,处理器(通常)完成当前指令。以某种方式 shape 或 form 保留了状态(因此它可以回到原来的位置),并且以某种方式 shape 或 form 开始执行中断服务程序。isr 通常不是 C 代码,至少入口点通常是特殊的,因为处理器不符合编译器的调用约定。ISR 可能会调用 C 代码,但您最终会犯下您所犯的错误,调用 printf 之类的调用不应该在 ISR 中。在 C 中很难避免尝试在 isr 中编写通用 C 代码,而不是典型的进出类型的东西。

理想情况下,您的应用程序层代码不应该知道中断发生,不应该有(基于硬件的)残差影响您的程序。您可以选择为应用程序留下一些东西,例如计数器或其他需要标记为易失性的共享数据,以便应用程序和 isr 可以共享它。让 isr 简单地标记发生中断并且应用程序轮询该标记/计数器/变量并且处理主要发生在应用程序而不是 isr 中,这种情况并不少见。这样,应用程序可以进行任何它想要的系统调用。只要满足整体带宽或性能,这可以并且确实可以作为解决方案。

于 2012-06-12T20:38:39.970 回答
1

软件无法识别具体的中断,它是微处理器 (INTC) 或微控制器 JOB。

中断例程调用就像对 Main() 的正常函数调用一样,唯一的区别是 main 不知道何时调用该例程。

每个中断都有特定的优先级和向量地址。一旦接收到中断(软件或硬件),根据中断优先级、屏蔽值和程序流被转移到与该中断相关的特定向量位置。

希望能帮助到你。

于 2012-06-13T06:07:44.167 回答