crystal serial
This commit is contained in:
parent
7539e9d5ab
commit
cfed6d44a6
95
content/posts/2023/crystal/accessing-serial-port.md
Normal file
95
content/posts/2023/crystal/accessing-serial-port.md
Normal file
@ -0,0 +1,95 @@
|
||||
---
|
||||
title: "📟 FAQ по доступу к Serial из Crystal"
|
||||
date: 2023-05-16T01:29:30+03:00
|
||||
draft: false
|
||||
tags: [crystal, serial, tips]
|
||||
---
|
||||
|
||||
Перевёл FAQ чувака с SOF, на вопрос работы с Serial в Crystal.
|
||||
|
||||
## Как мне получить доступ к Serial в Linux/BSD?
|
||||
|
||||
Открыть его как файл.
|
||||
В Linux/BSD последовательное соединение устанавливается в тот момент,
|
||||
когда устройство было подключено,
|
||||
и затем отображается в разделе `/dev/` (обычно как `/dev/ttyUSB0`).
|
||||
Чтобы получить доступ к этому соединению, просто откройте его как обычный файл.
|
||||
Иногда этого достаточно, чтобы начать взаимодействовать с устройством,
|
||||
поскольку современное оборудование работает со всеми скоростями и флагами по умолчанию.
|
||||
|
||||
## Как мне настроить устройство Serial/tty в Linux/BSD?
|
||||
|
||||
Необходимо установить флаги [termios](https://linux.die.net/man/3/termios) для файла.
|
||||
Если необходимо для соединения установить такие параметры,
|
||||
как скорость передачи данных в бодах, IXON/IXOFF и т.д.,
|
||||
это можно сделать еще до запуска вашей программы с помощью команды
|
||||
[stty](https://linux.die.net/man/1/stty), если она доступна.
|
||||
Например чтобы установить скорость передачи данных в бодах,
|
||||
необходимо выполнить следующую команду: `stty -F /dev/ttyUSB0 9600`.
|
||||
И после того, как соединение настроено,
|
||||
можно просто открыть соединение как файл и начать использовать.
|
||||
|
||||
Вы можете запустить `stty` из Crystal с помощью
|
||||
`Process.run`, если нужен простой способ настройки устройства из вашего приложения.
|
||||
Я бы, вероятно, порекомендовал этот способо в качестве решения.
|
||||
|
||||
## Как мне установить флаги termios из Crystal, не используя stty?
|
||||
|
||||
Используйте функции `termios` напрямую.
|
||||
Crystal предоставляет FileDescriptor с несколькими
|
||||
распространенными настройками `termios`, такими как
|
||||
[cooked](https://crystal-lang.org/api/1.8.2/IO/FileDescriptor.html#cooked%28%26%3Aself-%3E_%29-instance-method),
|
||||
что означает, наличие минимальных привязок
|
||||
[termios](https://github.com/crystal-lang/crystal/blob/master/src/termios.cr).
|
||||
|
||||
Мы можем начать с использования существующего кода:
|
||||
|
||||
```crystal
|
||||
require "termios"
|
||||
|
||||
# Открываем файл
|
||||
serial_file = File.open("/dev/ttyACM0")
|
||||
raise "Oh no, not a TTY" unless serial_file.tty?
|
||||
|
||||
# Извлекаем unix FD. Это всего лишь цифра.
|
||||
fd = serial_file.fd
|
||||
|
||||
# Извлекаем существующие флаги TTY файла
|
||||
raise "Can't access TTY?" unless LibC.tcgetattr(fd, out mode) == 0
|
||||
|
||||
# `mode` теперь содержит структуру termios. Давайте включим, ммм.. ISTRIP and IXON
|
||||
mode.c_iflag |= (Termios::InputMode::ISTRIP | Termios::InputMode::IXON).value
|
||||
# Давайте также отключим IXOFF.
|
||||
mode.c_iflag &= ~Termios::InputMode::IXOFF.value
|
||||
|
||||
# Обнаружение неисправности: в Termios недоступна скорость cfset[ввода-вывода]
|
||||
# Давайте добавим их, чтобы изменить скорость передачи данных в бодах было не так сложно.
|
||||
lib LibC
|
||||
fun cfsetispeed(termios_p : Termios*, speed : SpeedT) : Int
|
||||
fun cfsetospeed(termios_p : Termios*, speed : SpeedT) : Int
|
||||
end
|
||||
|
||||
# Используйте приведенные выше функции, чтобы установить скорость ввода
|
||||
# и скорость вывода на заданную вами скорость передачи данных в бодах.
|
||||
LibC.cfsetispeed(pointerof(mode), Termios::BaudRate::B9600)
|
||||
LibC.cfsetospeed(pointerof(mode), Termios::BaudRate::B9600)
|
||||
# Пишите свои изменения в FDA.
|
||||
LibC.tcsetattr(fd, Termios::LineControl::TCSANOW, pointerof(mode))
|
||||
|
||||
# Сделано! Ваш дескриптор serial_file готов к использованию.
|
||||
```
|
||||
|
||||
Чтобы установить другие флаги, обратитесь
|
||||
к [руководству](https://linux.die.net/man/3/termios) termios
|
||||
или к этому замечательному
|
||||
[руководству](https://en.wikibooks.org/wiki/Serial_Programming/termios) по Serial,
|
||||
которое я только что нашел.
|
||||
|
||||
## Есть ли библиотека, которая могла бы сделать все это за меня?
|
||||
|
||||
Нет :(. Но было бы здорово, если бы кто-нибудь написал.
|
||||
Вероятно, что написать библиотеку не составит большого труда,
|
||||
если у кого-нибудь будет личный интерес :)
|
||||
|
||||
## Источник
|
||||
- [Crystal-lang Accessing Serial port](https://stackoverflow.com/questions/51069578/crystal-lang-accessing-serial-port) — StackOverFlow.
|
Loading…
Reference in New Issue
Block a user