Не получается асинхронное получение данных от драйвера
|
|
mashakovmarat | Дата: Понедельник, 12.08.2019, 14:47 | Сообщение # 1 |
Сержант
Группа: Пользователи
Сообщений: 36
Статус: Offline
| Здравствуйте.
Есть Raspberry с минимальной начинкой, т.е. ось Raspbian, X-сервер, но никакого GUI (он не нужен). К контроллеру через USB подключен тачскрин. Моя программа прописана в автозагрузке контроллера.
В самом начале никак не получилось запустить доступными штатными средствами драйвер тачскрина, поэтому решил написать его самостоятельно на FB. Это получилось, тачскрин работает корректно, но есть большое "НО".
Чтобы было понятно, распишу как организована работа: - Через OPEN PIPE при помощи cat читаю соответствующий тачскрину файл /dev/input/event*. - Как ни странно, но стабильно работает только если открывать поток при помощи INPUT, через BINARY ничего не получается. - Далее при помощи GET забираю пакет данных и расколдовываю его. Как бы все. - Суть в том, что как только поток от драйвера тачскрина исчерпывается, программа останавливается на GET и ждет данных. Соответственно, как только поводишь/потыкаешь пальчиком по экрану, данные снова побежали, программа снова пошла работать до очередного прекращения поступления данных от драйвера. - Но у программы есть другие задачи кроме обработки тачскрина, и вот в эти моменты все остальные задачи тоже останавливаются. Это и есть большое "НО".
Как пытался бороться: - пробовал отслеживать длину файла event при помощи LOF (не работает, всегда длина равна нулю); - пробовал BINARY доступ; это, кстати, дает возможность проскакивать GET даже если с тачскрином ничего не делаешь, но почему то, при BINARY чтении ничего не читается; - попробовал вынести блок чтения GET с последующим парсингом пакета в отдельный поток, но это задачи не решает - нужно дождаться завершения потока Threadwait и только потом уходить на очередную итерацию. Пробовал также применить Threaddetach, но плюс-минус та же самая проблема - GET останавливает всю программу при прекращении потока данных от драйвера.
В некотором смысле понимаю, что-то делаю криво (например, с потоками раньше не особо работал, хотя туториалы в хелпе понятные и все нормально).
Как бы BINARY кажется перспективным направлением движения, но почему он не дает данных при чтении - пробовал читать и блочно, и просто отдельные байты - файл словно пустой. Хотя это не так - параллельно запущенный cat показывает обратное.
Писать обработчик полученного пакета на bash не хотелось бы.
Может кто сталкивался с подобным?
|
|
| |
DarkDemon | Дата: Среда, 14.08.2019, 11:38 | Сообщение # 2 |
Полковник
Группа: Друзья
Сообщений: 200
Статус: Offline
| Цитата mashakovmarat ( ) Может кто сталкивался с подобным?
Сталкивался с остановом ввода только в сообщениях винды. Гарантированно лечится запуском этого процесса в отдельном потоке. Но организация этого процесса не всегда тривиальна. Как в линуксе - хз. Под виндой встроенного функционала не хватало, приходилось лезть в WinAPI.
|
|
| |
mashakovmarat | Дата: Четверг, 15.08.2019, 12:22 | Сообщение # 3 |
Сержант
Группа: Пользователи
Сообщений: 36
Статус: Offline
| Цитата DarkDemon ( ) Гарантированно лечится запуском этого процессав отдельном потоке. Но организация этого процесса не всегда тривиальна. Как в линуксе - хз. Под виндой встроенного функционала не хватало, приходилось лезть в WinAPI. Решил еще раз попробовать вынести работу с тачскрином в отдельный поток, который бы существовал весь цикл работы основной программы. Но, увы, опять пришел к ситуации, когда GET# при пустом stdout останавливает и дополнительный поток, и программу в целом. Есть еще одна мысль (пришла только что) относительно потоков, но пока не озвучу, для начала попробую. О результатах напишу.
DarkDemon, спасибо за содействие.
|
|
| |
WQ | Дата: Четверг, 15.08.2019, 13:27 | Сообщение # 4 |
Полковник
Группа: Проверенные
Сообщений: 215
Статус: Offline
| Примерный код бы посмотреть
Под linux для межпоточного общения вроде можно использовать те же PIPE, хотя они обычно для взаимодействия между процессами
А в крайнем случае можно и 2 процесса создать: программа запускается и запускает саму себя еще раз
В некоторый таких задачах еще помогает использование таймеров
|
|
| |
mashakovmarat | Дата: Четверг, 15.08.2019, 21:18 | Сообщение # 5 |
Сержант
Группа: Пользователи
Сообщений: 36
Статус: Offline
| Цитата WQ ( ) Под linux для межпоточного общения вроде можно использовать те же PIPE, хотя они обычно для взаимодействия между процессами Сегодня весь день на линуксовские пайпы как раз и налегал, но все равно, пока от /dev/input/event* не идет stdout все остальное замирает. Как "измерять" stdout от /dev/input/event* через bash, чтобы понимать что в данный момент происходит, ума не приложу.
Цитата WQ ( ) А в крайнем случае можно и 2 процесса создать: программа запускается и запускает саму себя еще раз Не знаю, говорите ли вы о потоках, или все же процессы Linux. Сегодня попробовал разносить в разные дополнительные потоки и считывание stdout от event*, и, как бы, основной код программы, все равно, при исчерпании поступающего stdout все замирает и ждет, чтобы по тачскрину поводили пальчиком. Вот если бы поток с GET# можно было сделать фоновым...
Цитата WQ ( ) В некоторый таких задачах еще помогает использование таймеров По поводу таймеров можно подумать.
Думаю, как вариант, можно поработать через пользовательскую переменную окружения. Т.е. повесить демона, который и будет работать с потоком от cat, ну и назначать этой переменной окружения требуемые значения. А фрибейсиком уже просто читать текущие значения переменной. Но опять-таки не знаю, будет ли этот демон работать как надо. Попробую.
Нашел упоминания, что stdout - это текстовой/строкой поток. Может поэтому через BINARY не получается его достать. Кроме того, в help-е для OPEN PIPE есть информация, что BINARY доступ не реализован на некоторых платформах. А у меня получается ARM. А жаль ))
|
|
| |
DarkDemon | Дата: Пятница, 16.08.2019, 20:53 | Сообщение # 6 |
Полковник
Группа: Друзья
Сообщений: 200
Статус: Offline
| Цитата mashakovmarat ( ) Нашел упоминания, что stdout - это текстовой/строкой поток. Может поэтому через BINARY не получается его достать. Кроме того, в help-е для OPEN PIPE есть информация, что BINARY доступ не реализован на некоторых платформах.
Есть предположение, что этот т.н. драйвер просто не поддерживает такой метод. А вообще когда читаешь BINARY допустим файл и пытаешься прочесть именно строку, то эта самая строка должна быть заполнена чем-нибудь, например, пробелами. Сколько надо считать - столько пробелов(или любых других символов). Либо соотв. UDT структура, но её надо знать точно - до байта. Кинь сюда код как ты читаешь, посмотрим может косяк где есть.
Цитата mashakovmarat ( ) Вот если бы поток с GET# можно было сделать фоновым...
Ну а что CreateThread разве не так делает? Или в линуксе потоки как-то через жопу работают?
P.S: В справке по пайпам написано, что BINARY не поддерживается нигде. А ещё там есть пример с EOF. Пайп должен что-то вернуть, если там пусто EOF не даст зациклиться. Пайп можно закрыть и открыть повторно, чтобы обновить статус.
Сообщение отредактировал DarkDemon - Пятница, 16.08.2019, 21:06 |
|
| |
mashakovmarat | Дата: Понедельник, 19.08.2019, 16:54 | Сообщение # 7 |
Сержант
Группа: Пользователи
Сообщений: 36
Статус: Offline
| Цитата DarkDemon ( ) Вот если бы поток с GET# можно было сделать фоновым...Ну а что CreateThread разве не так делает?
Я тоже думал, что таким образом разделю процессы, изолирую друг от друга, но видимо нужно будет убирать работу с event-файлом вообще в другое приложение/демон. Т.е. как поток через CreateThread никак не катит. Видимо здесь имеет место просто режим разделение времени между потоками (CreateThread) в внутри одного приложения. Все же попробую сместить обращение к event в другое приложение. Ну а там смычку через переменную среды пробовать надо. Сегодня попробовал через СИ, т.е. fopen, fread, fgetc, feof - все работает, но также, как если бы через Open Pipe "sudo cat dev/input/event" во Фрибейсике -то бишь, замирает и ждет возобновления потока от устройства. Причем feof никак не помогает, хоть проверяй его после считывания read-ом, хоть до. Все одно 0 (ноль). Можно проверить линуксовский пайп cat > файл, с последующим парсингом этого файла, но чего то так не хочется попусту диск нагружать этим. Тем более это будет выполняться нон-стоп.
Добавлено (22.08.2019, 19:06) --------------------------------------------- Данную ветку можно, как бы, закрыть, поскольку наконец могу точно сформулировать задачу. Новая ветка здесь http://freebasic.ucoz.com/forum/4-457-1 Спасибо.
Сообщение отредактировал mashakovmarat - Четверг, 22.08.2019, 19:06 |
|
| |
|