* Re[2]: UDEV.
@ 2010-08-19 15:07 Тима
2010-08-24 9:27 ` Тима
0 siblings, 1 reply; 2+ messages in thread
From: Тима @ 2010-08-19 15:07 UTC (permalink / raw)
To: linux-hotplug
Thanks.
My question (I think) is very easy. But I could not find answer in the Internet, and did not get it on forum.
My aim is to make UDEV create device node automatically on loading module.
I tied rule:
KERNEL="math", NAME="math"
meaning my device name (register char dev) is "math" and the node name I want is "math".
But nothing happens.
Is there any possibility to make such rule?
Maybe I do not export some required information to SysFS?
If you need module code I can send it to you with Makefile.
> Wed, 18 Aug 2010 05:49:31 -0700 письмо от Greg KH <greg@kroah.com>:
>
> > On Wed, Aug 18, 2010 at 01:51:11PM +0400, ???? wrote:
> > > Hello All!
> > > My name is Tima, I'm embedded software developer.
> > > I'm working on driver for Satellite Digital Video Receiver.
> > >
> > > May I ask some question about UDEV?
> >
> > You never have to ask the question "can I ask a question?" :)
--
To unsubscribe from this list: send the line "unsubscribe linux-hotplug" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re[2]: UDEV.
2010-08-19 15:07 Re[2]: UDEV Тима
@ 2010-08-24 9:27 ` Тима
0 siblings, 0 replies; 2+ messages in thread
From: Тима @ 2010-08-24 9:27 UTC (permalink / raw)
To: linux-hotplug
>
> A: No.
> Q: Should I include quotations after my reply?
>
> http://daringfireball.net/2007/07/on_top
>
> On Thu, Aug 19, 2010 at 07:07:40PM +0400, ???? wrote:
> > Thanks.
> > My question (I think) is very easy. But I could not find answer in the Internet, and did not get it on forum.
> > My aim is to make UDEV create device node automatically on loading module.
> > I tied rule:
> > KERNEL="math", NAME="math"
> > meaning my device name (register char dev) is "math" and the node name I want is "math".
> > But nothing happens.
> > Is there any possibility to make such rule?
> > Maybe I do not export some required information to SysFS?
> > If you need module code I can send it to you with Makefile.
>
> Yes, please post your kernel code. You need to hook into the driver
> model to properly be able to have udev pick up your device information.
> Have you done that?
>
> thanks,
>
> greg k-h
Yes, here is my code.
(Sorry for comments in russian. If you need something to understand - ask me and I'll translate it.)
I want kernel to make, for example, /dev/math on loading this module. What should I add to this code or to UDEV rules?
#include <linux/module.h> // Необходим для любого модуля ядра
#include <linux/kernel.h> // Здесь находится определения KERN_*
#include <linux/init.h> // Здесь находятся определения макросов
#include <linux/fs.h> // Фаил для работы с фаиловой системой
#include <asm/uaccess.h> // Определение функции put_user
#include <linux/device.h>
static char *DeviceName = "math";
static char *ParamStr = "NULL";
module_param (ParamStr, charp, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
// Третий аргумент функции - права доступа к соответствующему фаилу в SysFS.
// В нашем случае Read User, Write User, Read Group, Read Others.
MODULE_PARM_DESC (ParamStr, " String Parameter.");
static int DevMajor = -1;
#define STR_LEN 256
static char Expression [STR_LEN];
static char FirstOperand [STR_LEN];
static char SecondOperand [STR_LEN];
static char Answer [STR_LEN];
static int Calculate (void)
{ // Функция выполняющая разбор заданного выражения и вычисление результата.
// Принимает Expression, результат вычислений возвращает в Answer.
int lStr = 0;
int lOperation = -1;
int Operand1, Operand2 = 0;
// lOperation: -1 - "Error"; 0 - "+"; 1 - "-"; 2 - "*"; 3 - "/";
sprintf (Answer, "No Calculated Result.\n");
Answer[strlen ("No Calculated Result.\n")] = 0;
// Ищем знак математической операции:
while (lStr < strlen (Expression))
{
if (Expression[lStr] = '+')
{
lOperation = 0;
break;
} else
if (Expression[lStr] = '-')
{
lOperation = 1;
break;
} else
if (Expression[lStr] = '*')
{
lOperation = 2;
break;
} else
if (Expression[lStr] = '/')
{
lOperation = 3;
break;
};
lStr++;
};
if (lOperation = -1)
{// Если знак операции не найден - выводим подсказку.
sprintf (Answer, "Error in Expression. Please use as \"Operand1 [+, -, *, /] Operand2\".\n");
} else
{
memcpy (FirstOperand, &Expression[0], lStr);
memcpy (SecondOperand, &Expression[lStr + 1], strlen (Expression) - lStr - 1);
Operand1 = simple_strtol (FirstOperand, &FirstOperand, 10);
Operand2 = simple_strtol (SecondOperand, &SecondOperand, 10);
// Сосчитаем что просят:
switch (lOperation)
{
case 0: // +
sprintf (Answer, "%s = %d\n", Expression, Operand1 + Operand2);
break;
case 1: // -
sprintf (Answer, "%s = %d\n", Expression, Operand1 - Operand2);
break;
case 2: // *
sprintf (Answer, "%s = %d\n", Expression, Operand1 * Operand2);
break;
case 3: // /
if (Operand2 = 0)
{
sprintf (Answer, "Sorry, division by Zero is not implemented yet.\n");
} else sprintf (Answer, "%s = %d\n", Expression, Operand1 / Operand2);
break;
default:
sprintf (Answer, "Error in Expression. Please use as \"Operand1 [+, -, *, /] Operand2\".\n");
break;
};
};
return lOperation;
};
static ssize_t DevWrite (struct file * _File, const char __user * _Buffer, size_t _Count, loff_t *_PPos)
{ // Функция отвечает за запись в устройство.
memcpy (&Expression[0], &_Buffer[0], _Count);
Expression[_Count] = 0;
// Вычисляем заданное выражение:
Calculate ();
// Нужно вернуть количество записавшихся (или полученных) байт.
// Иначе будет цикл бесконечной записи в устройство.
// Видимо кернел продолжает попытки записать в устройство если возвращать 0.
// Если устройство вообще не желает принимать данные, нуж но вернуть -EINVAL.
// Но это будет обрабатываться именно как ошибка:
// echo -n "123" > /dev/coffee
// bash: echo: write error: Invalid argument
// Мы выбираем самый приемлемый для нас вариант:
return _Count;
};
static ssize_t DevRead (struct file * _File, char __user * _Buffer, size_t _Count, loff_t *_PPos)
{ // Функция отвечает за чтение из устройства.
size_t BytesWritten = strlen (Answer) - *_PPos;
// Проверяем чтобы запрашиваемая позиция в фаиле не выходила за его размер,
// чтобы предоставляемый буффер был достаточного размера
// и чтобы буффер вообще существовал. Если что-то не так, возвращаем 0
// как признак конца фаила.
if ((*_PPos > strlen (Answer)) || (_Count < strlen (Expression))
|| (!_Buffer)) return 0;
// Т.к. буфер данных находится в пространсвте пользователя,
// а мы находимся в пространстве ядра, то для копирования
// данных в буфер пользователя мы используем функцию copy_to_user:
if (BytesWritten != 0)
{
if (_Count < BytesWritten) BytesWritten = _Count;
copy_to_user (_Buffer, Answer + *_PPos, BytesWritten);
*_PPos += BytesWritten;
}
return BytesWritten;
};
static ssize_t DevRelease (struct inode *_INode, struct file *_File)
{
module_put (THIS_MODULE);
return 0;
};
static ssize_t DevOpen (struct inode *_INode, struct file *_File)
{
try_module_get (THIS_MODULE);
return 0;
};
static const struct file_operations DevOps {
// Здесь мы задаём фнкции, отвечающие за операции с нашим устройством
// и указываем адреса процедур отвечающих за эти операции.
// В нашем случае - чтение из устройства, запись в него и отработка обращений.
.owner = THIS_MODULE,
.read = DevRead,
.write = DevWrite,
.release = DevRelease,
.open = DevOpen
};
int init (void)
{
printk (KERN_INFO "Given Parameter String is \"%s\".\n", ParamStr);
// Запрашиваем динамический старший номер устройства (драйвера - т.е. нас).
// В случае успеха, функция вернет Device Major.
DevMajor = register_chrdev (0, DeviceName, &DevOps);
if ((DevMajor) < 0)
{
printk (KERN_ERR "Error! Char Device Could not be Registerd.\n");
// В любом случае, вернем то что получилось. Пусть лубуются.
return DevMajor;
};
printk ("Use 'mknod /dev/%s c %d 0' to create device file.\n", DeviceName, DevMajor);
// Если вернуть ненулевое значение, то это будет воспринято как ошибка,
// возникшая в процессе работы init_module; и модуль не будет загружен.
sprintf (Expression, "Empty Expression.\n");
sprintf (Answer, "Empty Answer.\n");
return 0;
}
void cleanup (void)
{
// Освобождаем номер, выданный нам ранее.
// С версии 2.6.23 unregister_chrdev возвращает void т.е. ничего.
// Нет возможности проконтролировать работу этой функции.
printk (KERN_INFO "unregister_chrdev ();");
unregister_chrdev (DevMajor, DeviceName);
}
// Начиная с версии 2.3.13, требования к именованию начальной и конечной функций
// модуля были сняты. Достигается это с помощью макроопределений module_init()
// и module_exit(). Воспользуемся этим, т.к. теперь это считается правильно:
module_init (init);
module_exit (cleanup);
// Описание модуля (может быть прочтено программой modinfo):
MODULE_LICENSE("GPL"); // Нужно для функции class_create.
MODULE_AUTHOR("Timofey Chernigovskiy"); // Автор.
MODULE_DESCRIPTION("Math-Device Module"); // Описание.
MODULE_VERSION("0.1"); // Версия.
MODULE_SUPPORTED_DEVICE(DeviceName); // Тип устройств поддерживаемых модулем.
--
To unsubscribe from this list: send the line "unsubscribe linux-hotplug" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-08-24 9:27 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-19 15:07 Re[2]: UDEV Тима
2010-08-24 9:27 ` Тима
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.