Skip to content

FreeBSD драйвер для приёмника кодов с пульта управления 433МГц (или 315 МГц)

FreeBSD kernel driver for gpio based remote control codes receiver. Я рад представить свой новый FreeBSD драйвер для радиомодуля MX-RM-5V. Хочу заострить внимание, что это приёмник радио сигнала - моя задача была именно в получении кода нажатой кнопки с пульта управления и выполнения соответствующей этому коду задачи. Драйвер, как раз, и занимается получением и декодированием радио импульсов до того момента, пока не сочтёт, что получилось что-то похожее на RC-код. Поиском соответствующей задачи и её выполнением будет заниматься отдельный сервис (aka daemon), который большую часть времени проводит в ожидании события kevent (или poll) от драйвера. Получение данного события для демона означает, что у драйвера для него есть новый код, который можно считать непосредственно с символьного устройства драйвера или с помощью вызова ioctl(). В моём случае, пара драйвер и демон, служит для ручного включения и выключения света и аэрации аквариума, которые в обычном режиме управляются по расписанию моим OrangePI Zero. "Апельсинка" скрыта от посторонних глаз за аквариумом, а для ручного управления используется 4х-кнопочный пульт rf-433МГц от китайских настенных выключателей "miniTiger", закреплённый в распечатанном на 3D-принтере держателе.
Почему именно драйвер:
  • Я понял, как их писать! Почему бы и нет?
  • Я не нашёл другого похожего решения для FreeBSD, ну не ESP866 же прикручивать для такой ерунды?
  • Хотелось бы получить "механизм", которым можно пользоваться при минимальных навыках программирования, например из bash. Не обязательно ожидать событий kevent или poll, можно просто опрашивать символьное устройство приёмника в цикле, пока не будет считана строка с кодом;
  • Я так и не смог воспроизвести GPIO-прерывания на уровне пользователя, тогда как реализация прерываний на уровне ядра есть в /usr/src/sys/dev. Кроме того, мне видится, что более корректно проводить обработку прерываний на уровне ядра, а пользовательскому процессу предоставить готовый результат, в данном случае, готовый код.

Скачать драйвер можно отсюда: https://gitlab.com/alexandermishin13/rcrecv-kmod.

Для сборки драйвера Вам понадобится исходный код ядра (Именно Вашей версии ядра, хотя возможна успешная сборка при незначительной разнице в версиях). Как его получить - тема для отдельной статьи, уверен, что кто-то её уже написал, поищите в Интернете... Я, к примеру, собираю FreeBSD для своих ARM-компьютеров на AMD64 ПК, делаю zfs snapshot и монтирую его на ARM ПК с помощью NFS. Подойдет и флешка с исходниками FreeBSD, смонтированная в /usr/src.

В общем случае для сборки драйвера следует выполнить следующие команды:
CODE:
make depend # If Your platform haven't DTS enabled You can skip next line (keep opt_platform.h empty) echo "#define FDT 1" > opt_platform.h make sudo make install


Чаще всего для настройки GPIO-пина для подключаемого приёмника рекомендуемый способ - FDT-оверлей, но в некоторых системах единственный способ это редактирование файла /boot/device.hints. В этом случае Вы можете не выполнять строку с #define FDT 1, немного уменьшив таким образом размер драйвера.

Настройка с помощью FDT-оверлея


Для создания своего FDT-оверлея скопируйте какой-нибудь из dtso-примеров в папке ./fdt-overlays/ в файл с расширением dtso и отредактируйте строки с ключевыми словами: compatible, pins, gpios в соответстивии с вашими потребностями и выполните команды в этой папке:
CODE:
make sudo make install

Создайте или допишите переменную в /boot/loader.conf для автоматической загрузки оверлея, например:
CODE:
fdt-overlays=overlay1,overlay2,sun8i-h3-rcrecv-gpio


Настройка с помощью файла /boot/device.hints


Для файла /boot/device.hints создайте новый или добавьте в него строки:
CODE:
hint.rcrecv.0.at="gpiobus0" hint.rcrecv.0.compatible="rcrecv" hint.rcrecv.0.pin_list="13"

Измените номер пина в примере на реальный номер используемый для подключения приёмника.

Перезагрузка...


Перегрузите ARM-компьютер и попробуйте загрузить драйвер:
CODE:
kldload rcrecv

Если всё прошло хорошо, появится символьное устройство /dev/rcrecv. Если вы пошлёте rc-код на той же частоте, на которой работает Ваш приёмник, то при чтении из устройства Вы получите строку с шестнадцатиричным представлением этого кода:
CODE:
cat /dev/rcrecv

Процедура считывания кода очищает буфер устройства для получения следующего кода.

Самое время писать ПО для анализа получаемых кодов и выполнения заданных процедур.
Со своей стороны я могу предложить готовый сервис, который:
  • читает код с устройства;
  • проверяет код на совпадения с заданным списком;
  • производит переключение заданного для данного кода пина.
Возможные операции с пином: set, unset, toggle. После успешной обработки кода выдерживается настраиваемая пауза (по умолчанию, 1 сек.) для игнорирования повторных (одинаковых) кодов.
Скачать сервис можно отсюда: https://gitlab.com/alexandermishin13/rcrecv-daemon

Успехов!

Обратные ссылки

Нет обратных ссылок

Комментарии

Показывать комментарии Как список | Древовидной структурой

Нет комментариев.

Добавить комментарий

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
To leave a comment you must approve it via e-mail, which will be sent to your address after submission.
Опции формы

Добавленные комментарии должны будут пройти модерацию прежде, чем будут показаны.