У каждого программиста микроконтроллеров с опытом формируется коллекция решенных багов. Баги появляются и исчезают, как вспышки на Солнце. Некоторые из них весьма эпичные. Многие уже читали про ошибку переполнения при конвертации double в int16_t в коде ракеты Ариан-5.

Самый типичный баг - это зависание прошивки. Переслали мигать heart beat LEDы, UART-CLI перестала отвечать на команды. В таких случаях не надо подвергаться конвульсиям, судорогам и параличу. Надо просто спокойно и методично разбираться в ситуации.
Выявление причин багов порой сродни работе детективом. Это проявляется в том, что очень трудно выявить причину бага. Сначала разработчик идет по ложному следу, ходит кругами, а конце концов выясняется (порой случайно), что причина на самом деле была проста, как солдатский валенок.
Вот об этом сейчас и поговорим...
1-- Отлаживаем телематическую плату в CAN сети. Подключили переходник USB-CAN. Автомобиль не заводится. Стартер работает, но зажигания (вспышек в цилиндрах) не происходит. Разобрали половину впускного коллектора. Рукой шевелили дроссельную заслонку. Три часа искали причину поломки. Оказывается в OBD-II разъем попал кусок фольги от папиросок, которые замкнули три крайних пина. Стоило пинцетом извлечь мусор, как автомобиль завёлся с пол-оборота. Вот так. Этот баг называется "Мусор между разъёмами". Вот так просто и не затейливо.

2-- Схемотехники разработали электронную плату с разъемом Tag-Connect. Плату разрабатывали полгода. Плата скомпонована с плотностью нейтронной звезды. А после сборки выяснилось, что никак не примонтировать самый главный разъём - тот что для программирования. Ручной зажим Tag-Connect не защелкнуть, так как пальцы банально не пролезают между стабилизатором напряжения Traco Power и разъёмом Tag-Connect. Да... Всё не предвидишь. В результате пришлось просить женщин с тонкими пальцами, чтобы соединить программатор и электронную плату. Этот баг называется: "толстые пальцы".

3--При питании от USB электронная плата не включается. Вернее она на мгновение мигнет и сразу отрубается. Сначала я подумал, что происходит это из-за инициализации BLE и UWB. Якобы они сильно просаживают напряжение. Но при отключении всего wireless connectivity из сборки пропадание электропитания осталось. Но потом случайно заметил. Когда USB вилка вставлена до упора, то на плату не подается питание. Однако если же USB вилку аккуратно выдвинуть всего только на полдлины, то так питание поступает! Оказывается был просто бракованный разъём гнезда для USB-A. На плату просто не поступало питание по USB. Мораль: "Не надо жалеть денег на кабели USB".
4-- Отсутствие SWD link(a). Программатор не видит target по SWD. Собрали стенд, положили SWD длиной 90 см и нет Link(а) с MCU. Когда кабель 12 см, то link есть. Оказывается, что пакеты SWD шины просто не проходили через slip-ring. Slip-ring - это такое устройство, чтобы пропускать провода через подшипник. Чтобы провода не наматывались на ось и не рвались. Пришлось прошивать электронные платы внутри турели навесу.

5-- Плата с СС26x2 зависает при перезагрузке. Плата работает под отладчиком, а при пере сбросе питания не стартует прошивка. На другой плате это не проявляется. Эта ситуация потребовала неделю на выяснение причины и устранение.
Оказывается у СС26x4 MCU от TI надо прописать спец адреса в конце Flash памяти, чтобы чип переключился на внешний осциллятор. Там в последней странице Flash живет сектор конфигурации SoC-а. Поэтому во все новые платы надо первым делом записывать прошивку blinky_backdoor_select_btn26x2.bin из SDK при помощи утилиты SmartFR Flash Programmer 2. Прошивка blinky_backdoor_select_btn26x2.bin корректно настраивает конфигурационные CFG регистры за счет того, что они лягут в последней страницу Flash. Потом уже накатывать свою прошивку поверх. Вот так.
6--Статическое электричество постоянно портит жизнь. Порой ставишь электронную плату на недельный тест, чтобы наработать логи. Приходишь через неделю cнять характеристики по UART, ценнейшие логи из RAM памяти. Только дотрагиваешься до края электронной платы... Дзык! Проскальзывает искра статического электричества, которая убивает содержимое RAM памяти и прошивка заклинивает прямо на глазах.
И весь недельный тест с логами внутри накрывается медным тазом... Пришлось поднимать на устройстве NVRAM и черный ящик в SD карту, чтобы писать логи в энергонезависимую память. Вот такие вот пирожки с капустой... Понимаете?...
14--Хрипящий голос. Из Bluetooth classic модуля BT1026 по I2S приходит хриплый голос. Сначала подумал, что DMA не так настроено. Микроконтроллер тактирует WS на частоте 50kHz. Оказывается, что если BT1026 опрашивать с частотой дискретизации чаще 48kHz, то по I2S data out будут идти нули. Модуль FSC-BT1026С не может выдавать I2S семплы чаще чем 48kHz. Эти вкрапления нулей и были слышны как хрип. Решение было в том, чтобы добиться частоты следования семплов не выше 48kHz. Микроконтроллер nRF5340 самое близкое мог выдавать на I2S WS только 50kHz. Пришлось сконфигурировать мастером шины I2S сам BT1026. Так звук стал непрерывным и чистым.

7--У меня был случай, когда три схемотехника спроектировали электрическую цепь электронной платы (схемотехнику), развели топологию (layouts), отправили производство в другую страну, a спустя три месяца на выходе выяснилось, что они забыли вообще даже подать на микроконтроллер электропитание! Вот тот самый МГТФ проводок, который пофиксил ошибку дизайна.

