Официальный форум СВД Встраиваемые Системы
25 Апрель, 2024, 12:34:11 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
 
 
 Сайт СВД ВС  Начало   Помощь Поиск Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: При выполнении команды ls в драйвере устройства вызывается io_open.  (Прочитано 1053 раз)
KA3AKOB
Пользователь

Сообщений: 55


« : 15 Февраль, 2018, 17:24:51 »

В разрабатываемом мною Resource Managerе есть стандартный вход при открытии файла:

int io_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle, void *extra)
{
      if (optv) {   fprintf (stderr, "%s:  in io_open\n", progname);   }
     // делаем всё, что полагается при открытии устройства, установки регистров,
     // всякие in8(ba+3); и прочее.
     intr_id = InterruptAttach (intRQ, main_isr_handler, NULL, 0, _NTO_INTR_FLAGS_END ); //realtime interrupt
     return (iofunc_open_default (ctp, msg, handle, extra));
}

Но если я вызываю стандартную команду оболочки ls /dev/имя_моего_устройства_5 из resmgr_attach(),
то влетаю в io_open. Я полагал, что утилита ls работает с файловой системой, в которую включается моё устройство.
Ну скажи мне, система, что устройство есть, распиши его атрибуты, но открывать-то зачем? На мой взгляд совсем лишняя,
мешающая операция. Вот open("/dev/моё_устройство5", ... вполне то самое место в программе, где надо вызывать io_open
в драйвере. Подскажите, пожалуйста, как избавиться от открывания устройства ls'ом.
С уважением,
Казаков С.А.
Записан
Андрей Докучаев
Сотрудник СВД ВС
Легенда

Сообщений: 1076



WWW
« Ответ #1 : 15 Февраль, 2018, 17:27:12 »

как избавиться от открывания устройства ls'ом.

Вариантов несколько:
1. не использовать утилиту ls.
2. не регистрировать обработчик io-open.
Записан

KA3AKOB
Пользователь

Сообщений: 55


« Ответ #2 : 16 Февраль, 2018, 17:42:07 »

2. Как можно работать с внешним устройством, использовать стандартную функцию read(), не открывая устройство? А обработчик io_open это стандартный вход, генерируемый, кстати, штатным генератором Resource Managerов. Смотрим Кртена, глава 5. На мой взгляд, без обработчика io_open никак нельзя.
1. Можно, конечно, и не использовать ls. Но, вообще-то хотелось бы, узнать убедительные доводы, зачем ls'у открывать устройство? Это не ляп оболочки?
С уважением,
Казаков С.А.
 
Записан
Андрей Докучаев
Сотрудник СВД ВС
Легенда

Сообщений: 1076



WWW
« Ответ #3 : 16 Февраль, 2018, 21:03:52 »

2. Как можно работать с внешним устройством, использовать стандартную функцию read(), не открывая устройство?

При отсутствии зарегистрированного обработчика io_open библиотека libc будет использовать собственный.

Это не ляп оболочки?

Нет, это соответствует корректному поведению утилиты.
« Последнее редактирование: 16 Февраль, 2018, 22:17:30 от Андрей Докучаев » Записан

KA3AKOB
Пользователь

Сообщений: 55


« Ответ #4 : 19 Февраль, 2018, 11:39:41 »

Боюсь, что Вы меня не поняли, уважаемый Андрей Докучаев! В самом начале темы, я привёл пример. Надеюсь, очевидно, что стандартный (собственный) обработчик io_open из библиотеки libc ничего не знает про аппаратные регистры моего устройства. Поэтому, на мой взгляд, очевидно, что обработчик io_open та самая подпрограмма, в которой следует разрешать прерывания, сбрасывать регистры состояния, инициировать указатели буферов и проделывать подобные важные операции. Надеюсь, очевидно, что мне нужно писать собственный обработчик. Собственно, штатный обработчик io_open и у меня вызывается согласно Кртену:   return (iofunc_open_default (ctp, msg, handle, extra)); Понятно, что для таких утилит как cat или find, операция open("/dev/my_device5,... " естественна и необходима. Но вот открывание устройства утилитой ls не представляется естественным поведением. Хотелось бы узнать: какими соображениями руководствовались разработчики утилиты ls, если сочли такое поведение естественным?  Обладает ли таким поведением только утилита ls из QNX или это характерно для всех клонов Unix?
С уважением,
Казаков С.А.
Записан
Олег Большаков
Легенда

Сообщений: 3140



« Ответ #5 : 19 Февраль, 2018, 13:38:50 »

Здравствуйте, Сергей Алексеевич!

Утилита ls использует функции семейства *stat() для определения существования файла. В указанном Вами примере используется lstat(). Функции stat() и lstat() открывают файл, т.е. отправляют сообщение типа _IO_CONNECT. Делается это не просто так, а в виде комбинированного сообщения _IO_CONNECT_COMBINE_CLOSE. В своей реализации функции io_open() на основании поля subtype структуры io_open_t Вы можете выяснить, что используется вызов stat() или lstat(), и обработать это сообщение особым образом.

Более подробная информация содержится в справочной подсистеме QNX 6:

 - Combine Messages (описание _IO_CONNECT_COMBINE_CLOSE)
 - Описание структуры _io_connect
Записан
Андрей Докучаев
Сотрудник СВД ВС
Легенда

Сообщений: 1076



WWW
« Ответ #6 : 19 Февраль, 2018, 13:54:53 »

Поэтому, на мой взгляд, очевидно, что обработчик io_open та самая подпрограмма, в которой следует разрешать прерывания, сбрасывать регистры состояния, инициировать указатели буферов и проделывать подобные важные операции

Именно по причине того, что любая программа в системе при определенных обстоятельствах может захотеть открыть зарегистрированный ресурс-менеджером префикс, инициализация аппаратных ресурсов в обработчике io_open() в большинстве случаев не является хорошей практикой. Это можно сделать либо однократно при запуске драйвера, либо в том случае, когда становится понятным, что для конкретного клиентского процесса подобные действия действительно необходимы.

Ошибка в Вашем подходе кроется в самом первом предложении в этой теме:

В разрабатываемом мною Resource Managerе есть стандартный вход при открытии файла:

Ассоциированная с ресурс-менеджером сущность не является файлом, она называется префикс. При определенных условиях она может выглядеть как файл, при определенных условиях она может быть как директорией, так и устройством. При этом в libc нет разных API на каждый возможный случай и все представленные сценарии реализуются в рамках общего подхода. Кроме того, libc не ограничивает количество открытых сессий клиентских приложений с ресурс-менеджером. В этом случае написанный подобным образом обработчик io_open() будет создавать чрезмерное число обработчиков прерываний.
Записан

KA3AKOB
Пользователь

Сообщений: 55


« Ответ #7 : 19 Февраль, 2018, 17:50:08 »

Спасибо за ответы, уважаемые Олег и Андрей. По поводу того, что: "Утилита ls использует функции семейства *stat() для определения существования файла.", поработаю, буду разбираться.
По ответу Андрея, сразу возникает вопрос: если io_open, не лучшее место для разрешения прерываний, то значит ли это, что не наилучшим, но более подходящим местом для разрешения прерываний является запуск драйвера? Если прерывания разрешить сразу при запуске, а попытаться читать данные функцией read() когда-либо позже, то буфера приёмника переполнятся очень быстро и надо будет при каждом чтении read'ом проверять буфера на переполнение. Такая логика? Такая ли логика и у /dev/ser*?
Что касается префикса, то да, убедительно. Правда, не до конца понятно, как быть с множественными открытиями и неблокирующим чтением. Буду думать, спасибо.
С уважением,
Казаков С.А.
Записан
Андрей Докучаев
Сотрудник СВД ВС
Легенда

Сообщений: 1076



WWW
« Ответ #8 : 19 Февраль, 2018, 18:54:55 »

но более подходящим местом для разрешения прерываний является запуск драйвера?

Этот фрагмент кода по описанным причинам может быть более подходящим. По большому счету, libc позволяет реализовать даже условно "плохие" практики. Однако нужно четко понимать последствия и влияние на работоспособность системы в будущем.

Если прерывания разрешить сразу при запуске, а попытаться читать данные функцией read() когда-либо позже, то буфера приёмника переполнятся очень быстро и надо будет при каждом чтении read'ом проверять буфера на переполнение.

Здесь нужно исходить из особенностей работы конкретного железа. Например, программный буфер может быть увеличен и данные в отсутствии клиента могут отбрасываться. Также можно организовать разделяемую память между клиентом и сервером во избежание излишнего копирования. Вариантов здесь очень много может быть.

Записан

Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP © 2002-2024 СВД Встраиваемые Системы.
При использовании материалов сайта ссылка на forum.kpda.ru обязательна.

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines | © Aiwan. Kolobok smiles | Sitemap
Valid XHTML 1.0! Valid CSS!
Сайт СВД ВС

В последний раз google посещал эту страницу 24 Декабрь, 2020, 15:47:08