Связать событие с устройством-источником прерывания
#include <sys/neutrino.h>int InterruptAttachEvent( int intr,const struct sigevent *event,unsigned flags );int InterruptAttachEvent_r( int intr,const struct sigevent *event,unsigned flags );
libc
The InterruptAttachEvent() and InterruptAttachEvent_r() kernel calls attach the given event to the hardware interrupt specified by intr. They automatically enable (i.e unmask) the interrupt level.
The InterruptAttachEvent() and InterruptAttachEvent_r() functions are identical except in the way they indicate errors.
Before calling either of these functions, the thread must request I/O privileges by calling:
ThreadCtl( _NTO_TCTL_IO, 0 );
If the thread doesn't do this, it might SIGSEGV
when it calls InterruptAttachEvent() or InterruptAttachEvent_r().
To prevent infinite interrupt recursion, the kernel automatically does an InterruptMask() for intr when delivering the event. After the interrupt-handling thread has dealt with the event, it must call InterruptUnmask() to reenable the interrupt.
Consider the following when choosing an event type:
SIGEV_PULSE
to trigger a channel.
SIGEV_INTR
as the event notification type and InterruptWait() as the blocking call.
SIGEV_SIGNAL
, SIGEV_SIGNAL_CODE
, or SIGEV_SIGNAL_THREAD
is discouraged. It is less efficient than the other mechanisms for interrupt event delivery. On a multicore system, the thread that receives the event set up by InterruptAttachEvent() runs on any CPU, limited only by the scheduler and the runmask.
Flags
The flags argument is a bitwise OR of the following values, or 0
:
Put the new event at the end of the list of existing events instead of the start.
The interrupt structure allows hardware interrupts to be shared. For example if two processes call InterruptAttachEvent() for the same physical interrupt, both events are sent consecutively. When an event attaches, it's placed in front of any existing events for that interrupt and is delivered first. You can change this behavior by setting the _NTO_INTR_FLAGS_END
flag in the flags argument. This adds the event at the end of any existing events.
Associate the event with the process instead of the attaching thread.
Adding _NTO_INTR_FLAGS_PROCESS
to flags associates the interrupt event with the process instead of the attaching thread. The interrupt event is removed when the process exits, instead of when the attaching thread exits.
![]() | The kernel automatically attempts to set the _NTO_INTR_FLAGS_PROCESS flag if the event is directed at the process in general (for SIGEV_SIGNAL , SIGEV_SIGNAL_CODE , and SIGEV_PULSE events). |
Track calls to InterruptMask() and InterruptUnmask() to make detaching the interrupt handler safer.
The _NTO_INTR_FLAGS_TRK_MSK
flag and the id argument to InterruptMask() and InterruptUnmask() let the kernel track the number of times a particular interrupt handler or event has been masked. Then, when an application detaches from the interrupt, the kernel can perform the proper number of unmasks to ensure that the interrupt functions normally. This is important for shared interrupt levels.
![]() | You should always set _NTO_INTR_FLAGS_TRK_MSK . |
Advantages & disadvantages
InterruptAttachEvent() has several advantages over InterruptAttach():
There are also some disadvantages:
You can freely mix calls to InterruptAttach() and InterruptAttachEvent() for a particular interrupt.
This call doesn't block.
-1
, код ошибки записывается в errno.Use the ID with InterruptDetach() to detach this interrupt event.
ЗОСРВ «Нейтрино»
InterruptAttach(), InterruptDetach(), InterruptLock(), InterruptMask(), InterruptUnlock(), InterruptUnmask(), InterruptWait(), struct sigevent
Предыдущий раздел: Описание API системной библиотеки