Читать «Linux: Полное руководство» онлайн - страница 404
Денис Николаевич Колисниченко
Если же вам все-таки хочется узнать конкретное количество устройств /dev/deviceX, установленных у пользователя, можно просто просмотреть содержимое каталога /dev и посчитать количество файлов device*.
Все готово для того, чтобы написать функцию открытия устройства.
Листинг 28.7. Функция открытия устройства
static int device_open(struct inode *inode, struct file *fp) {
struct device_state *dev_state;
printk("My module: try to open device with minor number %d\n",
MINOR(inode->i_rdev));
devastate = &state[MINOR(inode->i_rdev)];
if (dev_state->dev_open) {
printk("Devise is busy\n");
return -EBUSY;
}
dev_state->dev_open = 1;
dev_state->byte_read = 0;
dev_state->byte_write = 0;
MOD_INC_USE_COUNT;
return 0;
}
Младший номер устройства мы получаем с помощью вызова MINOR (inode->i_rdev). Если устройство уже открыто, мы выводим сообщение: Devise is busy. В противном случае устанавливаем флаг открытия устройства, обнуляем byte_read и byte_write, а также увеличиваем счетчик использования данного модуля (MOD_INC_USE_COUNT).
Функция закрытия устройства сбрасывает флаг dev_open и уменьшает счетчик использования устройства.
Листинг 28.8. Функция закрытия устройства
static int device_close(struct inode *inode, struct file *fp) {
struct device_state *dev_state;
printk("My module: try to close device with minor number %d\n",
MINOR(inode->i_rdev));
dev_state = &state[MINOR(inode->i_rdev)];
if (!dev_state->dev_open) {
printk("Device is not open\n");
return 0;
}
dev_state->dev_open=0;
MOD_DEC_USE_COUNT;
return 0;
}
Теперь нам нужно указать ядру, какие функции нужно использовать для открытия и закрытия устройства:
struct file_operations FO = {
open: device_open,
release: device_close
};
Полный код модуля устройства device вместе с функциями открытия и закрытия устройства, а также структурой file_operations приведен в следующем листинге:
Листинг 28.9. Модуль устройства device (module.с)
#define MODULE
#define __KERNEL__
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h> // регистрация устройств
#include <linux/ioport.h> // работа с портами ввода/вывода
#include <linux/sched.h> // резервирование прерывания
// Имя нашего устройства
#define DEV_NAME "device"
// Порты ввода-вывода нашего устройства
#define PORT_START 0x2000
#define PORT_QTY 10
// Память нашего устройства
#define MEM_START 0x20000000
#define MEM_QTY 0x20
// Номер прерывания для нашего устройства
#define IRQ_NUM 9
MODULE_DESCRIPTION("Linux kernel module");
// Старший номер файла устройства
static int Major;
// Структура file_operations - пока пустая,