5.1.1 Инициализация и старт драйвера |
Предыдущая Содержание Следующая |
Теперь давайте обсудим функции инициализации для драйвера. Функция инициализации регистрирует устройство TTY, а затем задаёт путь между ядром UART и драйвером. Основными структурами данных, участвующими в этом процессе и объявленными в файле include/linux/serial_core.h, являются следующие:
▪struct uart_driver: эта структура данных содержит информацию об имени, старшем и младшем номерах, и количестве портов данного драйвера. ▪struct uart_port: эта структура данных содержит все данные о конфигурации низкоуровневого оборудования. ▪struct uart_ops: эта структура данных содержит указатели на функции, которые работают с оборудованием.
Для устройства UART с двумя аппаратными портами, эти три структуры данных связаны друг с другом так, как показано на Рисунке 5.3. Для данного примера мы используем двухпортовое оборудование; однако, наш пример оборудования однопортовый.
Рисунок 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); }
|
Предыдущая Содержание Следующая |