我们知道我们为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 execution
和starts 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吗?
答案 0 :(得分:4)
主要不知道。你必须在你的设置代码中执行一些系统相关的功能(可能在main中),用硬件中断例程/向量等来注册中断处理程序。
中断代码是否可以直接执行C函数变化很大;中断过程的运行时约定并不总是遵循应用程序代码的运行时约定。通常,从中断例程到C代码的信号有一些间接性。
答案 1 :(得分:3)
你的疑问:我理解你的答案。但我想知道中断何时发生当前任务执行如何停止/暂停以及ISR是否开始执行?
好Rashmi回答你的问题,如下所示,
当微控制器检测到中断时,它会在执行当前指令后停止执行程序。然后它将PC(程序计数器)推到堆栈并加载具有该中断的向量位置的PC,因此,程序流被引导到中断服务程序。在完成ISR后,微控制器再次从堆栈中弹出存储的程序计数器并将其加载到PC上,因此,程序执行将从下一个停止的位置再次恢复。 这回复了你的问题吗?
答案 2 :(得分:1)
在大多数嵌入式系统中,硬件具有一些特定的存储器地址,当硬件条件指示需要中断时,指令指针将移动到该地址。
当指令指针位于此特定位置时,它将开始在那里执行代码。
在很多系统中,程序员只会在这个位置放置一个ISR地址,这样当中断发生并且指令指针移动到特定位置时,它将跳转到ISR
尝试在“中断矢量化”上进行Google搜索
答案 3 :(得分:1)
这取决于你的目标。
例如,ATMEL mega系列使用预处理器指令向ISR注册中断向量。发生中断时,相关状态寄存器中会出现相应的中断标志。如果引发全局中断标志,则在调用ISR之前,程序计数器将存储在堆栈中。这一切都发生在硬件中,主要功能一无所知。
为了让main知道是否发生了中断,您需要在中断例程和主函数之间实现共享数据资源,并且RTOS编程的所有规则都适用于此处。这意味着由于ISR可能在任何时候执行,因此从主服务器读取共享资源是不安全的,而不首先禁用中断。
在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应该非常短并且执行速度非常快。
答案 4 :(得分:1)
中断处理对于正在运行的程序是透明的。处理器根据事件自动分支到先前配置的地址,并且该地址是相应的ISR功能。从中断返回时,一条特殊指令恢复被中断的程序。
实际上,大部分时间你都不会想要程序中断,知道它已经被打断了。如果您需要知道这些信息,程序应该调用驱动程序函数。
答案 5 :(得分:1)
中断是硬件而不是软件。当中断信号命中处理器时,处理器(通常)完成当前指令。在某种程度上,形状或形式保留了状态(因此它可以回到原来的位置),并且在某种程度上,形状或形式开始执行中断服务程序。 isr通常不是C代码,至少入口点通常是特殊的,因为处理器不符合编译器的调用约定。 ISR可能会调用C代码,但您最终会犯下您所犯的错误,使得像printf这样的调用不应该在ISR中。在C中努力避免尝试在isr中编写通用C代码,而不是典型的get in和get out类型的东西。
理想情况下,您的应用程序层代码永远不会知道发生的中断,应该没有(基于硬件)残留影响您的程序。您可以选择为应用程序保留一些内容,使其看起来像计数器或其他需要标记为易失性的共享数据,以便应用程序和isr可以共享它。这种情况通常只是标记中断发生并且应用程序轮询该标志/计数器/变量并且处理主要发生在应用程序而非isr中,这种情况并不少见。这样,应用程序可以进行任何系统调用。只要满足整体带宽或性能,这可以而且确实可以作为解决方案。
答案 6 :(得分:1)
软件不识别特定的中断,它是微处理器(INTC)或微控制器JOB。
中断例程调用就像Main()的正常函数调用一样,唯一的区别是main不知道该例程何时被调用。
每个中断都有特定的优先级和向量地址。一旦接收到中间输入(软件或硬件),根据中断优先级,掩码值和程序流被转移到与该中断相关的特定向量位置。
希望它有所帮助。