Читаем Linux: Полное руководство полностью

Если же вам все-таки хочется узнать конкретное количество устройств /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

#include

#include

#include // регистрация устройств

#include // работа с портами ввода/вывода

#include // резервирование прерывания

// Имя нашего устройства

#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_AUTHOR("Denis Kolisnichenko [email protected]");

MODULE_DESCRIPTION("Linux kernel module");

// Старший номер файла устройства

static int Major;

// Структура file_operations - пока пустая,

// но вскоре мы ее напишем

struct file_operations FO {

 open:    device_open,

 release: device_close

};

// Структура для хранения состояния устройства

struct device_state {

 int dev_open; // 1 - устройство открыто, 0 — закрыто

 ssize_t byte_read; // Количество прочитанных байтов

                    // из устройства

 ssize_t byte_write; // Количество записанных байтов

};

// Массив для хранения информации о состоянии устройств

static struct device_state state[2];

// Обработчик прерывания

Перейти на страницу:

Все книги серии Полное руководство

Похожие книги