Символьное устройство: выберите устройство для чтения / записи
Я нашел хороший код в качестве примера для модуля символьного устройства: https://github.com/euspectre/kedr/blob/master/sources/examples/sample_target/cfake.c
Я не модифицировал код, и я протестировал его. Я получил два устройства (/dev/cfake0 и /dev/cfake1), но я хотел бы кое-что понять.
Существует два экспортируемых устройства, но только одна функция чтения. Как указать, какую функцию чтения использовать для каждого устройства (если реализованы две функции чтения)?
В конце я хотел бы иметь два символьных устройства (одно для связи I2C, другое для SPI) на одном модуле, модуль и пространство пользователя нуждаются в связи, поэтому мне нужно экспортировать оба из них.
1 ответ
У вас есть одна функция для каждого вызова в вашем файле:
- открытие
- чтение
- пишу
- закрытие
- ...
Но все функции имеют struct file
в качестве параметра.
Эта структура, которая содержит информацию о файле, создается модулем, когда он загружается в ядро. (увидеть static int __init cfake_init_module(void);
функция).
В конце я хотел бы иметь двухсимвольные устройства (одно для связи I2C, другое для SPI)
Вы могли бы сделать вещи, чтобы сделать так:
В приведенном вами примере каждый файл создается с minor device number
(увидеть cfake_construct_device()
). Вы можете использовать этот номер, чтобы выбрать, является ли устройство SPI или устройством I2C.
Ваш read
функция может выглядеть так:
ssize_t
cfake_read(struct file *filp, char __user *buf, size_t count,
loff_t *f_pos)
{
/* reading minor device number */
unsigned int mn = iminor(filp->f_inode);
/* select specialized function to use */
if (0 == mn)
return cfake_read_i2c(filp, buf, count, f_pos);
else
return cfake_read_spi(filp, buf, count, f_pos);
}
Сказал, что я не думаю, что это хорошая идея иметь два разных протокола в одном модуле (если два устройства не должны обмениваться данными): при сбое модуля вы потеряете два канала связи, и модуль будет трудно отладить,