История одной ошибки

dvqcr8nj-bvc6u_45zida8xayd8.jpeg

Практически все интегрированные среды разработки значительно упрощают жизнь программистам. А в случае разработки прошивки для микроконтроллеров, еще и освобождают его от нудной настройки параметров работы периферии, оставляя больше времени на разработки и отладку основной функциональности.

Например, при работе в STM32 CubeIDE, вся настройка параметров работы периферии сводится к вводу правильной частоты кварца и условного «кликанья мышкой», вместо того, чтобы программировать параметры работы железа вручную.

В продолжение серии статей про различные полезности для STM32 (1, 2 и 3), хочу рассказать, как в некоторых случаях, такое упрощение работы может стать источником совершенно не очевидных ошибок.

Сама история

Как-то разрабатывал устройство на базе STM32F4xx, которое подключается к последовательной линии связи (RS485) в качестве Modbus Slave. Протокол и система команд устоявшиеся, схемотехника отлажена и работоспособна, осталось только убедиться в логике взаимодействия и прошивку можно сдавать. Но я все медлил с завершением работы, т.к. иногда связь с устройством странным образом сбоила.

И это была не то чтобы серьезная ошибка. Ведь при передаче данных по линии связи и сами собой могу возникать ошибки даже в тепличных условиях. Но мне не давал покоя тот факт, случайные сбои возникали только на одном типе устройств и только во время одной единственной команды. Причем после второй-третьей передачи, данные обычно проходили нормально.

Ни пошаговая отладка, ни визуальный мониторинг сигнала с помощью осциллографа ясности не добавили, а самом сигнале никаких артефактов не выявили. Тем не менее, при имитации работы сети на обычном компьютере (через переходник USB-RS485) так же было зафиксировано периодическое возникновение ошибок, тем самым подтвердив наличие непонятной плавающей проблемы.

Анализ статистики этих сбоев выявил следующую закономерность. Проблема иногда возникала, когда команда передавала самый большой объем данных. Тогда как все остальные команды были размером 4–6 байт, и во время их передачи сбоев практически не бывало!

После этого стало понятно в какую сторону копать. Оказывается, все сбойные команды принимаются, но игнорируются из-за сбоя контрольной суммы. Причем, чем длиннее команда, тем больше шанс получить сбой.

Полез проверять в STM32CubeIDE настройки параметров работы UART — все нормально (логично, ведь остальные команды работают). Тактовая частота кварца 11.0592 МГц — все правильно. К делителям тоже вопросов быть не может, ведь их IDE проверяет.

Или может …?

2kxxwjtjqsv09zxmhjycqdrzcbs.jpeg

Как раз неделю назад, перед выявлением непонятных сбоев связи, я игрался с автоматическим подбором делителей. И мне запало в память, как IDE в попытке подобрать требуемую частоту, перебирает различные комбинации всевозможных делителей PLL.

Сейчас уже не помню, сам ли я переключил тактирование с кварца на внутренний RC генератор (HSI RC), или это сделала STM32 CubeIDE во время попыток подбора требуемой частоты для одной из шин, но причина периодического сбоя связи была найдена (уход частоты при тактировании от RC генератора).

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

Фактически, мой косяк — это очередное подтверждение поговорки: «Доверяй, но проверяй»! Буду рад любой дополнительной информации, на что еще следует обращать внимание при использовании IDE, что бы случайно не нарваться на какую-нибудь похожую проблему, но уже в другом месте.

© Habrahabr.ru