Надежность STM32 UART с высокой скоростью передачи данных

Я использую STM32F4 (голое железо с библиотекой HAL) в качестве HTTP-сервера. Я не реализую уровень TCP, потому что это делает для меня модуль WiFi232 D2 — все, что я получаю в uC через UART, — это строка с чистым HTML-запросом (и все, что я отправляю, — это строка с чистым HTML-ответом). Требованием приложения является отправка одного большого ответа с веб-страницей SPA (почти 300 тыс. символов) и нескольких крошечных ответов в виде AJAX (~ 200 символов). С 57600bps все работает нормально, но для загрузки большого отклика на клиенте требуется 50 секунд, поэтому, очевидно, мне нужно увеличить скорость передачи данных.

Это было введение в декорации, теперь основная игра, где начинается проблема: со всем, что выше 57600 бит/с, я теряю символы сообщений по пути в браузер. Я теряю их случайным образом — обычно это ряд смежных символов; иногда несколько, иногда более сотни из них. Первоначально я играл с блокировкой приема UART. Когда я заметил проблему, я перешел на DMA, и это не дало абсолютно никаких изменений. Я протестировал оба случая отправки через UART на терминал FTDA -> USB -> Termite вместо модуля WiFi и увидел те же симптомы. Поскольку каждая отдельная симуляция приводила к потере данных, я дошел до того, что даже скрестил STM Tx с Rx и проверил, все ли работает нормально на самой короткой из возможных цепей, и... это, конечно, сработало отлично :) Итак, UC исключается из числа подозреваемых.

Так возможно ли добиться надежной передачи UART? Есть ли у вас какие-либо идеи о том, как отправлять HTTP-сообщения по UART с высокой скоростью передачи данных? Я чувствую, что исчерпал все возможности, но маловероятно, что 115 кбит/с - это слишком много, не говоря уже о Мбит/с... Может быть, я упускаю что-то простое? Применение аппаратного управления потоком лишь немного исправляет передачу, я все еще получаю ошибки на 115 кбит/с (хотя и реже, чем без него).

*Обратите внимание, что я продолжаю говорить о HTTP-сообщениях из-за их особой природы - я не могу реализовать ни кадрирование, ни программный алгоритм управления потоком, потому что у меня нет власти на стороне браузера в этой коммуникационной цепочке.


РЕДАКТИРОВАТЬ: Еще несколько наблюдений:

  • С управлением потоком RST/CST я вижу закономерность при передаче (при 230 кбит/с): непрерывные ~45056 ИЛИ ~28672 символов отправляются правильно, затем я теряю пару символов, а затем снова - ~45056 ИЛИ ~28672, затем теряется пара символов и т. д. Обратите внимание, что количество смежных правильных символов всегда одно из двух упомянутых (+/- пара).
  • Без управления потоком я (как и ожидал) получаю следующую картину: передать ТОЧНО 8191 при 115 кбит/с или 4095 при 230 кбит/с непрерывных правильных символов, а затем потерять около 90 при 115 кбит/с или 110 при 230 кбит/с символов. Что странно, так это то, что я не теряю персонажей ни в каком другом месте...

В соответствии с этими наблюдениями я предпочитаю не использовать hwfc, а просто добавлять некоторую задержку в известных местах (после каждого 8191-го или 4095-го символа, в зависимости от скорости передачи). Однако это очень хакерски , я ненавижу это решение и надеюсь, что есть лучший способ решить эту проблему.

Ознакомьтесь с таблицей 133 справочного руководства и попробуйте скорость передачи данных UART с низким процентом ошибок. Кроме того, вы проверили, не входит ли модуль UART на UC в какие-либо условия ошибки, такие как переполнение или ошибка кадрирования?
UART требует, чтобы отправитель и получатель использовали одинаковые часы. При более высоких скоростях передачи часы становятся менее точными, поскольку относительная ошибка выше. Какой источник синхронизации вы используете?
Не пробовал это с F401, который я использую в настоящее время, но F051 работал нормально со скоростью до 512 кбит/с (больше не пробовал, так как он был достаточно быстрым). Хотя UART немного отличается, я бы сказал, что вполне возможно надежно достичь высоких скоростей передачи.
Адам , чем выше скорость передачи данных, тем больше процент, поэтому выбор более низкой относительной ошибки борется с моей первоначальной целью повышения скорости передачи данных :) Что касается ORE и FE, они на самом деле не происходят в tx, не так ли? @КЛ. Тестирую на плате Дискавери, так он внешний 8МГц с PLL поднимающим до 168. Арсенал UART на стороне uC работает нормально - как я писал, проверял перекрестием Tx с Rx. Это модуль WiFi, который теряет символы.

