Как отделить alloc_chrdev_region и cdev_add от функции проверки драйвера платформы, чтобы инициировать несколько экземпляров одного и того же устройства? И где я могу получить доступ к образцу кода соответствующего драйвера платформы с аналогичными возможностями?
У меня есть 4 экземпляра устройства, которые работают одинаково. Обычно я использую драйвер платформы для управления своим устройством, но имеющийся у меня код может инициировать только одно созданное устройство с помощью команд .ko и insmod, а не несколько экземпляров одного и того же устройства.
Я пытался переписать свой код. Я обнаружил, что функция проверки platform_driver включает alloc_chrdev_region и cdev_add. Я не знаю, как отделить функцию alloc_chrdev_region и cdev_add от функции проверки platform_driver.
Следующий код - это дерево устройств моего устройства:
mipi_csi2_rx_v_cap_pipeline_0: v_cap_pipeline@a0030000 {
compatible = "xlnx,v-cap-pipeline-1.0";
interrupt-names = "interrupt";
interrupt-parent = <&gic>;
interrupts = <0 104 4>;
reg = <0x0 0xa0030000 0x0 0x4000>;
xlnx,s-axi-chn-mst-num = <0x2>;
};
mipi_csi2_rx_v_cap_pipeline_1: v_cap_pipeline@a0034000 {
compatible = "xlnx,v-cap-pipeline-1.0";
interrupt-names = "interrupt";
interrupt-parent = <&gic>;
interrupts = <0 105 4>;
reg = <0x0 0xa0034000 0x0 0x4000>;
xlnx,s-axi-chn-mst-num = <0x2>;
};
mipi_csi2_rx_v_cap_pipeline_2: v_cap_pipeline@a0038000 {
compatible = "xlnx,v-cap-pipeline-1.0";
interrupt-names = "interrupt";
interrupt-parent = <&gic>;
interrupts = <0 106 4>;
reg = <0x0 0xa0038000 0x0 0x4000>;
xlnx,s-axi-chn-mst-num = <0x2>;
};
mipi_csi2_rx_v_cap_pipeline_3: v_cap_pipeline@a003c000 {
compatible = "xlnx,v-cap-pipeline-1.0";
interrupt-names = "interrupt";
interrupt-parent = <&gic>;
interrupts = <0 107 4>;
reg = <0x0 0xa003c000 0x0 0x4000>;
xlnx,s-axi-chn-mst-num = <0x2>;
};
Следующий пример кода - это пробная функция моего драйвера платформы:
static int fstream_probe(struct platform_device *pdev) {
struct device *dev = &pdev->dev;
dev_t devno = MKDEV(fstream_major, 0);
ret = alloc_chrdev_region(&devno, 0, DEV_NUM, DRIVER_NAME);
fstream_major = MAJOR(devno);
cdevp = (struct fstream_cdev *) kzalloc(sizeof(struct fstream_cdev)*DEV_NUM, GFP_KERNEL);
fstream_setup_cdev(cdevp);
...
/* others ignored */
PDEBUG(" init success\n");;
}
static struct of_device_id fstream_of_match[] = {
{.compatible = "xlnx,v-cap-pipeline-1.0", },
{ /* end of list */ },
};
MODULE_DEVICE_TABLE(of, fstream_of_match);
static struct platform_driver fstream_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = fstream_of_match,
},
.probe = fstream_probe,
.remove = fstream_remove,
};
static int __init fstream_init(void) {
return platform_driver_register(&fstream_driver);
}
module_init(fstream_init);
Когда функция проверки в моем коде вызывается 4 раза, в / proc / devices создаются 4 основных устройства с разными основными идентификаторами, чего я не ожидал (мне нужен 1 основной идентификатор с 4 разными второстепенными идентификаторами).
Следующее сообщение - это журнал моего устройства, он показывает, что функции зонда вызываются 4 раза:
zynqmp#dmesg |grep fstream
[ 111.769297] st_fstream: loading out-of-tree module taints kernel.
[ 111.775514] st_fstream: unknown parameter 'st_fstream' ignored
[ 111.781314] st_fstream: unknown parameter 'st_fstream' ignored
[ 111.787429] [fstream]cdev Device number reg/allocation successed. cdev->major=243, cdev->minor=0.
[ 111.787511] [fstream]@0xa0030000 mapped to 0xffffff800bbe0000, irq=46
[ 111.787512] [fstream] init success
[ 111.787572] [fstream]cdev Device number reg/allocation successed. cdev->major=242, cdev->minor=0.
[ 111.787631] [fstream]@0xa0034000 mapped to 0xffffff800bbf0000, irq=47
[ 111.787634] [fstream] init success
[ 111.787671] [fstream]cdev Device number reg/allocation successed. cdev->major=241, cdev->minor=0.
[ 111.787730] [fstream]@0xa0038000 mapped to 0xffffff800bc00000, irq=48
[ 111.787732] [fstream] init success
[ 111.787767] [fstream]cdev Device number reg/allocation successed. cdev->major=240, cdev->minor=0.
[ 111.787826] [fstream]@0xa003c000 mapped to 0xffffff800bc10000, irq=49
[ 111.787827] [fstream] init success
alloc_chrdev_region
в функции инициализации вашего модуля, чтобы зарезервировать диапазон номеров устройств, а затем назначить неиспользуемый номер устройства из вашего зарезервированного диапазона в функции проверки. - person Ian Abbott   schedule 22.08.2019int mydriver_fop_open(struct inode *inode, struct file *file)
) получает объединенные старший и младший номер устройства вinode->i_rdev
. Вы должны иметь возможность использовать это, чтобы проверить, какое устройство открывается (например,MINOR(inode->i_rdev)
сообщает вам младший номер). Установитеfile->private_data
, чтобы он указывал на личные данные вашего устройства для использования другими обработчиками файловых операций драйвера. - person Ian Abbott   schedule 02.09.2019