Глава 12. Интерфейс Proc |
Предыдущая Содержание Следующая |
ALSA предоставляет простой интерфейс для файловой системы procfs. Файлы proc очень полезны для отладки. Я рекомендую вам создавать proc файлы, если вы пишете драйвер и хотите получать статус работы или распечатку регистров. API находится в <sound/info.h>.
Чтобы создать proc файл, вызовите snd_card_proc_new().
struct snd_info_entry *entry; int err = snd_card_proc_new(card, "my-file", &entry);
где второй аргумент указывает имя proc файла, который должен быть создан. В приведённом выше примере будет создан файл my-file внутри каталога карты, например, /proc/asound/card0/my-file.
Как и другие компоненты, запись в proc, созданная через snd_card_proc_new(), будет автоматически регистрироваться и освобождаться в функциях регистрации и освобождения карты.
При успешном создании функция сохраняет новый экземпляр в указателе, указанном в третьем аргументе. Он инициализируется как текстовый proc файл доступный только для чтения. Чтобы использовать данный proc файл как только читаемый текстовый файл, укажите обратный вызов read с закрытыми данными через snd_info_set_text_ops().
snd_info_set_text_ops(entry, chip, my_proc_read);
где второй аргумент (chip) является закрытыми данными, которые будут использоваться в обратных вызовах. Третий параметр указывает размер буфера чтения, а четвёртый (my_proc_read) является функцией обратного вызова, которая определяется как
static void my_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer);
Для вывода строк в обратном вызове read используйте snd_iprintf(), которая работает так же, как обычная printf(). Например,
static void my_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct my_chip *chip = entry->private_data;
snd_iprintf(buffer, "This is my chip!\n"); snd_iprintf(buffer, "Port = %ld\n", chip->port); }
Права доступа к файлам в последствии могут быть изменены. По умолчанию они установлены для всех пользователей как доступные только для чтения. Если вы хотите добавить для пользователя разрешение на запись (по умолчанию root-у), сделайте следующее:
entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
и установите размер буфера записи и обратный вызов
entry->c.text.write = my_proc_write;
Для получения строки текста в обратном вызове write можно использовать snd_info_get_line(), а для получения из неё кусочка строки - snd_info_get_str(). Некоторые примеры можно найти в core/oss/mixer_oss.c и core/oss/pcm_oss.c.
Для proc файла для необработанных данных укажите атрибуты следующим образом:
static struct snd_info_entry_ops my_file_io_ops = { .read = my_file_io_read, };
entry->content = SNDRV_INFO_CONTENT_DATA; entry->private_data = chip; entry->c.ops = &my_file_io_ops; entry->size = 4096; entry->mode = S_IFREG | S_IRUGO;
Обратный вызов является гораздо более сложным, чем версия для текстового файла. Для передачи данных необходимо использовать низкоуровневые функции ввода/вывода, такие как copy_from/to_user().
static long my_file_io_read(struct snd_info_entry *entry, void *file_private_data, struct file *file, char *buf, unsigned long count, unsigned long pos) { long size = count; if (pos + size > local_max_size) size = local_max_size - pos; if (copy_to_user(buf, local_data + pos, size)) return -EFAULT; return size; }
|
Предыдущая Содержание Следующая |