Доброго времени знатокам драйверописателям и не только.
Возможно-ли в Linux использовать отслеживание асинхронных событий от некоего девайса, которые не являются событиями от read()/write()?
Допустим, есть некое у-во, от которого мне нужно ловить некоторые события изменения его состояния, грубо - моргание светодиодика. Но мне это нужно делать не поллингом, а в event-based режиме.
В оффтопике я для этих целей могу сделать так:
// получаем хендл у-ва
HANDLE hDevice = ::CreateFile(..., FILE_FLAG_OVERLAPPED);
// создаем событие
OVERLAPPED ov = {0};
ov.hEvent = CreateEvent(...);
// переменная, которая отражает состояние LED
DWORD ledState = 0;
// запускаю отслеживание евента о смене состояния LED
::DeviceIOControl(
hDevice,
LED_TRIGGERED_NOTIFY_ON,
NULL,
0,
&ledState,
sizeof(ledState),
NULL,
&ov
);
// где-то жду когда событие произойдет.
::WaitForSingleObject(
ov.hEvent,
INFINITE
);
// если оно произошло, то сбрасываю евент и
// получаю состояние LED
::GetOverlappedResult(
hDevice,
&ov,
&NumberOfBytesTransferred,
FALSE
);
// ledState теперь содержит текущее состояние LED у-ва
DWORD newLedState = ledState;
А как сделать подобное в Linux?
// получаю дескриптор у-ва
int fd = ::open();
// делаю ioctl
::ioctl(fd, LED_TRIGGERED_NOTIFY_ON, <но что сюда совать?? >)
// Жду события, но непонятно какой дескриптор сюда
// писать.. По идее нужен не дескриптор у-ва fd,
// а какой-то дескриптор события, но где его взять?
::select(<какой сюда дескриптор нужен???>)
Есть ли какие-то мысли по этому поводу?
Может быть, в ioctl() передавать некую пользовательскую структуру, типа:
//
typedef struct {
int efd; // дескриптор события, но как его создать?
int ledState; // состояние LED
} led_state_t;
led_state_t ls = {0};
ls.efd = <надо как-то что-то создать??>
::ioсtl(fd, LED_TRIGGERED_NOTIFY_ON, &ls);
::select(ls.efd, ...);
// если дождались, то
int newLedState = ls.ledState;
Подскажите, знатоки, как в этом случае быть?