是否有一种在标准C(ANSI / ISO)中维护硬件中断的方法?到目前为止,我见过的所有实现都使用编译器特定的语言扩展或预处理器指令。
我刚刚遇到了标准的C库'信号'功能,但维基百科对它的使用非常清楚,我认为它没有达到目的。
答案 0 :(得分:5)
POSIX信号可以允许用C编写的用户程序捕获和处理某些类型的中断和/或异常。这是我所知道的最标准的方法。
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
int a,b,*p;
jmp_buf jump_destination;
void exception_handler (int sg)
{
printf ("Error dereferencing pointer\n");
p=&b; /* pointer quick fix. */
longjmp(jump_destination,1); /* long GOTO... */
}
void main (void)
{
int i;
signal (SIGSEGV, exception_handler);
b=0; p=NULL;
setjmp(jump_destination); /* ...to this position */
printf ("Trying to dereference pointer p with value %08.8X... ",p);
printf ("After dereferencing pointer, its value is: %d\n", *p);
}
对于硬件中断,C没有明确的语义,主要是因为它不需要。例如,Linux设备驱动程序可以为硬件设备安装自己的中断处理程序。您所需要的只是使用将负责处理中断的函数的地址调用request_irq()
函数。
例如,这将为RTC芯片安装一个中断处理程序(假设它存在并在您的硬件中激活)
...
...
res=request_irq (8, /* que IRQ queremos */
interrupt_handler, /* address of handler */
IRQF_DISABLED, /* this is not a shared IRQ */
“mydriver", /* to be shown at /proc/interrupts */
NULL);
if (res!=0)
{
printk ("Can't request IRQ 8\n");
}
...
...
你的处理程序只是一个常规的C函数:
static irqreturn_t gestor_interrupcion (int irq, void *dev_id, struct pt_regs *regs)
{
/* do stuff with your device, like read time or whatever */
...
...
...
return IRQ_HANDLED; /* notify the kernel we have handled this interrupt */
}
这是可能的(使用常规C函数来处理硬件中断),因为处理程序本身是从另一个内核函数调用的,它负责保留当前上下文,因此被中断的进程不会注意到任何内容。如果您正在处理“裸”计算机中的中断并且您希望保持C代码不偏离标准,那么您将需要使用一些汇编程序来调用您的函数。
答案 1 :(得分:3)
没有
信号(来自POSIX)不是用于处理硬件中断,尽管它们可以连接到它们。它们用于处理更高级别的系统事件。
您需要执行类似于您所见过的实现,并为每个要支持的硬件平台提供特定代码。
答案 2 :(得分:1)
在某些时候,您的实现必须与C规范之外的某些标准接口,无论是Linux's family of types and function signatures that define interrupt handlers,为另一个操作系统构建的类似C代码体,还是嵌入式的硬件规范allow you to implement your own的平台。如果您可以澄清您的目标,则可以提供更具体的答案。