Вход на хостинг
IT-новости
20.04.2016 iPhone 2017 года поместят в водонепроницаемый корпус из стекла
Линейка iPhone в новом году серьезно поменяется. В этом уверен аналитический исследователь Мин Чи Ку......
30.07.2015 Ищем уникальный контент для сайта
Ищем уникальный контент для сайта Без уникального контента Ваш сайт обречен на то, что его страницы......
return 0;
}
void cleanup_module()
{
// Освобождаем порты ввода-вывода
release_region(PORT_START, PORT_QTY);
printk("My module: release io ports ");
// Освобождаем память
release_mem_region(MEM_START, MEM_QTY);
printk("My module: release memory ");
// Освобождаем прерывание
free_irq(IRQ_NUM,NULL);
printk("My module: release irq ");
// Отменяем регистрацию устройства
if (unregister_chrdev(Major, DEV_NAME) < 0){
printk("My module: cannot to unregister device ");
}
printk("My module: device unregistered ");
return;
}
При загрузке модуля вы увидите следующее сообщение:
My module: device registered, major number = 255
Конечно, кроме этого сообщения будут другие сообщения, но нас они не интересуют. Почему именно это сообщение так важно для нас? В первой части сообщения говорится, что наше устройство успешно зарегистрировано, а во второй – сообщается старший номер устройства, который мы будем использовать для создания устройств /dev/device0 и /dev/device1.
Вы не забыли, что нам еще нужно создать два устройства типа device, чтобы программы могли бы работать с ними? Перейдите в каталог /dev и от имени пользователя root выполните команды:
mknod device c 255 0
mknod device c 255 1
Здесь 255 – это старший номер устройства (у вас он будет другим), 0 и 1 – младшие номера устройств. После выполнения данных команд будут созданы два файла устройств – /dev/device0 и /dev/device1.
После регистрации устройства функцией register_chrdev() мы пытаемся захватить диапазон портов. Для этого предназначена функция request_region(), но перед ее вызовом мы должны убедиться, что нужный нам диапазон не используется (функция check_region()). Затем, если нужно, мы резервируем память для нашего устройства. Для резервирования памяти используется функция request_mem_region(), а для проверки возможности захвата памяти предназначена функция check_mem_region(). После успешной регистрации памяти можно попытаться захватить IRQ – функция request_irq().
Предположим, что на каком-то этапе регистрации драйвера произошла ошибка. Если мы не смогли зарегистрировать порты ввода/вывода, вряд ли имеет смысл продолжать работу. Если же ошибка произошла при резервировании памяти, то перед завершением работы модуля нам нужно освободить порты ввода/вывода, которые мы зарегистрировали на предыдущем этапе. Аналогично поступаем при ошибке захвата IRQ – освобождаем порты и память. Функции release_mem_region(),release_region и free_irq() используются для освобождения памяти, портов и IRQ соответственно.
Обратите внимание: мы написали драйвер так, что он захватывает порты и память от имени одного устройства – DEV_NAME. В реальности все гораздо сложнее: нужно захватывать ресурсы для каждого устройства данного типа. К тому же нужно предусмотреть поиск устройств драйвером: в нашем случае мы знаем, что устройств только два, но у конечного пользователя таких устройств может быть больше или меньше, поэтому наш драйвер будет не универсален, если он будет поддерживать только два устройства. О поиске устройств мы поговорим чуть позже.