Читать «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 - пока пустая,