Question

Is there a method of servicing hardware interrupts in standard C (ANSI/ISO)? All the implementations Ive seen so far either use compiler specific language extensions or pre-processor directives.

I just came across the standard C library 'signals' feature, but wikipedia is very light on its use and I dont think it serves the purpose.

Was it helpful?

Solution 3

At some point your implementation will have to interface with some standard outside of the C spec, whether that's Linux's family of types and function signatures that define interrupt handlers, a similar body of C code built up for another operating system, or maybe the hardware spec for an embedded platform that would allow you to implement your own. If you can clarify your goal, it might be possible to give a more specific answer.

OTHER TIPS

POSIX signals can allow a user program written in C to catch and handle some types of interrupts and/or exceptions. It's the most standard approach I know about.

#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);
}

For hardware interrupts, C has no explicit semantics, mainly because it is not needed. For example, a Linux device driver can install its own interrupt handler for a hardware device. All you need is to call request_irq() function with the address of the function that will be in charge of handling the interrupt.

For example, this will install an interrupt handler for the RTC chip (assumming it's present and activated in your hardware)

...
...
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");
}
...
...

Your handler is just a regular C function:

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 */
}

This is possible (to use a regular C function to handle a hardware interrupt) because the handler itself is called from another kernel function, that has taken care of preserving the current context so the interrupted process won't notice anything. If you are dealing with interrupts in a "naked" computer and you want to keep your C code from deviating from the standard, then you will need to use some assembler to call your function.

No.

Signals (from POSIX) aren't for handling hardware interrupts, though they can be connected to them. They're for handling higher level system events.

You'll have to do something like the implementations you've seen, with specific code for each hardware platform you want to support.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top