我正在编写一个访问PCI卡的简单char驱动程序。它在新类的帮助下注册到sysfs,可在/dev/foodev
下访问。现在我想以方便的方式访问设备的多个参数。我想到了向设备注册多个属性(通过device_create_file()
),然后可以看到如下:
/dev/foodev
../version
../status
../control
因此,我按照Documentation/driver-model/device.txt中的描述定义了我的属性,并将其注册到GregKH on his blog所描述的类dev_attrs
属性,如下所示(代码去除了所有返回值验证):< / p>
static int __init foo_init(void)
{
int rv;
dev_t devNbr;
/* Create device class */
fooClass = class_create(THIS_MODULE, CLASS_NAME);
fooClass->dev_attrs = foo_attrs; /* my group of attributes */
/* Allocate device number */
rv = alloc_chrdev_region(&devNbr, 0, 1, DEVICE_NAME);
foo_majNbr = MAJOR(devNbr);
/* Registering driver */
rv = pci_register_driver(&foo_driver);
...
}
然后probe
函数将每个设备注册为char设备并将它们连接到类。在最后一步中,属性(此处只有一个)被注册为文件:
static int __devinit foo_probe(struct pci_dev *dev,
const struct pci_device_id *devId)
{
struct foo_dev *foo_dev = 0;
int rv = 0;
/* Allocate memory in Kernel (for parameters) */
foo_dev = kzalloc(sizeof(*foo_dev), GFP_KERNEL);
foo_dev->pci_dev = dev;
foo_dev->devNbr = MKDEV(foo_majNbr, 1);
/* Add class to device */
foo_dev->dev = device_create(fooClass, NULL, foo_dev->devNbr,
foo_dev, DEVICE_NAME);
/* Add char device */
cdev_init(&foo_dev->cdev, &foo_fops);
/* Enabling device */
rv = pci_enable_device(dev);
...
/* ----> Register attribute as file <---- */
device_create_file(foo_dev->dev, &dev_attr_bar);
...
}
我的问题:该属性没有出现在udev中,因为我打算这样做。我仍然只看到设备/dev/foodev
没有属性的“子文件”。仔细看看/sys/class/fooClass/fooDev/
我看到了一个文件bar
,我可以根据需要阅读和写入,但udev显然忽略了它:
第二:我的三个不同结构之间的关系是什么,都包含struct device
(pci_dev
,dev
和cdev
)?读完后我知道了。我为所有人创建了一个kobject。我也知道pci_dev已连接到总线,我想cdev是我希望用户访问的。在LDD的图14-1之后,我假设在设备模型中创建以下结构:
Buses Devices Classes
| | |
v v v
pci_dev <---- cdev dev
^ |
| |
+----------------------------+
正确?