Думаю, я понял это.Суть в том, что этот был подлинным переполнением RX из-за того, что мой код недостаточно быстро считывал буферы UART.Когда я достаточно быстро «читаю» последовательный порт, я могу достичь постоянной скорости передачи данных в мегабайтах.Причину, по которой я был полностью введен в заблуждение (и что отправлено странное и неожиданное сообщение FTDI_RS_OE), я объясню ниже.
Несколько замечаний о протоколе, который я использовал.Я отправлял какой-то пакет «запрос» по последовательной линии и ожидал большого ответа.(и делает это в цикле).«Моя ошибка» заключалась в том, что я ожидал, что удаленное устройство ответит очень быстро, а если не остановит обработку.Этот тайм-аут был слишком коротким, но фактический ответ все еще приходил. Затем «некоторый» буфер переполнялся, вызывая переполнение RX.
Но это было не так ясно.Несколько тонкостей:
Счетчик переполнения rx был увеличен только после следующего системного вызова чтения uart (например, через несколько минут, если мой код перешел в неактивное состояние) (НЕ сразу после возникновения проблемы), что очень запутанно)
Я полагал, что, как и драйвер imx6, ядро linux всегда будет просто обслуживать USB-устройство, если поступающие данные будут доступны.И что данные будут отправлены в буфер 640 КБ (определенный https://elixir.bootlin.com/linux/v4.9.192/source/drivers/tty/tty_buffer.c). В драйвере imx6 можно ясно увидеть, что произойдет, если этот буфер переполнится
Но этоЭто не так. Вместо этого, мое лучшее предположение о том, что здесь происходит (я не профилировал / не отлаживал ядро, чтобы убедиться в этом), заключается в том, что происходит последовательное «удушение». Когда эти 640 КБ «заполняются», linux выдастобратный вызов «throttle» к драйверу FTDI, который затем просто использует универсальный usb_serial_generic_throttle, который устанавливает флаг и отбрасывает входящие данные urb в https://elixir.bootlin.com/linux/latest/ident/usb_serial_generic_read_bulk_callback. Это объясняет, почему переполнения не «обнаруживаются», когда инцидент действительно происходит, но неожиданно обнаруживается, когда (например, после 1 минуты бездействия) я перезапускаю операцию чтения. Внутренний буфер FTDI-микросхемы должен быть переполнен из-за этого механизма, в результате чего устанавливается этот флаг FTDI_RS_OE, который затем фактически только правильно анализируется при регулированииснова отключен.
Итак заключение :главная проблема была на моей стороне, но драйвер FTDI неправильно реализует свои счетчики переполнения (они отображаются только «поздно» или даже не в зависимости от варианта использования) из-за, скорее всего, функции регулирования Linux.