2014-01-24 23 views
3

標準C(ANSI/ISO)中是否存在服務硬件中斷的方法?到目前爲止,我所見過的所有實現都使用編譯器特定的語言擴展或預處理器指令。可以在標準C中處理中斷嗎?

我剛剛遇到標準C庫的'信號'功能,但維基百科對它的使用非常輕,我不認爲它符合這個目的。

+2

中斷處理基本上是平臺特定的。 C標準不是。不能用純粹的標準C. – Mat

回答

3

信號(來自POSIX)不是用於處理硬件中斷,儘管它們可以被連接到它們。它們用於處理更高級別的系統事件。

您必須執行一些操作,比如您所看到的實現,以及您希望支持的每個硬件平臺的特定代碼。

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芯片的中斷處理程序(assumming它的存在,並且在硬件激活)

... 
... 
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代碼偏離標準,那麼你將需要使用一些彙編器來調用你的函數。

相關問題