Имитация сбоя драйвера устройства в Linux. Сделайте, чтобы питон перезагрузил это - PullRequest
2 голосов
/ 11 февраля 2010

У меня есть веб-камера, работающая в Linux с использованием модуля uvcvideo. И я использую приложение Python для доступа к веб-камере и отображения изображения.

Я хочу, чтобы программа python справилась с этим, если веб-камера по какой-то причине больше не работает. Протестировали только с разгрузкой модуля. Работает нормально, если я просто выгрузил модуль перед запуском кода на python, но если принудительно выгрузить его при использовании, я получу следующий отзыв.

VIDIOC_DQBUF: Inappropriate ioctl for device

И если я убью код python и перезапущу его, вся машина зависнет.

Код, который я пытаюсь запустить:

import pygame
import Image
from pygame.locals import *
import sys
import time, os

import opencv
from opencv import highgui 

camera = highgui.cvCreateCameraCapture(0)
fps = 10.0
pygame.init()
window = pygame.display.set_mode((640,480))
pygame.display.set_caption("WebCam Demo")
screen = pygame.display.get_surface()

while True:
 events = pygame.event.get()
 for event in events:
  if event.type == QUIT or event.type == KEYDOWN:
   sys.exit(0)
 while True:
  try:
   ima = highgui.cvQueryFrame(camera)
   im = opencv.adaptors.Ipl2PIL(ima)
   break;
  except TypeError:
   print 'No camera'
   os.system('sudo modprobe uvcvideo')
   time.sleep(1)
   camera = highgui.cvCreateCameraCapture(0)

 pg_img = pygame.image.frombuffer(im.tostring(), im.size, im.mode)
 screen.blit(pg_img, (0,0))
 pygame.display.flip()
 pygame.time.delay(int(1000 * 1.0/fps))

Это модифицированная версия http://www.jperla.com/blog/2007/09/26/capturing-frames-from-a-webcam-on-linux/ Используется openvc версии 1.x, а не 2.x.

Есть идеи, как заставить это работать?

Ответы [ 3 ]

4 голосов
/ 11 февраля 2010

Вы имеете в виду USB-камеру? Я не знаю о принудительной выгрузке, когда модуль используется, но этого не произойдет, и это не очень хорошая симуляция того, что камера больше не работает. Попробуйте сначала аккуратно обработать и отключить камеру.

Я не знаю, чего вы пытаетесь достичь при симуляции сбоя драйвера, но вы не можете обработать сбой драйвера, который может привести к ошибкам или чему-либо другому, с помощью пользовательского кода. Не существует защитного программирования, которое могло бы спасти вас, когда код ядра стал диким.

Теперь, если в коде драйвера возникает ошибка (ошибка отличается от сбоя), ее следует вернуть вам, и все, что вы можете сделать, это повторить попытку или выйти. Если ваше приложение предназначено для использования любой камерой UVC, купите USB-камеру, соответствующую UVC, и поиграйте с ней (отключите / переподключите).

Что касается аппаратного сбоя, вы ничего не можете сделать, кроме, возможно, установки таймаута. Что вы можете сделать в своем коде, так это то, что если вы обнаружите специфическую проблему с драйвером, избегите вызова этой специфической проблемы. Например, если известно, что изменение разрешения x на разрешение y приводит к зависанию камеры или к отказу драйвера, то избегайте этого.

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

2 голосов
/ 12 февраля 2010

Причина, по которой ваш код теперь дает сбой, заключается в том, что при сбое драйвера специальные файлы устройства, представляющие ваше оборудование, исчезают. В вашем коде все еще есть дескрипторы открытых файлов для этих устройств В зависимости от того, что именно ваш код делает за кулисами, он, вероятно, пытается выдать IOCTL для недопустимого дескриптора файла, который обычно не обрабатывается библиотечным кодом, потому что это должно происходить только в таком случае, как этот с какой-то ошибкой в ​​ядре земли, код пользовательской земли в любом случае ничего не может сделать.

Работа с камерой, если она перестает работать, совершенно иная, чем при сбое драйвера. Неисправная камера никогда не должна снимать (правильно написанный) драйвер. Если драйвер выйдет из строя, ваш пользовательский код мало что сможет с этим поделать. Да и не должно. Если драйвер выходит из строя, это проблема авторов, а не ваша. Если у вас есть драйвер, который часто ломается на вас, и вы испытываете желание попробовать его обработать, то я бы выбрал другой драйвер или попытался исправить тот, который вы используете. Никакое количество кода приложения не исправит неисправный драйвер.

Не забывайте, что ваш код не единственный код, использующий драйвер. Внутренние процессы ядра или другие приложения также могут использовать драйвер. Если что-то еще использует драйвер при его извлечении, вы можете заставить этот другой код зависать (вне вашего контроля) и потенциально разрушать всю систему.

Теперь, если у вашей веб-камеры есть проблема, драйвер должен изящно дать вам сообщение или ошибку какого-либо рода, которую код вашего приложения может обнаружить и обработать, одновременно выполняя свою работу, чтобы заставить камеру работать снова. Отказ оборудования не должен создавать нагрузку на код приложения; пусть водитель выполнит свою работу, и он по возможности вернет камеру в рабочее состояние. Если это не удается сделать, то либо камера находится в неисправимом состоянии, либо у драйвера есть место для улучшения (в этом случае предложение разработчикам драйверов протестировать их код на вашем оборудовании иногда может быть быстрым. способ улучшить поддержку драйверов для вашего устройства).

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

1 голос
/ 11 февраля 2010

Linux действительно не нравится, когда вы пытаетесь удалить драйвер ядра, когда его используют все процессы. Я не уверен, что для вашего пользовательского приложения есть какой-то хороший способ сделать это (и попытка вашего приложения запустить 'sudo modprobe uvcvideo' уже достаточно страшна).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...