Comments 24
Возможно, вместо FNDELAY корректнее использовать O_NONBLOCK.
man fcntl
F_SETFL (int)
Set the file status flags to the value specified by arg. File access mode (O_RDONLY, O_WRONLY,
O_RDWR) and file creation flags (i.e., O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) in arg are ignored.
On Linux, this command can change only the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK
flags. It is not possible to change the O_DSYNC and O_SYNC flags; see BUGS, below.
Если посмотреть файл
/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h
, то увидим там такое:# define FNONBLOCK O_NONBLOCK
# define FNDELAY O_NDELAY
Далеко за примером ходить не надо, внутри смартфона, лежащего у вас в кармане, будет с десяток UART интерфейсов, самый известный из которых — это подключение SIM-карты.Пример с SIM-картой как раз неудачный — там используется синхронный интерфейс передачи данных, который больше похож не на UART, а на I2C: есть двунаправленная линия передачи данных и отдельный сигнал тактирования.
Подозреваю там USART, который тогда уж больше похож на SPI.
Сразу скажу, что T0 как две капли воды похож на UART (он используется в передаче по COM-порту). Но с небольшими оговорками. Начнем с самого начала.
В каком месте I2C синхронный?
Шина I2C синхронная, состоит из двух линий: данных (SDA) и тактов (SCL).
Возвращает дескриптор (описатель) открытого файла, число больше нуля. В любом другом случае – это ошибка открытия файла.
open(2) — Linux manual page
The return value of open() is a file descriptor, a small, nonnegative integer that is an index to an entry in the process's table of open file descriptors.
Если количество count равно нулю, то
read(
) возвращает это нулевое значение и завершает свою работу.
Не так безобидно, см.
read(2) — Linux manual page
If count is zero, read() may detect the errors described below. In the absence of any errors, or if read() does not check for errors, a read() with a count of 0 returns zero and has no other effects.
например
EFAULT buf is outside your accessible address space.
On error, -1 is returned, and errno is set to indicate the error. In this case, it is left unspecified whether the file position (if any) changes.
По поводу фотографии в начале поста . Работал на таком в молодости. Но мне больше нравился такой как на фотографии ниже (справа). На него можно было пиво поставить.
![](https://habrastorage.org/getpro/habr/upload_files/02f/894/9b5/02f8949b57093e3416ebd51ed818e2b1.jpg)
Вы осознаёте теперь всю сложность работы с COM-портом? При этом мы не разобрали даже половины его возможностей, а уже это оказывается дико сложным.
Теперь осознал. Буду требовать повышения зарплаты.
Да очень просто, если у вас режим передачи RS-485 управляется линией DTR/RTS, либо GPIO, то вы должны точно знать, когда данные были отправлены, чтобы правильно выставить эти пины, меняя режим передачи на приём.
С RS-485 в линуксе всё обстоит неважно. Этот интерфейс совершенно не стандартизирован, и каждый производитель может делать всё, что захочет. Где-то его нужно инициализировать в ядре, и драйвер ядра будет автоматически переключать приёмо-передатчик, где-то это всё реализовано аппаратно.
По моему скромному мнению управлять направлением RS485 линией DTR/RTS - не слишком хорошее решение, а для линукса, даже на уровне драйвера ядра (если в контроллере нет аппаратной поддержки), практически невозможное. Поскольку линукс не система реального времени, а живёт как подобного рода системы богатой внутренней жизнью, то гарантировать заданное время переключения невозможно и в этом случае работают только внешние аппаратные решения.
По моему скромному мнению управлять направлением RS485 линией DTR/RTS — не слишком хорошее решение, а для линукса, даже на уровне драйвера ядра (если в контроллере нет аппаратной поддержки), практически невозможное. Поскольку линукс не система реального времени, а живёт как подобного рода системы богатой внутренней жизнью, то гарантировать заданное время переключения невозможно и в этом случае работают только внешние аппаратные решения.
В современных реалиях это будет достаточно быстро. Хотя, без сомнения решение кривое. Проблема в том, что оно часто встречается в аппаратной реализации.
Согласен. Похоже, что это нужно на уровне драйвера решать - отлавливать прерывание о том, что TX-FIFO пуста (если она есть) и регистр данных тоже пуст и тогда уже переключать направление. Правда не уверен, что такое возможно на ПК, т.к. с ними ни разу не работал с UART'ами - только arm cortex-m[0,3,4]
Правда не уверен, что такое возможно на ПК, т.к. с ними ни разу не работал с UART'ами — только arm cortex-m[0,3,4]
Всё зависит от аппаратной реализации. Сейчас чаще шнурки на USB на базе FTDI
Работа с СОМ-портом на Си в linux