LINUX.ORG.RU

Сигнал от модуля


0

0

Укажите правильный подход в таком вопросе: Модуль должен получить от устройства данные, и сообщить проге об этом. Причем не хотелось бы спать в ioctl или read. Как это сделать идеологически правильно ?


driver_poll в file_operations определить.

SatanClaus ★★★
()

Делать в цикле poll/select файла устройства. При этом нужна поддержка со стороны драйвера. Из вопроса неясно интересует ли kernel или user space.

geekkoo
()
Ответ на: комментарий от geekkoo

Значит данные валятся в kernel space по DMA, при заполнении буфера модуль должен сказать проге из user space, чтоб забрала данные. Я так понимаю, что при poll/select надо эти вызовы постоянно делать, а вот еслибы user прога во время приема своими делами занималась, а как буфер заполниться модуль типа прерывания выставляет, типа забирай данные.

senjy
() автор топика
Ответ на: комментарий от senjy

Это уже проблема проги. Дело драйвера обработать вызов, остальное его не касается. Хотя может и есть варианты.

SatanClaus ★★★
()
Ответ на: комментарий от SatanClaus

>>>Это уже проблема проги.

Совершенно верно. Я ж не знаю как у вас прога устроена. Если она threaded ничего не мешает просто read делать (чтение устройства в отдельной нити), иначе цикл (event loop) по всем интересующим file descriptor - ам. X connection - тоже file descriptor, так что можно устроить жизнь таким образом, что one-threaded программа спит большую часть времени и просыпается, когда пользователь мышой поелозит или данные с устройства придут.

geekkoo
()
Ответ на: комментарий от senjy

похоже ты хоч реализовать сигнальный ввод/вывод. некоторые ещё его зовут аинхронным, хотя я лично подасинхронным понимаю aio.

man fcntl

cvv ★★★★★
()

Попробуй использовать сигналы через
struct  fasync_struct *async_queue;


//--------------------------------------------------------------------

struct file_operations fops = {
    --------------------------
    fasync: dev_fasync,    	//  *fasync
};

//--------------------------------------------------------------------
// Зарегистрировать fasync для fops
int dev_fasync(int fd, struct file *file, int on)
{
	   device *pdx = (device *)file->private_data;
	 
         int retval = fasync_helper(fd, file, on, &pdx->async_queue);

         if (retval < 0)
                 return retval;

         return 0;
}
//--------------------------------------------------------------------
// Удалить fasync для fops
int dev_fasync(int fd, struct file *file, int on)
{
	   device *pdx = (device *)file->private_data;
	 
         int retval = fasync_helper(-1, file, 0, &pdx->async_queue);

         if (retval < 0)
                 return retval;

         return 0;
}

Послать сигнал из kerenl-space:

kill_fasync( &pdx->async_queue, SIGIO, POLL_IN );

//--------------------------------------------------------------------

Регистрировать обработчик сигнала в user-space:

signal(SIGIO, &handler);
fcntl(file, F_SETOWN, getpid());
flags = fcntl(file, F_GETFL);
fcntl(file, F_SETFL, flags | FASYNC);

Программа получит сигнал SIGIO из модуля после вызова в нем
kill_fasync. P. S. это делалось мной для ветки 2.4.х. Более детально можешь ознакомиться в LDD.

karak
()
Ответ на: комментарий от geekkoo

Драйвер принимает данные из PCI-устройства, после заполнения одного из буферов должен сообщить юзер процессу, что данные готовы. Ну а юзер процесс ну например в файл их скидывает. При этом бы хотелось запустить драйвер один раз (через ioctl) и чтоб драйвер посылал сигналы из прерывания DMA (т.е. когда буфер заполнен). Т.е. схема такая процесс запускает DMA (ioctl), а дальше тока отлавливает сигналы от модуля об окончании приема. Модуль же при заполнении буфера входит в прерывание от DMA, посылает сигнал пользователю и перенастраивает DMA для дальнейшего приема и так по кругу... По-моему посылка сигнал kill_fasync для этого как раз то, что надо...

senjy
() автор топика
Ответ на: комментарий от karak

> А можно-ли посылать  kill_fasync в top half?

из любого контекста можно. но с чего вы вообще решили,
что что-то можно делать в interrupt контексте, и нельзя
это же делать вне его?

idle ★★★★★
()
Ответ на: комментарий от idle

Если юзер процесс находится в слипе и получает kill_fasync от модуля, проснется ли он ? или сделает все что надо в обработчике сигнала и дальше спать ???

senjy
() автор топика
Ответ на: комментарий от senjy

> Если юзер процесс находится в слипе и получает kill_fasync от модуля,
> проснется ли он ?

ох... процесс получит сигнал. все, к ядру это отношения
не имеет.

однозначного ответа на ваш вопрос нет, читайте маны.
sigaction, sigprocmask.

idle ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.