Передача параметров из приложения alsa в драйвер ядра - PullRequest
1 голос
/ 27 мая 2019

Я пытаюсь проследить путь установки параметров от пользовательского пространства linux (arecord / aplay) до драйвера ядра.Давайте возьмем в качестве примера arecords --period-size.

Все начинается в set_params, функции в aplay.c:

if (period_time > 0)
    err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, 0);
else
    err = snd_pcm_hw_params_set_period_size_near(handle, params, &period_frames, 0);

Функция snd_pcm_hw_params_set_period_size_near() определена в [pcm.c: 5186] (alsa-lib https://github.com/alsa-project/alsa-lib/blob/master/src/pcm/pcm.c#L5186), и вот тут начинается моя головная боль ... Эта функция запускает цепочку вызовов других функций, что для меня не имеет большого смысла и, кажется, не ведетна любой конечный вызов драйвера.

Имеется метка _end, поэтому я пропустил все вызовы, например snd_pcm_hw_param_set_min() или snd_pcm_hw_param_set_max(), и перешел к snd_pcm_hw_param_set_last(), надеясь на какой-нибудь вызов драйвера, например:

drv->hw_params_set(...);

но вместо этого я обнаружил конечный вызов:

MASK_INLINE unsigned int snd_mask_min(const snd_mask_t *mask)
{
    int i;
    assert(!snd_mask_empty(mask));
    for (i = 0; i < MASK_SIZE; i++) {
        if (mask->bits[i])
            return ffs(mask->bits[i]) - 1 + (i << 5);
    }
    return 0;
}

, где возвращаемые значения должны быть набором параметров.

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

Спасибо.

1 Ответ

1 голос
/ 27 мая 2019

Структура hw_params содержит конфигурационное пространство , которое представляет собой описание всех возможных конфигураций, которые может поддерживать устройство.Числовые параметры описываются как интервалы (т. Е. Мин. И макс.), Доступ и формат как битовые маски.

Когда вы изменяете один параметр, библиотека вызывает драйвер ядра (SNDRV_PCM_IOCTL_HW_REFINE) для настройки всех остальных параметров вhw_params структура, которая зависит от измененного параметра.

После того, как вы сократили пространство конфигурации до требуемой конфигурации, вы вызываете snd_pcm_hw_params() (→ SNDRV_PCM_IOCTL_HW_PARAMS), чтобы фактически настроить устройство для этих параметров.параметры.(Если какой-либо параметр не был уменьшен до одного значения, snd_pcm_hw_params() выберет случайное значение.)


snd_pcm_hw_params_set_xxx_near() более сложный, поскольку SET_NEAR ioctl отсутствует.Эта функция пытается настроить интервал так, чтобы его максимум или минимум был желаемым значением, а затем проверить, ближе ли фактический максимум или минимум.

Например, предположим, что устройство поддерживает периоды размером 10242048, 4096 и 8192 кадра.Первоначально интервал описывается как [1024, 8192].Когда вы вызываете snd_pcm_hw_params_set_period_size_near(4000), вспомогательная функция snd_pcm_hw_param_set_near() вызывает set_min(4000) и set_max(4000) (для отдельных копий структуры hw_params), поэтому интервалы составляют [1024, 4000] и [4000, 8192];после уточнения драйвер возвращает интервалы [1024, 2048] и [4096, 8192].snd_pcm_hw_param_set_near() затем видит, что 4096 является ближайшим к требуемому значению, поэтому он вызывает set_first во втором интервале, что приводит к [4096, 4096].

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