Вот так... Как говорят:
У семи нянек дитя без глаза.
8--Никак не проходит auto-negotiation в Ethernet физике по 100-Base-TX. Не проходит ping. Оказывается в монтажных мастерских техник по ошибке припаяла кварц для физики fast-ethernet, не на частоту 25 MHz, а на частоту 23 MHz! Перекинули кварц и ping-и сразу побежали, как горный ручей. Не тот был кварц.
Или вот, плата Olimex-STM32-H407 в UART3 вместо лога загрузки сыплются кракозабры. Оказывается, что прошивка думает, что кварц 25 мегагерц, а там на самом деле 12 мегагерц. Пересобрал прошивку с настройками тактирования от 12 мегагерц и побежал понятный лог на ожидаемой битовой скорости .
9--Собранная прошивка для платы с МК STM32F413ZGJ6 зависает при прыжке из загрузчика в приложение. При пошаговой отладке всё стартует отлично. При выяснении причины выяснилось, что перед прыжком в приложение загрузчик смотрел на указатель
стека и не запускал прошивку, если в таблице векторов прерываний указатель
на верхушку стека ссылается на размер RAM больше, чем 128kByte. В таких случаях загрузчик просто прыгал в бесконечный цикл. Загрузчик, к слову, писал коллега из другого дивизиона.
При этом напомню на MCU STM32F413ZGJ6 320k Byte RAM! Оказывается коллега разработчик загрузчика по ошибке всегда собирали прошивку вообще для другого MCU: STM32F205VC. И generic приложение он тоже собирали для STM32F205VC, а записывал на STM32F413ZGх. Поэтому раньше у него это зависание не проявлялось. Его прошивка работала чисто только благодаря обратной совместимости между ядрами ARM Cortex-M4 и ARM Cortex-M3. Оказалось, что ему просто лень было посмотреть, что написано на корпусе микросхемы DD14. Упс!, Микроконтроллер перепутали...
Программисты порой как туземцы какие-то вообще не понимают с чем работают. Попалась им в руки европейская игрушка и давай её вертеть не по назначению.
Техника в руках дикаря - кусок железа.
10-- Ошибка snprintf. Прошивка для ARM Cortex-M33 неожиданно сваливается в исключение Default Handler внутри функции snprintf(). А конкретно на функции svfprintfr и ассемблерной команде VSTMDB. Оказывается snprintf использует вычисления с действительными числами. При этом код прошивки был собран с активированным аппаратным FPU одинарной точности. Это опции компилятора -mfloat-abi=hard -mfpu=fpv5-sp-d16, одновременно с этим startup код не включал сопроцессоры FPU в регистре SCB->CPACR.
Пришлось либо отрубать аппаратный FPU ( -mfloat-abi=soft ), либо включать сопроцессоры FPU.
#ifdef ENABLE_FPU
/* Enable CP10 and CP11 coprocessors */
SCB->CPACR |= (3UL << 20 | 3UL << 22);
#endif
11--Загадочные прерывания. Почему-то при инициализации CAN трансивера прошивка зависает в DefaultISR. Сначала я думал, что нет тактирования на CAN трансивере, ибо SoC весьма сложно раздавал тактирование. Однако нет. Тактирование настроено нормально. Это показал вывод частоты "на улицу". Оказывается, при инициализации CAN вызываются прерывания, на которые нет обработчика. Причём это были зарезервированные для данного MCU номера прерываний, для которых для данного MCU по спеке вообще ничего не предусмотрено. И тем не менее, иногда эти номера выстреливают, что приводит к сваливанию прошивки в бесконечный цикл default_ISR. Чтобы починить инициализацию CAN трансивера пришлось определить обработчики прерываний по умолчанию для всех 196 ISR. И определить эти обработчики, как weak функции.
12--Так называемая "ошибка 71-ой минуты". Прошивка всегда стабильно зависает на 71-ой минуте работы (4291 секунде). Светодиоды перестали мигать, UART-CLI перестала отвечать на команды. Оказывается переполнилась переменная up_time_us = 4294967296 us = 4 294 967 ms = 4 294 s= 71 m. И программный компонент limiter просто ждет, когда переменная up_time_us превысит значение 4294967297 us и не вызывает никаких функций. А это и не происходит, так как 32-х битный счетчик up_time_us пошел по второму кругу. Пришлось добавить обработку на переполнение типа данных uint32_t.
13--Очень низкая дальность LoRa link-a. У нас в компании спроектировали PCB c дальнобойной радиосвязью LoRa. Однако почему-то уже на расстоянии 30 метров обрывается сеанс связи. Радиокоманды не поступают. При этом тот же код драйвера SX1262 на покупной плате T-Beam работает аж на 15 километров. Это было специально проверено на полигоне. Оказывается на нашей плате схемотехник сильно отошел от reference дизайна и заложил ключ BGS12WN6E6327XTSA1 с инверсными логическими уровнями. В переводе на кухонный язык, когда LoRa трансивер передавал сигнал, антенна была просто отключена! Когда трансивер принимал, мультиплексор DA10 подключал антенну на передатчик и ASIC ничего не принимал. Вернее антенна была в виде дорожки PCB длинной 7 миллиметров. Вот так...

