Как изменить ядро ​​Linux, чтобы оно дольше ждало UART перед возвратом из read()?Linux

Ответить Пред. темаСлед. тема
Anonymous
 Как изменить ядро ​​Linux, чтобы оно дольше ждало UART перед возвратом из read()?

Сообщение Anonymous »

Я считываю данные из UART под управлением Linux 6.1 на встроенном устройстве i.MX6 ULL. Никакого канонического режима, только необработанные данные. termios::c_cc[VMIN] = 0, termios::c_cc[VTIME] = 20, поэтому read() возвращает значение всякий раз, когда получен хотя бы один байт или когда истекает тайм-аут в 20 децисекунд ( Мне очень нужен этот таймаут, см. ниже).

Один пакет размером 200 байт отправляется 100 раз в секунду. Сначала я передаю 200 в read() как количество ожидаемых байтов, затем после того, как вызов read() возвращает количество полученных байтов, в следующий раз я передаю меньшее значение и т. д., пока не будут получены все 200 байтов.

Когда используемая скорость передачи данных составляет 921600 бод, функция read() возвращает 6–12 раз за пакет, т. е. каждый вызов read() считывает примерно 17–33 байта.

Когда используемая скорость передачи данных составляет 921600 бод, функция read() возвращает 6–12 раз за пакет, т. е. каждый вызов read() считывает примерно 17–33 байта.

/>
Когда используемая скорость передачи данных составляет 460800 бод, функция read() возвращает 12-24 раза на пакет.
Итак, мой вывод таков: в коде Linux существует некоторый почти постоянный интервал времени, когда данные, накопленные до возврата read(). Назовем это «временем накопления».

Неудивительно, что процесс переключения 12-24 раз за пакет нагружает процессор ~2 раза больше, чем 6-12 раз (и это серьезная нагрузка для i.MX6 ULL — более 20%). Таким образом, я получаю странную ситуацию, когда мне приходится выбирать между надежностью (более низкой скоростью передачи данных) и загрузкой процессора, в то время как интуитивно низкая скорость передачи данных не должна иметь никаких недостатков.
Как увеличить это «накопление» time" в коде Linux, чтобы дольше ждать перед возвратом из read()? Я понимаю, что это снизит скорость реагирования, но в данной ситуации мне это не так уж и нужно (по крайней мере, мне не нужно). мне не нужно знать, что что-то получено 24 раза за пакет).
На самом деле мне нужна очень простая возможность ядра: разблокировать мой поток только тогда, когда указано количество полученных байтов или когда указано тайм-аут истекает; максимально эффективно.
У меня есть опыт исправления драйверов Linux (например, сборки Linux, подготовки его кода, настройки и расширения DeviceTree и т. д.), но на этот раз я отказался от поиска Значение «времени накопления» (слишком много кода для чтения и понимания), и мне действительно нужна помощь кого-то, кто уже знаком со всем этим кодом.
Я считаю, что значение «времени накопления» обычно имеет значение Linux tty/UART- связанный код или конкретный драйвер UART i.MX6 ULL, поэтому моими первыми точками входа были:

Код: Выделить всё

drivers/tty/n_tty.c
drivers/tty/serial/imx.c
хотя поиск безуспешно.
На случай, если кто-то предложит указать как termios::c_cc[VTIME], так и termios ::c_cc[VMIN]. Когда VMIN не равен 0, значение VTIME фактически отличается: тайм-аут отсчитывается от первого полученного байта, а не от вызова read(). Поэтому, если данные вообще не получены, read() никогда не возвращает результат.
Некоторые дополнительные примечания.

Архитектура нашего приложения подразумевает один выделенный поток для каждый порт UART (мы используем 7 из них, поэтому загрузка процессора так важна). Кроме того, нам необходимо обнаружить остановку отправки данных извне, поэтому использование таймаута termios::c_cc[VTIME] имеет решающее значение. Я понимаю, что цикл потока можно организовать по-другому: спать, скажем, на 100 мс в цикле и каждый раз проверять наличие байтов, доступных в UART; это позволило бы добиться как сбора пакетов, так и реализации таймаута. Но во-первых, у нашего приложения есть несколько нюансов (при необходимости я мог бы объяснить больше), из-за которых это решение весьма чувствительно снижает качество приложения и кодовой базы. И во-вторых, я ожидаю, что ядро ​​сможет реализовать то же самое гораздо эффективнее.

Я протестировал другой подход: вместо использования read() с termios::c_cc[VTIME ], я мог бы подождать в poll() (или epoll()) с таймаутом, переданным в качестве аргумента, и после него вызвать read() с обоими терминами: :c_cc[VMIN] = termios::c_cc[VTIME] = 255. Результаты использования poll() (или epoll()) одинаковы: мой поток разблокирует столько же раз за пакет, что и при использовании метода «голого» read(). На самом деле, в настоящее время я использую в своем коде метод poll(), поскольку он позволяет более точно и динамично контролировать значение тайм-аута; но для того, чтобы задать вопрос, я использовал подход read(), поскольку он демонстрирует проблему более простым способом.
Может быть, было бы приятнее ответить, зная, с каким устройством мы работаем на медицинском (электрокардиография).

Подробнее здесь: https://stackoverflow.com/questions/790 ... -from-read
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как изменить ядро ​​Linux, чтобы оно дольше ждало UART перед возвратом из read()?
    Anonymous » » в форуме Linux
    0 Ответы
    7 Просмотры
    Последнее сообщение Anonymous
  • Станет ли задержка vmalloc ядра Linux дольше, чем в более старой версии?
    Anonymous » » в форуме Linux
    0 Ответы
    18 Просмотры
    Последнее сообщение Anonymous
  • Функция read() в C++ аналогична функции c read()
    Гость » » в форуме C++
    0 Ответы
    138 Просмотры
    Последнее сообщение Гость
  • PHP 7: SessionHandlerInterface::read(string $session_id): строка должна быть совместима с SessionHandlerInterface::read(
    Anonymous » » в форуме Php
    0 Ответы
    43 Просмотры
    Последнее сообщение Anonymous
  • Dma неправильно получает данные от uart в Linux
    Anonymous » » в форуме Linux
    0 Ответы
    28 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Linux»