5.1.1 Инициализация и старт драйвера

Предыдущая  Содержание  Следующая V*D*V

Теперь давайте обсудим функции инициализации для драйвера. Функция инициализации регистрирует устройство TTY, а затем задаёт путь между ядром UART и драйвером. Основными структурами данных, участвующими в этом процессе и объявленными в файле include/linux/serial_core.h, являются следующие:

 

struct uart_driver: эта структура данных содержит информацию об имени, старшем и младшем номерах, и количестве портов данного драйвера.

struct uart_port: эта структура данных содержит все данные о конфигурации низкоуровневого оборудования.

struct uart_ops: эта структура данных содержит указатели на функции, которые работают с оборудованием.

 

Для устройства UART с двумя аппаратными портами, эти три структуры данных связаны друг с другом так, как показано на Рисунке 5.3. Для данного примера мы используем двухпортовое оборудование; однако, наш пример оборудования однопортовый.

 

Рисунок 5.3 Связь структур данных для UART.

Рисунок 5.3 Связь структур данных для UART.

 

Существует одна закрытая структура, удерживаемая ядром, - uart_state. Число uart_state равно числу аппаратных портов, которые доступны через драйвер. Каждая uart_state содержит указатель на структуру настройки данного порта uart_port, которая, в свою очередь, содержит структуру uart_ops, содержащую процедуры для доступа к оборудованию.

Структуры данных для MY_UART определены как показано в Распечатке 5.2.

Сначала мы пишем процедуру инициализации.

 

int __init my_uart_init(void)

{

  /*

   * uart_register_driver связывает низкоуровневый драйвер с

   * последовательным ядром, которое в свою очередь регистрируется

   * в уровне TTY с помощью функции tty_register_driver(). Также

   * создаются структуры uart_state (количество таких структур

   * равно числу аппаратных портов) и указатель на этот массив

   * сохраняется в my_uart_driver.

   */

  uart_register_driver (&my_uart_driver);

 

  /*

   * Как показано на Рисунке 5.3, эта функция соединяет

   * uart_state с uart_port. Также с помощью функции

   * tty_register_device() эта функция даёт знать

   * уровню TTY, что было добавлено устройство.

   */

  uart_add_one_port (&my_uart_driver, &my_uart_port);

 

  return 0;

}

 

Теперь обсудим функции в структуре my_uart_ops. Функции request_port() и release_port() обычно используются для запроса регионов ввода-вывода и памяти, используемых портом. Функции включения и выключения my_uart_startup() и my_uart_shutdown() выполняют настройку и отключение прерывания, соответственно.

 

static int my_uart_startup(struct uart_port *port)

{

  return(request_irq(MY_UART_IRQ, my_uart_irq_handler, 0,

                     “my uart”, port));

}

 

static void my_uart_shutdown(struct uart_port *port)

{

  free_irq(MY_UART_IRQ, port);

}

 

Предыдущая  Содержание  Следующая