И это только то, что я смог вспомнить за один присест. В реальности багов было много больше. Не наступайте на те же грабли, что и я.
Итог
Как видите, проблем может быть просто море и они поджидают вас абсолютно везде. И чтобы понять, что происходит, порой нужно воистину нешаблонное мышление.
В программировании микроконтроллеров до того, как вы дойдете до всяких так алгоритмов и структур данных пройдет год, а то и два колупания с электропитанием, макетированием, тактированием, прерываниями и прочим. А проблемы отсутствия всяческого Link(а) в программировании микроконтроллеров и вовсе красной нитью прошивают всю мою карьеру. Особенно в случае беспроводных интерфейсов.
На сам процесс программирования уходит максимум 10...30 процентов времени. В основном приходится что-то бесконечно ремонтить.
Суммируя аппаратные баги, это либо ошибка в схемотехнике или ошибка в топологии.
Баги в разработке на микроконтроллерах это совершенно нормальное явление. Главное чтобы из них делали выводы. Надо уметь выявлять их причину.
Если у вас тоже случались культовые баги в разработке на MCU и вы нашли причину и решение, то напишите про это в комментариях.
Ссылки
# |
Текст |
URL |
1 |
Как Чинить Программные Ошибки? |
|
3 |
Космическая ошибка: $370 000 000 за Integer overflow |
|
4 |
Невероятно неуловимый баг по электропитанию в Пастильде |
|
2 |
16 Способов Отладки и Диагностики FirmWare |
Комментарии (113)
nikolz
19.02.2025 23:04В программировании микроконтроллеров до того, как вы дойдете до всяких так алгоритмов и структур данных пройдет год, а то и два колупания с электропитанием, макетированием, тактированием, прерываниями и прочим. А проблемы отсутствия всяческого Link(а) в программировании микроконтроллеров и вовсе красной нитью прошивают всю мою карьеру. Особенно в случае беспроводных интерфейсов.
Сочувствую.
Замечу из своего опыта, что до программирования любого микроконтроллера(SoC) и разработки алгоритмов , особенно в случае беспроводных интерфейсов, который выполнен в виде китайского модуля (ESP,NRF,TLINK,STM,Ti и др) обычно проходит не более 5 дней (время на изучение документации на новый чип) и 1 дня (припаять провода для подключения к ПК и установить IDE на Eclipse).
CitizenOfDreams
19.02.2025 23:04И весь недельный тест с логами внутри накрывается медным тазом... Пришлось поднимать на устройстве NVRAM и черный ящик в SD карту, чтобы писать логи в энергонезависимую память.
Странно, что кому-то вообще пришла в голову идея хранить недельные логи в RAM...
AiR_WiZArD
19.02.2025 23:04Именно. Всегда когда надо тестировать больше пары часов в ход идет одноплатник, либо пишущий на свою флешку, либо если тест долгий и есть интернет, сразу по mqtt на сервер что бы можно было в реальном времени мониторить. + в одноплатник сразу программатор засунуть можно
REPISOT
19.02.2025 23:04Оказалось, что ему просто лень было посмотреть, что написано на корпусе микросхемы
Или кому-то другому было лень написать программисту ТЗ или хотя бы записку, где указать тип контроллера
NutsUnderline
19.02.2025 23:04весь случай со статикой это не баг - это стыд и позор для организации, особенное если она ориентирована на разработку электроники. многие из нас конечно же так делают, но это настолько ССЗБ что слов нет
eugenk
19.02.2025 23:04Мои два самых смешных случая связаны с тем, что я давно сижу под линуксом, а народ в основном под виндой. Случай первый. Нужно было написать некоторую не особо хитрую программку для STM8S (8-битный микроконтроллер от ST Microelectronix) Я писал на SDCC, у заказчика был IAR Embedded Workbench. У меня всё работает, и у заказчика прошитый мой бинарный файл тоже прекрасно работает. Но при попытке заказчика собрать прошивку из исходников, работать перестает. Выяснилось, что SDCC нумерует прерывания с нуля (как вроде оно и логично !), а IAR с единицы (почему спрашивается ???). Когда это поправили, всё заработало.
Случай второй. Нужно было сделать некий довольно хитрый проект на FPGA ice40 от Lattice (я писал об одной интересной задачке, связанной с этим проектом https://habr.com/ru/articles/485786/ ). На версии icecube2 под линукс всё собирается нормально и всё работает. На версии под винду у заказчика, прошивка собирается, но не работает. Слава богу удалось продемонстрировать это заказчику. Очевидно в версии под винду были баги, а под линукс - нет. Удивительно как такое вообще может быть. У них что, под разные системы различная кодовая база ??? Кстати после следующего обновления, под винду тоже стало собираться нормально.
zatim
19.02.2025 23:04Так ведь даже переход между разными версиями винды - уже проблемы. Ставил недавно банальную ардуину иде. Сначала поставил на 7 - проект не компилится, то одна ошибка вылезет, то другая, то третья. Помучался, надоело. Накатил 10-ку, проект скомпилился без проблем. Одна и та же версия ардуины, одни и те же библиотеки, один и тот же проект.
NutsUnderline
19.02.2025 23:04на win7 есть много внутренних ограничений, весьма неожиданных. проблемы с кирилическими именами папок это давно классика. а вот что в win7 ограничена длина строчки в командной строке - это уже неявный момент который легко приведет к странным ошибкам. так же регулярно используются утилиты писаные на python, новые версии на win7 которого уже не работают (без хитростей) и ошибки будут вообще из другой области.
zatim
19.02.2025 23:04Так ведь это, по сути, не проблема винды, все остальное на ней работает. Сама иде на ней работает, простейшие скетчи работают. Просто кто-то написал несовместимый код, а другой кто-то это не проверил.
Про питон вы верно сказали, проблема была именно с ним (esptool).
kuzzdra
19.02.2025 23:04Где esptool, и где проект не компилится, то одна ошибка вылезет, то другая, то третья (ц)
NutsUnderline
19.02.2025 23:04так нет такого обязательства писать код совместимый со старыми виндами (95,98,XP,7,8). MS ввела новые api которых в 7ке просто нет, компиляторы их используют по умолчанию, чтобы обеспечить совместимость нужны доп. телодвижения, на что разработчикам лень и некогда. и как бы никто не виноват, и вообще можно использовать не самые новые версии софта, либо костылить. либо мигрировать. под linux тоже кстати есть такие истории.
zatim
19.02.2025 23:04Ну, как это? Если для ide заявляется совместимость, то и для библиотек должна быть совместимость. Иначе какой смысл в ide в отрыве от библиотек? Тем более, что ардуина позиционирует себя для начинающих разработчиков, а значит все должно работать из коробки, без лишних телодвижений и, тем более, колдунства 80lvl.
Ну, или хотя бы просто написали что такая-то версия не совместима, установите вот такую. Так ведь нет, там ошибка вывалилась вообще хз какая и только вдумчивое гугление навело на мысль о версиях по.
kuzzdra
19.02.2025 23:04для библиотек должна быть совместимость
Тут наверное вопрос к авторам BSP для 8266.
только вдумчивое гугление навело на мысль о версиях по
opensource, ага ;)
remzalp
19.02.2025 23:04Arduino IDE с ванильной ардуиной - да, успешно.
Там даже Reset разведён куда надо и контроллер переключается в режим прошивки как надо.
А вот с подражателями уже куча вопросов - или надо успевать в момент заливки переводить в режим программирования (поленились резет куда надо вывести) или компиляторы внешние не очень корректные или внешние тулзы (питон для esptool)
Wesha
19.02.2025 23:04так нет такого обязательства писать код совместимый со старыми виндами (95,98,XP,7,8). MS ввела новые api которых в 7ке просто нет
Graceful degradation? Не слышали!
kuzzdra
19.02.2025 23:04Graceful degradation? Не слышали!
Не тот случай. Само arduino ide работает как обещано. А китайский плугин с чем-то несовместим.. ну, бывает. Они просто не тестировали на Windows 7 ;)
AiR_WiZArD
19.02.2025 23:04Я писал на SDCC, у заказчика был IAR Embedded
А зачем? Пусть SDCC у себя настраивают. Смысл поддерживать разные компиляторы, если это не крупный opensorce проект, где каждый свой велосипед собирает. Да даже версии компиляторов и флаги компиляции должны быть теми же самыми, что бы исключить странные баги.
kenomimi
19.02.2025 23:04Я перепутывал разьем usb - поставил перевернутым. Причем плата уровня ардуино нано, три с половиной детальки. В - внимательность. Так что теперь перед заказом откладываю проект на пару дней, потом делаю ревью, и только после отдаю в работу.
aitras
19.02.2025 23:04О, эту временную паузу я называю "плата должна настояться" :)
Как правило, либо ошибки находятся, либо умные мысли приходят в голову о том, что можно немного поправить.Gryphon88
19.02.2025 23:04Не зря корректорские и редакторские читки по-олдскульному делают с интервалом минимум в неделю :)
zatim
19.02.2025 23:04Я когда открываю свою схему через полгода, смотрю на нее и думаю: какой дурак это рисовал?! Тут же надо все переделать!
nv13
19.02.2025 23:04#12 - у нас как то на тестовом стенде перезагрузилась коробка с текущим релизом, кто то заметил это в отчёте и завёл инцидент. Проверяли билды, повторяли тесты -всё ок. Отложили. Через месяц перезагрузилась соседняя на другом релизе и ревизии платы, и снова никаких результатов расследования. На третий раз заметили, что все перезагрузки имели разные аптаймы - что то вроде 43 дня, 37 и 28, и это коррелировало с тремя ревизиями плат под тестированием, которые отличались моделями процессоров.
Ну а дальше стало понятно - какой то watchdog. Посчитав тики, выяснили какой из процессоров не сбрасывает таймер, и нашли баг.
Удивительным оказалось то, что этот код существовал с первого релиза, но воспроизвёлся баг только когда в тестовой лабе появились коробки, которые тестировались вдолгую. Не было ни одной жалобы от покупателей - они перезагружали коробки сами чаще, или просто не замечали перезагрузки.Wesha
19.02.2025 23:04Удивительным оказалось то, что этот код существовал с первого релиза, но воспроизвёлся баг только когда в тестовой лабе появились коробки, которые тестировались вдолгую.
Не вы первые, не вы последние...
nv13
19.02.2025 23:04Больше похоже на "супернадёжные"" Нокии, которые тихо ребутились по ночам или в кармане)
kipar
19.02.2025 23:04Из недавнего - развели плату с новым (для нас) Ethernet PHY, на прием пакетов работает на передачу нет. Смотрим осциллографом - пакеты уходят, с виду более шумные чем приходящие. Сравниваем с референсными схемами - там аналоговое питание отделено от обычных 3.3V индуктивностью, слабо верится что это может влиять но других идей уже просто не осталось. Развели заново чтоб точно по рекомендациям, конденсаторы на том расстоянии на каком должны быть, земля общая питание раздельно, не работает. Все знакомые электроники говорят "вы зря Ethernet осциллографом смотрите, оно должно просто само заработать".
Так и вышло. На схеме были перепутаны ножки TXD2 и TXD3.
aabzel Автор
19.02.2025 23:04Вот поэтому я и рекомендую всегда строить таблицу проводов в google spreadsheet. Для каждой схемотехники.
https://habr.com/ru/articles/716596/
zatim
19.02.2025 23:04Да, верно) ethernet - довольно таки устойчивая к помехам и несогласованности технология. Я когда на кабельном работал, лазил по чердакам, каких только скруток на езернет кабелях не встречал) и, по видимому, все работало.
С езернетом может быть такой прикол: неправильно обжаты пары. Например, tx+ оказался в одной кабельной паре, а tx- в другой. Это может даже как то работать, линк поднимется, простейший кабельный тестер подвоха не увидит, но будет сильно глючить.
1eg10n
19.02.2025 23:041) Переходили на новый МК. При подключении RTC модуля, контроллер начал падать в Hard fault. При этом, код до этого модуля и близко не доходил, падая в другой rtos задаче.
Выяснился интересный момент. Если чуть поменять код местами: if внутри case вынести до switch-а, то все снова начинает работать.
Проблема в итоге решилась, после исправления сопроцессора.
2) Не баг, а фича. Поймал коллизию CRC32 при изменении одного бита. Массив uint8_t [ < 0x20'0000].
AndGry
19.02.2025 23:04Случайно не на stm32 проблема с RTC?
Была такая проблема на L433, но в HardFault сваливался немедленно после старта, исключительно с вставленной батарейкой RTC. Заключили, вроде бы, что она наводит помехи на NRST и вообще на половину периферии прямо сквозь камень)
По крайней мере, симптоматика была такая.
sergyk2
19.02.2025 23:04день убил на ковыряние в прошивке, поиск косяков, почему вчера работало а сегодня перестало... в конце дня посмотрел через лупу - у микросхемы нога недопаяна
aabzel Автор
19.02.2025 23:04У меня был случай , когда с производства принесли плату, а там микроконтроллер 144 пин вообще держался на трёх угловых пинах. Можно было металлическую линейку под QFP144 засунуть.
CitizenOfDreams
19.02.2025 23:04Если это был некий отечественный микроконтроллер в некоем импортозамещенном мониторе, то оно при этом могло даже нормально работать...
aabzel Автор
19.02.2025 23:04Сам работал в Миландр. Даже не удивился, узнав про эту историю. Именно так там все и делается.
nixtonixto
19.02.2025 23:04Монтажник прихватил чип за крайние ножки, собрался пропаивать - но тут его отвлекли. Вернулся, посмотрел, что чип стоит на плате и пошёл паять следующие компоненты. Это вообще классика. Не отвлекайте монтажников, пока они работают, а монтажники - не отвлекайтесь, пока полностью не пропаяете компонент.
nghtsnw
19.02.2025 23:04Недавно проверял связь с ПК по RS485 с одним промышленным контроллером, ни в какую не было линка. Расковырял компаунд над чипом-трансивером, протыкал всё осциллографом с его стороны, вроде на обеих линиях сигнал видать, rx/tx переключается. Когда мозг начал покидать чат под конец рабочего дня, решил перебрать невероятные варианты. В итоге нашёл что соединительный проводок 10 см от адаптера до контроллера по одной из линий в обрыве, а с виду целый был.
Наши схемотехники тоже один раз выдали. Трансивер Ethernet соединялся с микроконтроллером по параллельной шине - 16 ног для данных и 13 для адреса. И пинг вроде есть, но со связью как-то всё коряво. И все руками разводят, на программиста пальцами показывают, чтоб у себя косяк искал. Оказалось что на одну из ног адресной шины по ошибке засадили светодиод линка.
CitizenOfDreams
19.02.2025 23:04Недавно проверял связь с ПК по RS485 с одним промышленным контроллером, ни в какую не было линка.
Я когда-то давно одним из первых нарвался на известную проблему с поддельными чипами USB to serial. Ну, это где обозленный производитель написал драйвера, которые вроде работали, но через каждые N байтов вставляли в поток данных текст "это подделка".
Firelander
19.02.2025 23:04А кто нынче таким грешит не подскажете?
CitizenOfDreams
19.02.2025 23:04А кто нынче таким грешит не подскажете?
Нынче не знаю, а тогда это был Prolific. Потом его примеру последовал FTDI, который вообще окирпичивал поддельные чипы, хотя и не фатально.
Firelander
19.02.2025 23:04сейчас пролифик тупо не работает, прямо в имени устройства пишет мол у вас чип древний идите вы отсюдова. Причём, я так понимаю они уже даже не пытаются различать оригиналы и не оригиналы. Довольно скотское поведение конечно. Только силабсы вроде бы адекватные остались
MaFrance351
19.02.2025 23:04хотя и не фатально
Смотря для кого не фатально. Если поставили партию девайсов (необязательно промэлектроника, мало ли что за железка, которая к ПК подрубается и работает себе) клиентам, а через полгода после обновления драйвера они массово отлетели, то ситуация аховая. И убытки от отзыва этих аппаратов на перепайку чипов понесёт не FTDI и не поставщик, который впарил контрафакт, а те, кто произвёл и продал.
MaFrance351
19.02.2025 23:04Это кто был? У меня FTDI так навеки оказались в чёрном списке вендоров, когда в обновлении драйверов стали окирпичивать чипы, определившиеся как поддельные. Просто перезаписывала PID на 0000, и для оживления надо было танцевать с бубном. Везде после этого перешёл на CP2102.
zatim
19.02.2025 23:04Бывает такое) в старом пикаде, когда переносишь кусок схемы из старого проекта в новый, нетлист так же переносится, с теми же номерами соединений. И может так случиться, что номера некоторых соединений из старой схемы совпадают с номерами в новой. Визуально это никак не видно и ошибок в схеме нет. А вот на трассировке платы это вылезает, и там действительно, светодиод может приконнектится к шине данных, силовая линия из источника питания - к ножке проца, и т.д. абсолютный рандом) приходилось очень внимательно проверять разводку плат за печатниками.
parilov
19.02.2025 23:04Невнимательно читал документацию на кварц: картинка выше - не посадочное место, а вид со стороны контактов. Нужно отзеркалить.
andi123
19.02.2025 23:04Заводили дополнительный eth на джетсоне через pcie. Взяли референсный дизайн. Единственная особенность eth (realtek) и джетсон сидели на разных платах и соединялись плоским шлейфом. Все завелось кроме eth. Причем eth завелся, но как-то по-особенному. как будто с неинициализированным флешем (там обычно лежат всякие настройки). Запускал сам, но в железо не лез (уверяли, что все собрали правильно). Не завелось. И поставщиками писали, прислали кучу утилит для инициализации. Проверяли шлейф тыщу раз. И по форумам писал. Отложил в сторону. Потом решили таки добить.
Достал этот бутерброд и начал по старинке все проверять. Подал питание и начал везде его проверять. Оказалось, что на шлейфе питания нет. Начал рассматривать шлейф и разъемы. И оказалось, что на материнке стоит двухсторонний разъем, а на плате с реалтеком односторонний. Воткнули шлейф вверх ногами. Перевернул шлейф и сразу же получил свой гигабит.
Получил еще одну прививку от доверия другим людям и их уверениям в своей безошибочности.
AVKinc
19.02.2025 23:04У меня было в Протеусе все работает, в железе глючит и перезагружается. Оказалось забыл отключить внешнее прерывание, нога висела в воздухе и генерила огромное количество прерываний.
vanxant
19.02.2025 23:04Не про микроконтроллеры, но тоже про "загадочные прерывания".
В ZX Spectrum можно было использовать свой обработчик прерывания от таймера (других источников прерываний там не было). Для этого надо было загрузить старшие 8 бит адреса, в котором лежит адрес обработчика в регистр процессора I, а младшие 8 бит Z80 брал с шины. В норме там должно было быть #FF, но на шайтан-клонах могло прилететь что угодно. Поэтому обработчик приходилось размещать по адресу #XYXY (с одинаковым младшим и старшим байтом), а под таблицу прерываний отдавать 257 байт и заполнять их этими самыми #XY.
beeruser
19.02.2025 23:04В норме там должно было быть #FF, но на шайтан-клонах могло прилететь что угодно.
Как раз в оригинальном спектруме и могло прилететь что угодно, а в клонах бывало и #FF
Assuming that the databus contains a "random" number in range of 00h..FFh upon IRQs, it requires a table with 101h bytes at [I*100h+0..100h]. On the Spectrum 128 and up the databus seems to be stable FFh, needing only a 2 bytes at [I*100h+FFh..100h].
MaFrance351
19.02.2025 23:04Тоже вспомнилось. Делал одну железку, там были драйверы моторов. Собрали, запустили - всё работает, шаговики крутятся, всё ездит. Но всплыла проблема - после нескольких десятков прогонов координаты уходят. Причём происходит этакий циклический сдвиг, если сделать запусков так сто, то оно вернётся на место. Явно как будто программная ошибка. Очень долго ковырял прошивку, поменял библиотеку для работы с драйверами, жгуты проводов все заменил на экранированные. И опять не работает.
А всё оказалось банально и просто - оказалось, что при слишком маленькой длительности импульса (какая стояла по умолчанию в той библиотеке) драйвер может пропускать шаги, причём крайне незначительно (может, один процент от числа всех импульсов игнорировался). А в сочетании с механикой, которая была у меня, он может это делать вот так вот необычно, что напоминает программный баг (как будто погрешность при непонятно откуда взявшемся округлении или что-то вроде этого). Увеличил длительность вдвое, и всё ожило.
aabzel Автор
19.02.2025 23:04оказалось, что при слишком маленькой длительности импульса (какая стояла по умолчанию в той библиотеке) драйвер может пропускать шаги
У меня с той турелью был даже обратный эффект.
Из-за ненадежного разъёма между MCU и платой с драйвером drv8711 наоборот из-за дребезга на линии STEP получались лишние шаги.
В результате ось каждый раз уезжала дальше на 3-5%.MaFrance351
19.02.2025 23:04А я тогда ещё на механику грешил. Думал, что-то где-то заедает, болтается... Всё разобрали, почистили, смазали, собрали обратно - не помогло. А оно вот как оказалось.
rsashka
19.02.2025 23:04Это проблема у всех шаговых двигателей
aabzel Автор
19.02.2025 23:04А ещё шаговые двигатели свистят во время работы. И тоже не ясно как бороться с шумом.
alexey_public
19.02.2025 23:04Частота ШИМ, я на своих драйверах иногда за 120 кГц выводил, чтобы вообще не было слышно, но это не всем доступно. Ну и если делать глубокий microstep - то и при движении ничего особо не шумит.
the_bat
19.02.2025 23:04Очень полезная статья. Особенно с точки зрения поиска. Например если вбить в поисковой строке "Программатор не видит target по SWD", то можно будет получить вполне вменяемый ответ на решение проблемы. Также описание проблем сможет направить пуско-наладчика в нужном направлении. Баги довольно интересные, конечно.
Andrey_13
19.02.2025 23:04Ух, какая отличная статья. Поделюсь частью своего набора:
1.Разъем USB-B. После смены поставщика ( ну разъемы то похожие, по мнению снабружов) стали наблюдаться интересные явления: некоторые платы не определялись компьютером. Оказалось, что на новых разъемах контакты расположены ближе к задней крышке. Итог, припой образует мениск и образуется замыкание ножек на корпус. Там + шина c USB и одна из шин данных.
2.Тоже из раздела схемотехники. Много лет заказывали печатные платы. Посадочные площадки под штыревые разъемы всегда были металлизированы с обоих сторон и в отверстии тоже была металлизация. В последней партии приехали платы, а в отверстии металлизации нет. Оказалось, сменили изготовителя печатных плат, и он сделал в точности, как в герберах.
3.При переходе с камня STM32 на GD32 ( была черная полоса в заказах, нужно было делать продукцию, а обходных путей на ST, как и подделок не было) обнаружилось следующее: АЦП на GD32 не работает, хотя прошивка ранее работала на всех STM32. Детальное "курение" даташитов результата не дало. Ну одинаково было у них. Решилось все банальным уменьшением частоты опроса АЦП.
AKudinov
19.02.2025 23:042. Но ведь в Gerber не указывается (и даже нет возможности) наличие металлизации в отверстиях. Это в бланке заказа платы указывается. Да, интересный у вас поставщик. А с переходными отверстиями он справился успешно? Или проволочки пришлось впаивать?
Andrey_13
19.02.2025 23:04Металлизация переходных отверстий сделана правильно. На плате есть другие разъемы, в них тоже металлизация есть, все нормально. Видимо ранее тоже в сгенерированных файлах было отсутствие металлизации в конкретных отверстиях, но производитель сделал по своему. А сейчас просто решили сделать все по правильному.
zatim
19.02.2025 23:04Вроде бы, все что касается отверстий описывается в файле сверловки. А герберы да, только слои описывают. Сколько слоев, столько и герберов.
S_Elisei
19.02.2025 23:04Не люблю ардуинки идеологически, а после этого случая особенно. Достался как то раз чужой код и встала задача дописать в него команду на ребут. Ну, дело известное - включаем wdt, зацикливаемся, после ребута выключаем wdt. Не работает. Точнее ребутится-то плата хорошо, даже слишком, а если точнее - то циклически и бесконечно. Смотрели в код тремя парами глаз, выводили отладочные сигналы и трогали их осциллографом - ну вот не выходит из ребута и все тут. Оказалось, что для выключения wdt AVR требует установки битов в регистр в течении какого то количества тактов после старта программы (могу быть не точен за давностью лет, но там действительно был довольно небольшой допуск по времени). Ну а ардуинья библиотека банально не успевала это сделать. Переписали вручную эту часть - всё прекрасно заработало. Мораль - не верьте высокоуровневым библиотекам и читайте референс мануалы на контроллер.
MaFrance351
19.02.2025 23:04Я так писал прогу для управления газоразрядным индикатором с самосканированием (такой эпичный аппарат как ПИУ-2). Оказалось, ардуино с "медленными" digitalWrite не укладывается в тайминги сканирования индикатора (там текстовый дисплей из семи рядов точек, надо успевать выставлять на ножках вертикальную линию из семи точек, когда схема управления даёт сигнал на это) и текст разъезжался. Поменял на "быструю" работу с портами, и всё заработало.
zatim
19.02.2025 23:04Не так давно с этим же бодался. Насколько я понял, там дело не во времени, а в том, что биты в регистре нужно выставлять по отдельности, а не одной командой. То есть, нужно сделать в точности в той последовательности, как написано в даташите, шаг влево, шаг вправо - работать как надо не будет. Это достаточно не очевидный момень, так как обычно биты можно ставить/убирать в любом порядке, хоть скопом, хоть по отдельности.
S_Elisei
19.02.2025 23:04Сейчас открыл RM, нашел это место, вот так там было:
The sequence for clearing WDE and changing time-out configuration is as follows:
In the same operation, write a logic one to the watchdog change enable bit (WDCE) and WDE. A logic one must be written to WDE regardless of the previous value of the WDE bit.
Within the next four clock cycles, write the WDE and watchdog prescaler bits (WDP) as desired, but with the WDCE bit cleared. This must be done in one operation.
Сначала разрешаем изменения, а потом быстро их вносим, пока оно не запретилось обратно. 4 такта для библиотечной функции оказывается слишком мало
zatim
19.02.2025 23:04Да, это оно.
А разве библиотечная функция не должна проделать обе этих операции вместе для включения вотчдога? Там ведь всего 2 действия. Они что, растащили эти 2 элементарных действия по разным функциям?
S_Elisei
19.02.2025 23:04Она там действительно одна. wdt_disable(); но вот не работала. Во всяком случае в 2017 году, не в курсе как сейчас. Подозреваю что внутри этой функции было накручено.
fivlabor
19.02.2025 23:04Да, три года назад такое же с avr32uc3a столкнулся. Доставщиеся в наследство старые проекты на mplab.x.ide мигрировал. Всё красиво на C, а десяток строк - смена осциллятора на asm. Переписал на C - не работает. Оказалось, что даже со всеми оптимизациями не успевает, оставил старый код, но как-то не очень. Удручало, что гуглишь форумы, а ссылки на 404 ведут
Jorell
19.02.2025 23:04А ещё есть такое: для того, чтоб не тянуть кучу проводов от кнопок, решили на кнопки поставить резисторы с разным сопротивлением, а микроконтроллер в установке взависимости от сопротивления понимал какую именно кнопку нажали. Между пультом и установкой получилось всего 2 провода. Красотииища! Все довольны. Но со временем контакт в кнопках стал хреновым, и кнопки стали определяться некорректно. Пришлось переделать кучу пультов, вставить микроконтроллер в каждый, и проводов стало 3. Теперь опять все довольны. Но столько головной боли было.
MaFrance351
19.02.2025 23:04В каком-то мониторе (LG, кажется) видел такое решение с аналоговым выходом. И случилась та же история - контакты в кнопках окислились (их с самого момента производства монитора толком никто не нажимал) и регулировать параметры стало невозможно.
AKudinov
19.02.2025 23:04Такое решение вообще довольно распространено. У многих автомобилей кнопки на руле так обрабатываются.
zatim
19.02.2025 23:04Такое решение применяется в большинстве телеков и мониторов. Ну, кроме тех, наверное, где кнопки на самой плате стоят.
nv13
19.02.2025 23:04Есть комнатные пульты регуляторов для отопления, там 3 провода - земля, температура помещения с потенциометра, и выбор режима - с переключателя сделанного на дискретном потенциометре
DrGluck07
19.02.2025 23:04Мы даже для миллисекундных таймеров используем uint64. А использовать 32-битный счётчик для микросекундного таймера это вообще смелое решение.
kipar
19.02.2025 23:04По-моему наоборот хорошее - лучше сразу корректно обрабатывать переполнение, чем оно выстрелит один раз на объекте а до того не поймается никем.
AKudinov
19.02.2025 23:04положили SWD длиной 90 см и нет Link(а) с MCU
Что, в принципе, вполне ожидаемо при метровой длине. У нас как-то разработку блока SPI заказали, и потом заказчики жаловались на нестабильную работу на частоте 25 МГц. Оказалось, они SPI по многометровому кабелю, проложенному внутри своего "изделия", запускали.
zatim
19.02.2025 23:04Я в таком случае конвертировал spi в lvds, lvds в линию, а потом обратная конвертация. LVDS - согласованная диффпара, как в эзернете, ее можно тянуть достаточно далеко. Главное - если тянуть далеко, надо снижать скорость, чтобы фронты не сильно разбегались.
Jijiki
19.02.2025 23:04не в тему багов на железках, но про баги
помню самые эпик баги на одном из линуксов) ставишь дистрибутив и черный екран и всегда разное решение ) не во всех версиях и не каждое время, с чем-то связано, но наблюдал часто) еще смешные баги в Киберпанке помню когда игра вышла люди делали нарезки о своих багах, на какойто момент помню поймал себя на мысли, что это прикольно, но долго на багах не вывезешь, сейчас наверно большинство багов пофикшено )
Gryphon88
19.02.2025 23:04Всё родное...
"Есть контакт, где не должен, отсутствует, где нужен". Мое любимое: на логанализаторе ничего, тычешь мультиметром - всё, как должно быть. Оказалось, плохо припаял питание на сдвиговом регистре, и когда проверял мультиком - нога дожималась и всё работало.
"О нужности курилки и документации". То монтажник не то запаяет, то произойдёт рассинхрон бома и схемы.
"О внимательности и даташитах": когда поленился читать раздел на периферию целиком, надеясь, что тут изменений в логике не будет. Медитировал над кодом, потом пошел на крайние меры - почитал ДШ. Оказалось, что для включения ШИМ на advanced таймере нужно установить бит, которого нет на остальных.
Wesha
19.02.2025 23:04Самые Эпичные Баги при Программировании Микроконтроллеров
Вас Тоже Покусали Британские Газетчики, Пищущие Все Слова В Заголовках С Заглавной?
Этот баг называется «Мусор между разъёмами».
«Электротехника — это наука о контактах, а вернее — об их отсутствии.» ©
Этот баг называется: «толстые пальцы».
Вот прям интересно: и зачем человечество изобрело пинцеты?..
Загрузчик, к слову, писал коллега из другого дивизиона.
Вот что бывает, когда спортсменов (или военных) заставляют софт писать!
aabzel Автор
19.02.2025 23:04Вас Тоже Покусали Британские Газетчики, Пищущие Все Слова В Заголовках С Заглавной?
Нет. У меня просто диплом британского университета.
xkostuax
19.02.2025 23:04На объекте пропала связь от контроллера RS-482 до ПК, вся разводка идёт под потолком через все помещение. Приговорили преобразователь интерфейсов, но после замены ничего не заработало. Почесывая затылок пошёл попить чаю и увидел доп.блок системы через который проходил сигнал. На этом то блоке как раз и была наполовину выдрана фишка, которой там не должно быть( возможность есть, но только при подключении дополнительного оборудования, на комп по схеме идёт напрямую от контроллера). Баг называется монтаж не по схеме и невнимательность. Скорее всего монтажники сэкономили таким образом пару десятков метров кабеля.
aMster1
19.02.2025 23:04Потух пульт системы селекторной связи. Не видит его система. Берут из зипа второй, ставят - фик, тоже не видится. Блок питания, перезагрузки... А с утра "Очень Важный Селектор".
Спрашиваю - что делали? -Ничего. Все работало, но вдруг перестало. Продолжаю пытать, признаются что переделывали кроссировки. И тут меня осеняет, вспоминаю как 10 или даже 12 лет назад запускали систему, и я не мог оживить пульт после переноса его в другую комнату. Вся проблема в том (и тогда и сейчас) что пульт управлялся по rs485 и при перекроссировке путали А и В жилы. В общем через 3 минуты пульт завелся.
Gryphon88
19.02.2025 23:04Напоминает, как у нас был комп, где интернет работал только у мужчин. Оказалось, перебили кабель под полом, мужчины его весом до контакта прожимали, а девушки все стройные)
VelocidadAbsurda
19.02.2025 23:04В давнем проекте на AT91SAM7S256 написали прошивку, протестировали, всё отлично работало, девайс пошёл в массы, и тут от некоторых пользователей начали прилетать похожие жалобы «периодически намертво зависает при включении». Сделали возврат, получили свои коробки обратно, стали гонять - действительно, виснут. Меняем МК - не виснут, паяем «плохой» МК в нашу рабочую плату - виснет и тут, дело в МК. Попробовали изучить под JTAG-отладчиком - а он в состоянии этого зависания даже не подключается. Делаем «reset and halt» - подключается, ставим break на main и запускаем - труп. Трассируем стартовый код - умирает на включении PLL. Внимательно смотрим исходник (типовой стартовый код из Keil, копировали не задумываясь, «это ж Keil, а мы - юнцы зелёные»), заглядывая в мануал, и видим непотребство - одной записью в регистр и включается PLL, и осуществляется переключение на него (т.е. не то что не ждут готовности PLL, а ну прямо вообще одной операцией и запуск, и переключение). Вставляем ожидание готовности PLL, сразу всё начинает работать как надо. Дальше - обновление бутлоадера, где получилось и замены/возвраты, где нет.
tormozedison
19.02.2025 23:04«Однако если же USB вилку аккуратно выдвинуть всего только на полдлины, то так питание поступает! Оказывается был просто бракованный разъём гнезда для USB-A»
На Micro USB сталкивался с таким поведением несколько раз. Но чтобы на огромном USB-A - ни разу, даже на очень бюджетных кабелях.
kenomimi
19.02.2025 23:04Еще одно вспомнил. Купил как-то давно на али десяток stm32f437, которые с криптой. Удивился, чего оно так дешево - десяток за обычную цену пары. Но халява же! Штук шесть завелись отлично. Остальные, когда передаешь что-то по usb, почти сразу глухо висли. Сначала думал баг в коде, но нет - обнаружилось, что зависание происходит, если пакет 64 байта. Меньше - всё ок... Потом еще ловил F103 с нерабочим SPI - после инициализации любого из оных начинали нагреваться и висли. Да, китайцы собирают брак, не прошедший тестирование, и продают - будте осторожнее с халявой.
ProgerMan
19.02.2025 23:04Как-то был проект, где использовали Raspberry Pi с российским адаптером USB-to-RS485, сделанным по всем правилам. У заказчика внезапно перестало работать и перезагрузка не помогала.
Позже выяснилось, что у "правильный" адаптер при загрузке Linux должен быть вытащен из гнезда и вставлен обратно после загрузки. Тогда всё работает. В следующем проекте использовали купленный на AliExpress в 7 раз дешевле (брал для домашних проектов). Работал идеально - хоть сколько перезагружай.
MicroKoder
19.02.2025 23:04Схемотехник новичок первый раз разводил плату для управления BLDC мотором с датчиками холла. От провели длинные дороги через всю плату к фазам двигателя (он небольшой). Я начал отлаживать датчики холла, кручу руками вал - четкий сигнал. Запускаем с питанием - мотор дергается, не крутит, на датчиках шум. Мне имеют мозг, типа сделай программный фильтр на датчиках. Ковырялся несколько дней (сам был не опытен). Потом думаю погляжу ка я на линию питания МК, а там при запуске мотора просто шум дичайший, конечно МК в перезагрузку уходит 50 раз в секунду. Переделали плату, фазные дороги сделали короткими и разнесли подальше от сигнальных и питания МК, заработало как часы.
Случай после которого я вообще психанул на весь embedded. Контроллер не помню какой, но какой то Atmel 32 бит с Ethernet Phy. Задача поднять веб сервер, TCP сервер, UART и делать простые действия. Собрал проект в Harmony. Работает отлично, но спустя время зависает. Может зависнуть через 10 минут, может через 10 часов, может через 4 часа. Ковырялся чуть ли не месяц, пробовал разные аллокаторы памяти, думал может из фрагментации памяти ломается. Плюнул, снес проект и собрал с нуля заново. Перестал зависать, так и не понял почему.
Опять BLDC. Собрали плату для управления. уже опытные, собаку на моторах съели. На тестовом моторе работает как часы. Подключаем к мотору заказчика - дергает, еле крутит, ток повышенный. Репу чесали долго. Вешаем осциллограф на датчики холла - сигналы сильно кривые. Очевидно установка датчиков холла неправильна. Переделывали несколько раз, проверяли, считали углы - все равно кривые сигналы. Решили проверить магниты на валу. Нам показывают чертеж - да вот жеж все ровно. По факту оказалось что вал с магнитами сильно перекошен.
МК EFR32. На отладочной плате прошивка работает, на плате заказчика - не дышит. Оказалось на отладке есть дополнительный внешний тактовый генератор низкой частоты, а у заказчика его нет. Решение: в настройках проекта переключил на внутренний генератор.
схемотехник придумал питание пустить через монтажные стойки на плате, а земля полигоном по всей плате. Конечно когда стойку прикрутили коротнуло.
Проблемы тактирования, питания, перемкнутых контактов уже настолько тривиальные что проверяются в первую очередь когда плату собрали и первый раз прошили.
Gryphon88
19.02.2025 23:04схемотехник придумал питание пустить через монтажные стойки
Какое неочевидное решение)
TeCHNoiD
Круто! Спасибо, что поделились :)