Arduino Due случайным образом тормозит, последовательная связь прекращается

У меня есть Arduino Due, подключенный к Raspberry Pi через Serial3. Due случайным образом перестанет отправлять данные на Pi через несколько дней, а иногда и через несколько часов. С помощью осциллографа я вижу, что Pi продолжает передавать данные на Due, но ответа от Due нет. Я также получаю, что Due повторяет все, что он получает от Pi к последовательному порту, который подключен к моему компьютеру. Я вижу, что Due перестанет отображать символы на полпути получения сообщения от Пи.

Затем я установил один из контактов в качестве выхода и просто регулярно переключал его. Когда Due ожидает данных от Pi, этот сигнал имеет частоту около 100 Гц, то есть период 10 мс. У меня есть счетчик от 0 до 1000, чтобы немного контролировать эту частоту. Когда возникает эта ошибка и связь прекращается, я вижу, что импульсы теперь имеют период 2,14 секунды, т.е. в 214 раз медленнее.

Я использую Arduino-MemoryFree для проверки утечек памяти, но пока не обнаружил никаких проблем, и я похоже, не хватает памяти. Если это имеет значение, я также использую библиотеку ArduinoJson. Версия Arduino IDE — 1.6.7, я обновил пакет плат Arduino SAM до версии 1.6.9 (проблема присутствовала и до обновления).

Может кто-нибудь подсказать мне, что может быть причиной такого замедления?

, 👍4

Обсуждение

Утечки памяти проявляются не только в уменьшении объема памяти — они также проявляются в повреждении переменных из-за таких вещей, как переполнение буфера. Вам нужно опубликовать свой код, чтобы мы могли увидеть, где он может дать сбой., @Majenko

Скорее всего, это утечка памяти, но другим вариантом может быть фрагментация памяти из-за чрезмерного использования команд new и delete., @Code Gorilla

Возможно, регистры PMC повреждены, и основная тактовая частота была переключена на медленную тактовую частоту. Вы можете попытаться заблокировать настройки PMC, чтобы их нельзя было случайно изменить., @KIIV

@KIIV Как мне заблокировать эти настройки? Что происходит после блокировки, когда код пытается их перезаписать? Будет ли Arduino Due сброшен или полностью выйдет из строя (в этом случае сторожевой таймер все еще может восстановиться, так что я тоже этим доволен)?, @chippies

@Matt Я тоже это подозревал, за исключением того, что я не использую новый/удалить, а библиотека ArduinoJson использует буфер фиксированного размера в стеке. Может ли встроенный класс String вызывать проблемы (он часто используется)? Я читал, что с этим возникла проблема, но указанный номер версии был v1.0.5 IDE., @chippies

@chippies Это должно быть включено чем-то вроде PMC_WPMR = 0x504D4301;. Затем при нарушении защиты от записи он устанавливает бит PMC_WPSR 0 (WPVS) и нарушает смещение регистра PMC. Это должно быть все., @KIIV

@KIIV Ах, таким образом я могу включить его в setup(), затем продолжать проверять PMC_WPSR в loop() и немедленно сбросить срок выполнения, когда бит 0 изменится на 1. Я добавлю это в понедельник., @chippies

@KIIV, где я могу найти PMC_WPSR? Я обыскал свой каталог Arduino и не нашел ни одного файла, в котором бы это упоминалось. Я уже установил пакет плат Arduino SAM. Спасибо за помощь., @chippies

Дополнительные пакеты @chippies спрятаны в другом каталоге, чем пакет Arduino. Где-то в каталоге пользователя., @KIIV


1 ответ


Лучший ответ:

1

The Due случайным образом перестанет отправлять данные на Pi через несколько дней, а иногда и через несколько часов.

Вот типичное проявление фрагментации кучи в скетче Arduino.

Решение:

  1. Удалите как можно больше String и замените их char[]
  2. Используйте StaticJsonBuffer вместо DynamicJsonBuffer

Если вы удалите все String и используете StaticJsonBuffer, ваша программа будет работать без кучи. Никакой кучи, никакой фрагментации! Он будет не только надежнее, но и меньше и быстрее.

Если вам необходимо использовать String, вызовите <code>String::reserve()</code>, чтобы убедиться, что размер одинаков на каждой итерации. Действительно, повторное выделение одного и того же размера не увеличивает фрагментацию.

,

В конце концов я изменил архитектуру системы, чтобы избежать обработки JSON на Due. Это устранило проблему, поэтому я отмечаю это как решение., @chippies