Ответы (1)

Звучит как проблема управления потоком для меня. Модуль Wi-Fi требует этого при более высоких скоростях передачи данных, потому что он не может отправлять пакеты на полной скорости - внутренние буферы заполнены. Если ваш MCU поддерживает это, вы должны использовать UART с аппаратными сигналами управления потоком (обычно называемыми RTS и CTS).

Я упомянул в своем посте, что, к сожалению, я не могу этого сделать (потому что контакты на плате заняты).
Управление потоком RTS/CTS может быть реализовано с помощью прерываний GPIO. Если у вас нет свободных булавок , вам нужно перепроектировать доску.
Боюсь, что в данном случае перепроектирование необходимо, хотя это и дорогостоящий маневр.. Хотя реализация GPIO hfc - интересная идея, сам до этого не додумался. Спасибо за это!
Я использую встроенное в STM32F4 аппаратное управление потоком, но после многих экспериментов надежность выросла совсем немного (теперь я могу отправлять 115200 бит / с, но даже тогда у меня теряется некоторое количество символов каждое ~ 5-е сообщение). Разве RTS/CTS не должны практически исключать проигрыши персонажей? Я действительно запутался прямо сейчас ... Я установил huart3.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS, я проверяю флаги TC и TXE перед каждым началом передачи, я всегда жду в цикле HAL_BUSY, когда я не получаю никаких ошибок во время передачи, и принимающий модуль должен работать даже с 460800... Что-то еще надо сделать?
Вы не забыли настроить модуль Wi-Fi для использования управления потоком RTS/CTS? Обычно это не конфигурация по умолчанию.
Да, я сделал. Пожалуйста, имейте в виду, что связь работает на более низких скоростях передачи данных (я думаю, что этого не произошло бы, если бы модуль не был сконфигурирован для аппаратного управления потоком).
Нет, модуль будет работать на более низкой скорости передачи данных и потеряет данные, когда более высокая скорость передачи данных истощит его буферы, как вы и заметили.
Вы уверены? Я думал, что: если на стороне получателя нет HWFC, если трансивер отправляет сигнал RTS, то получатель не ответит CTS, поэтому данные вообще не будут отправлены. В любом случае, конфигурация та же. с обеих сторон, так что это не так. Я также заметил, что при высоких битах в секунду я получаю ошибку кадрирования сразу с первым символом. Подводя итог: хорошо работает при бит/с<115k; работает, но теряет байты в 115k и 230k; ошибка кадрирования сразу с первым символом при скорости передачи 460k. Мне это кажется непостоянством скорости передачи данных или сигнальным шумом, но может ли быть какая-то другая причина?
Я сделал одно потенциально интересное наблюдение: когда я не использую управление потоком, я получаю данные в виде «кадров» точно: (для 115 000 бит/с): 8191 правильный символ, а затем около ~ 90 потерянных символов; (для 230kbps): 4095 правильных символов и ~110 потерянных [в обоих случаях первый кадр всегда в два раза короче]. Очевидно, это связано с буферизацией. Я НЕ теряю персонажей в случайных местах. Однако с hwfc я не получаю столь точных данных, но есть также шаблон - правильные непрерывные строки символов имеют длину ~ 45056 или ~ 28672...
Очень очевидный вопрос, но вы используете кристалл на своем STM32F4 (с конденсаторами NP0 ) и подтвердили, что скорости передачи и приема находятся в пределах 1% друг от друга, даже когда плата нагревается от розыгрыша WiFi > 50 мА, верно? Также перепроверьте, что Адам сказал о таблице 133.