
Я работаю с машиной ARM, у которой зуммер подключен к выводу GPIO 102. Машина работает под управлением Linux 2.6, поэтому у нас есть интерфейс sysfs к выводам в /sys/class/gpio. Когда я впервые попытался заставить работать зуммер, я попробовал что-то вроде следующего:
# cd /sys/class/gpio
# echo 102 > export
# cd gpio102
# echo out > direction
# echo 1 > value
К моему ужасу, машина не издала ни звука. Однако, проверив исходный код драйвера зуммера, написанного для WinCE, я заметил, что мультиплексор GPIO должен был быть установлен в определенный режим. Я не очень хорош в вещах за пределами программного обеспечения, поэтому я все еще не совсем уверен, что это значит. Однако, поскольку мне дали исходный код версии U-Boot, используемой для загрузки Linux на машине, я смог отредактировать его, чтобы установить режим банка GPIO, добавив эту строку кода в заголовочный файл платы ( u-boot/board/somecompany/someboard/someboard.h
):
MUX_VAL(CP(CCDC_DATA3), (IDIS | PTD | DIS | M4));
Я перекомпилировал загрузчик, скопировал его, перезагрузил машину и снова запустил мой тест выше, и он заработал! Я думал, что выполнил свою задачу. Однако мне сообщили, что способ, которым я это сделал, может быть небезопасным, поскольку банк GPIO может использоваться для других драйверов. Когда я монтирую debugfs и проверяю /sys/kernel/debug/gpio
, оказывается, что другие контакты GPIO в банке GPIO используются для драйверов.
Затем я попробовал другой подход — поскольку звуковой сигнал в основном важен при загрузке, я решил попробовать добавить в загрузчик код для подачи звукового сигнала:
MUX_VAL(CP(CCDC_DATA3), (IDIS | PTD | DIS | M4));
if(!gpio_request(102, "buzzer")){
gpio_direction_output(102, 1);
udelay (500000);
gpio_direction_output(102, 0);
}
MUX_VAL(CP(CCDC_DATA3), (IEN | PTD | DIS | M0));
Это работает, поскольку загрузчик однопоточный, поэтому ему не нужно бороться за банк GPIO. Последняя строка сбрасывает режим мультиплексирования банка GPIO на тот, который был установлен ранее в коде.
Он успешно издает звуковой сигнал во время выполнения загрузчика, и, насколько я могу судить, не мешает никаким драйверам, поскольку банк GPIO восстанавливается до требуемого состояния. Однако, это не так полезно, как мне бы хотелось, поскольку звуковой сигнал во время последовательности загрузчика не обязательно означает, что полная загрузка прошла успешно. Вместо этого было бы гораздо лучше, если бы я мог получить доступ к звуковому сигналу из Linux, чтобы указать на успешную загрузку или другие события. Однако мне не удалось найти документацию по настройке режима мультиплексирования банка GPIO в Linux. Поэтому мой вопрос заключается в следующем:
Есть ли способ установить режим мультиплексирования банка GPIO из пространства ядра?