Главная

Разработка BeOS Драйвера Устройств Наметки и Информация

просьба не закидывать камнями, а указать на неточности в переводе(с указанием своего перевода), в местах в которых смысл потерян или смысл оказался совсем другой, а не тот что в оригинальной статье.
http://www.bedrivers.com/usingandwritingdriversonbeos.html

следующий перевод постараюсь закончить и выложить завтра

А вот и сам перевод.

Разработка BeOS Драйвера Устройств Наметки и Информация

Данный документ — попытка научить разрабатывать драйвера устройств для BeOS (и BeIA) операционных систем. Он также полезен разработчикам приложений, которые непосредственно работают с драйверами устройств. Сначала я расскажу о драйвере устройства.

Использование Драйверов устройств в BeOS

Обычно, приложение пользовательского уровня не используют BeOS драйвер устройства напрямую, вместо этого используются некоторые высокоуровневые API, которые вызывают пользовательские add–on, в свою очередь которые вызывают драйвер. Однако, это не мешает приложению напрямую обращаться к драйверу подобно соответствующему add–on; действительно, в некоторых случаях это не соответствующий add–on API и ты можешь передавать драйверу напрямую из приложения. Это также полезно передавать напрямую в драйвер, пока драйвер разрабатывается и тестируется. Мы будем вызывать объект (приложение или add–on) использующий драйвер — в качестве <клиента> драйвера.
Сначала ищется устройство. Драйвер будет передавать одно или несколько устройств в поддиректории в «/dev». Например, sonic_vibes аудио карты, драйвер передает в /dev/audio/raw/sonic_vibes/ так же как и в другие местоположения. Потому что большинство BeOS драйверов поддерживают больше чем одну установленную карту одного вида, условные номера установленных карт начинаются с 1. Таким образом, первая установленная sonic_vibes карта найдется как /dev/audio/raw/sonic_vibes/1. Ты можешь использовать BDirectory класс или C функцию opendir() для поиска через директорию свободного устройства.
Раз ты знаешь какое устройство ты хочешь использовать, тебе нужно открыть его используя функцию С open() вызвав:
int fd = open(«/dev/audio/raw/sonic_vibes/1», O_RDWR);
Впредь ты будешь использовать ссылку на файловый дескриптор для открытия устройства. Файловый дескриптор необходимо будет закрыть функцией close(), когда закончишь с ним работу. Если процесс(team), который открыл устройство, разрушится или закончится без закрытия файлового дескриптора, он будет закрыт kernel'ом(ядром) и собран в мусор.
Многие устройства осуществляют чтение read() и запись write() протоколов. Таким образом, чтобы записать аудио из входного источника выбранного по умолчанию, используй raw–аудио файловый дескриптор открытый выше, сделай так:
short * data = (short *)malloc(200000);
ssize_t rd = read(fd, data, 200000);
“rd” будет содержать число байт успешно прочитанных, или -1 в случае ошибки (что за ошибка thread–local macro “errno” будет содержать код ошибки).
Формат данных возвращаемых устройством, у каждого устройства различен; по умолчанию формат sonic_vibes драйвера — стерео 16–bit signed native–endian 44.1 kHz PCM sample data. Проиграть назад эти данные можно используя вызов write():
ssize_t wr = write(fd, data, rd);
“wr” будет содержать число успешно записанных байт или -1 в случае ошибки, “errno” при этом будет содержать код ошибки.
Многие устройства не работают хорошо с простым read() и write() протоколом; например, video capture карты часто требуют смежную заблокированную область памяти, которая обычно не находится в буфере и проходит мимо read() и write(). Затем ты можешь обработать свой твой протокол изменив настройки ioctl(). Существуют число точно–определенных ioctl() значений, которые твое устройство может обработать, если они имеют смысл для класса устройств, с которыми ты работаешь; специальные поддиректории в /dev могут требовать определенные в ioctl() протоколы которые должны быть выполнены (такие как s /dev/joystick, /dev/midi, или /dev/audio).
Допустим что мы используем video capture драйвер с таким вот протоколом: enum {
drvOpSetBuffers = B_DEVICE_OP_CODES_END+10001,
drvOpStart,
drvOpStop,
drvOpWaitForFrame,
};
struct drv_buffer_info {
color_space in_space;
int in_width;
int in_height;
int in_rowbytes;
void * in_buffers[2]; /* even, odd */
};
struct drv_frame_info {
int out_frame_number;
};
Клиент должен сконфигурировать драйвер, например так:
drv_buffer_info buf_info;
buf_info.in_space = B_YUV422;
buf_info.in_width = 640;
buf_info.in_height = 240;
buf_info.in_rowbytes = 640*2; /* 422 is 16bpp */
area_id buf_area = create_area(«capture buffers», &buf_info.in_buffers[0],
B_ANY_ADDRESS, buf_info.in_rowbytes*buf_info.in_height*2,
B_CONTIGUOUS, B_READ_AREA|B_WRITE_AREA);
buf_info.in_buffers[1] = ((char *)buf_info.in_buffers[0])+buf_info.in_rowbytes*buf_info.in_height;
int err = ioctl(fd, drvOpSetBuffers, &buf_info);
if (err == -1) err = errno;
И запустить захват видео так:
int err = ioctl(fd, drvOpStart);
if (err == -1) err = errno;
затем ожидать каждый кадр так:
while (running) {
drv_frame_info frm_info;
int err = ioctl(fd, drvOpWaitForFrame, &frm_info);
if (err == -1) err = errno;
process_frame(frm_info.out_frame_number, buf_info.in_buffers[frm_info.out_frame_number & 1]);
}
В конце остановить захват так:
int err = ioctl(fd, drvOpStop);
if (err == -1) err = errno;
В реальной жизни, типичный протокол способен на большее, и поэтому он более сложен, чем рассмотренный здесь, но этого будет достаточно что бы иметь представление о структуре протокола между user–level клиентом и драйвером.Также в реальной жизни драйвера знают лучше об их буферных требованиях, чем приложения, так, скорее всего, API будут иметь возможность в ioctl() изменять буфер(ы) и возвращать информацию о нем(них) клиенту, чем клиент будет говорить драйверу, какой буфер(ы) использовать.

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Allowed HTML tags: <a> <em> <i> <img> <strong> <b> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Строки и параграфы переносятся автоматически.

Подробнее о форматировании

CAPTCHA
Введите перечисленные символы, чтобы мы убедились, что вы не робот. Не требуется для зарегистрированных пользователей.
L
v
m
K
5
Z
Enter the code without spaces and pay attention to upper/lower case.