How can i start to write an interrupt for device drivers?

0x2024 is the right vector to attach to.

The “Out of interrupt events” message normally means that your interrupt source is constantly asserting.

Looking at your interrupt handler I see a few weird things. For one thing, you are masking the interrupt within your interrupt handler. The interrupt level is already masked upon
entry to the interrupt service routine, and will unmask afterwards, so there is no need for you to do additional masking, unless you want the interrupt to remain masked after the
completion of the ISR.

Note that if you do not acknowledge the source of the interrupt sufficiently (and here I must profess to know nothing about how CAN is implemented on the SH 7770) then it will
interrupt again immediately after unmasking the interrupt level, and you will spin forever in your interrupt handler. Since you are returning events then the kernel will eventually
complain that it can no longer allocate an event entry to deliver to your device driver.

Hope that helps a bit…

Dear cburgess,
thanks your answer,
It mean is in my interrupt handler , i will not use InterruptMask and InterruptUnMask

const struct sigevent *
_hcan2_irq_ser(void *arg, int iid)
{
hcan2_dev_t *dev=(hcan2_dev_t *)arg;
struct sigevent *event = NULL;

event = &dev->intr_event;    

// InterruptMask(dev->irq,dev->iid);

/* handler */

switch (dev->mode){
case CMODE_TRANSMIT:	
	...........			
	atomic_set(&dev->status, HCAN_STATUS_DONE); 

// InterruptUnmask(dev->irq,dev->iid);
return (event);
break;
case CMODE_RECEIVE:

atomic_set(&dev->status, HCAN_STATUS_DONE);
// InterruptUnmask(dev->irq,dev->iid);
return (event);
break;
default:
atomic_set(&dev->status, HCAN_STATUS_DONE);
// InterruptUnmask(dev->irq,dev->iid);
return (event);
}
// InterruptUnmask(dev->irq,dev->iid);

return (event);

}

is it Ok?
thanks ,
tuyndie

Yes, as long as whatever you are doing to read the message is clearing the cause of the interrupt.

And I might add, unless dev points to some control memory, and unless setting dev->status to HCAN_STATUS_DONE, it doesn’t look like the interrupt is being cleared.

Dear cburgess and maschoen,

i repaired my code here which create a new thread :
//////////
int main(int argc, char *argv[]) {

SIGEV_INTR_INIT(&dev->intr_event);

pthread_create(NULL, NULL, int_thread, NULL);

InterruptDetach(dev->iid);
free(dev);
}
////////////
void *int_thread(void *arg)
{
int errvalue;
int timeout;
uint64_t cycle_mark;

struct sigaction    sa;
//interrupts will generate IRQ
dev->hcanp->imr=0x0000;		
printf("In interrupt thread: Attaching the interrupt\n"); 	
//Enable I/O privilege
ThreadCtl(_NTO_TCTL_IO, NULL); 	
ThreadCtl(_NTO_TCTL_RUNMASK, (void*) 0x01); 
setprio(0, 63); 
InterruptEnable();

errno = EOK;
SIGEV_INTR_INIT(&dev->intr_event);	
//Attach the ISR to IRQ	
//interrupt attatch 
dev->iid = InterruptAttach(dev->irq, (void*) _hcan2_irq_ser, &dev,sizeof(dev), 0);
if(dev->iid==-1)
{ 
	printf( "Couldn't attach dev->irq %d\n", dev->irq ); 
	exit(-1);
} 
errvalue = errno;
printf( "The error generated was %d\n", errvalue );
printf( "That means: %s\n", strerror( errvalue ) );

sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGTERM);
sa.sa_handler = exit_signal;
sa.sa_flags = 0;
sigaction(SIGTERM, &sa, NULL);

procmgr_daemon(0, PROCMGR_DAEMON_NOCLOSE);

printf("wait\n"); 
while(1 ) 
{ 
	// Reenable this interrupt 		
	timeout=InterruptWait( 0, NULL ); 
	if (timeout == -1 )
	{ 
		printf( "Time Out\n" ); 
		exit(-1) ;
	}

	cycle_mark = ClockCycles(); 
	cycle_mark = ClockCycles() - cycle_mark; 
} 

}
///////////////
const struct sigevent *
_hcan2_irq_ser(void *arg, int iid)
{
//the same as upon
}
/////////////
when i ran finishing the driver device CAN and type in terminal :

pidin irqs
229390 2 guyen1176179929640
9 0x2024 0 — @0x8043f20:0x804690c

it is successful about driver device.
but when i run application to call that driver
and driver run here:

timeout=InterruptWait( 0, NULL );

and stop .
i don’t know why driver can not run to function
const struct sigevent *
_hcan2_irq_ser(void *arg, int iid)
{

}
can you help me?
thanks ,
tuyndie

I’m not sure why you created another thread - and you appear to be Attaching/Detaching the interrupt handler in the main thread too?
SIGEV_INTR is delivered to the thread that attached the interrupt - so if you mess things up there you will never be woken up.