Проблемами с постоянной нехваткой микросхем сейчас никого не удивить. Началось это всё ещё в конце 2020 года, в начале 2021 стала сильно тяжелее, с введением санкций в 2022 году стал просто кошмар! Я сейчас с грустью вспоминаю времена, например, 2019 года, когда при заказе партии микроконтроллеров в 2-3 тыс. шт. я выбирал на складах поставщиков самую низкую цену при этом ориентируясь на срок поставки в 1-4 дня! Тогда остатки у них в 20-30 тыс. шт. считались нормальным явлением. Начиная с 2021 года такие цифры тоже ещё можно было увидеть, но сроки выросли до 15-30 дней. Сейчас реальность такова, что поставка в течение 30 дней считается уже большой удачей, если удаётся отхватить партию микросхем хотя бы в 500-1000 шт. Обычный срок 50-60 дней. При этом даже при своевременной оплате счёта нельзя быть уверенным в поставке. У нас до сих пор из 10 заказов отменяется почти половина. Объясняют это тем, что "кто-то уже перехватил данную партию", хотя мы давно уже платим вперёд и держим у поставщиков на депозите определённый запас денежных средств для мгновенной оплаты. Про такие моменты, конечно, можно рассуждать ещё долго, но я хотел бы коснуться некоторых технических нюансов, которые всплыли из-за всей этой ситуации. Из-за проблем с поставками мы постоянно занимаемся поиском аналогов всех используемых микросхем. И если с той же I2C-памятью, драйверами RS-232, RS-485 проблем нет, так как их всегда можно чем-то заменить, то вот с микроконтроллерами и преобразователями питания большие проблемы. Про спец. микросхемы вообще молчу. Сейчас мы стараемся их не использовать вообще. В первой части статьи пойдёт речь о микроконтроллерах. Так сложилось, что мы используем в основном продукцию компании Microchip. Уже в прошлом году под текущие проекты было практически нереально оперативно приобретать более-менее приличные партии одного вида микроконтроллеров. Поэтому нам пришлось в одном и том же устройстве использовать различные модели. Сейчас разнообразие моделей только в одном контроллере мониторинга и управления ИБП "СКУП-2" достигает 8 шт! Это порождает следующие проблемы: Необходимость изготовления различных печатных плат под разные корпуса микросхем. Необходимость сборки универсальной прошивки под все типы микроконтроллеров. Первую проблему решаем так: По возможности пытаемся объединять на одной плате посадочные места под два типа микросхем. Сейчас вариант с TQFP + QFN является для нас фактически нормой: Тут ещё добавляется проблема с Ethernet-контроллером, который тоже получается доставать в двух видах – корпус SOIC с шагом 1,27 мм и корпус SSOP с шагом 0,65 мм. Но под него универсальное посадочное место сделать не получилось. В итоге мы имеем целый набор плат с различными комбинациями контактных площадок. Но, надо сказать, что проблема с платами в целом решается не так уж и сложно. А вот с созданием единой прошивки пришлось попотеть. Понятно, что она "единая" только абстрактно. Мы используем микроконтроллеры совершенно разных подсемейств, у которых периферия отличается очень сильно. Например, PIC18F46K22 и PIC18F46Q43. Поэтому пришлось в первую очередь максимально переработать наши библиотеки для работы с периферией. В них появилось большое количество define’ов, но в итоге получилось свести всё к единому стилю. Полностью отличается только начальная инициализация микроконтроллеров, но и тут мы постарались максимально унифицировать её в пределах похожих подсемейств. Далее мы добавили в каждую прошивку функцию для определения "типа микроконтроллера", по факту просто код модели. Это нужно для софта верхнего уровня при обновлении "прошивки". Код представляет собой одну букву от A до Z за исключением буквы X (об этом будет ниже). Таким образом, у нас на данный момент есть возможность использования 25 типов микроконтроллеров в одном устройстве. Надеюсь, что этим всё и ограничится 😁. Разработку "прошивок" для микроконтроллеров мы осуществляем в среде MPLAB X. Там есть очень удобная штука в настройках проекта – конфигурации. Для каждого типа микроконтроллера мы задаём свои уникальные параметры: адрес расположения загрузчика и т.п. В результате весь проект можно отлаживать на какой-то одной модели (стараемся брать самую "дохлую" в плане периферии и памяти, например, PIC18F46K22), а затем уже пересобирать под все остальные типы: В итоге мы получаем набор hex-файлов, которые фактически должны идти на одну и ту же плату, но с разными моделями микроконтроллеров. Чтобы пользователь не мог перепутать и залить "прошивку" от другой модели мы поступили следующим образом. Написали небольшую утилитку, которая из набора этих hex’ов формирует единый контейнер (фактически это ZIP-архив), содержащий все эти файлы, а также небольшой XML-документ, в котором прописано соответствие нужного файла и "типа микроконтроллера".  Вот пример такого документа: Здесь имеется определённая гибкость. К примеру, одна прошивка может соответствовать разным типам микроконтроллеров. Также контейнер может содержать дополнительные файлы, например, Web-интерфейс устройства. Они тоже содержатся в списке. При этом наши hex-файлы имеют дополнительную метаинформацию: номер версии, дату и время сборки, код устройства, имя файла Web-интерфейса и т.п. Подобные данные оформляются в виде строк, начинающихся с точки с запятой: Эта информация добавляется автоматически отдельной утилитой после окончания сборки прошивки. При формировании контейнера проверяются все "перекрёстные ссылки", а также совпадение номеров версий для всех видов "прошивок". При обновлении "прошивки" софт для ПК считывает "тип микроконтроллера" с платы и достаёт из контейнера нужный hex-файл. В случае группового обновления устройств для каждого из них эта процедура повторяется автоматически: Особняком в данной системе стоят платы, выпущенные до 2020 года, когда чип использовался всегда один. Они тогда ещё не имели функции считывания "типа микроконтроллера". Для таких вариантов у нас используется "прошивка по умолчанию". В контейнере она помечается буквой X. В большинстве случаев такой микроконтроллер поддерживается и сейчас, поэтому подобные прошивки идут, как правило, с двухбуквенным типом: AX, BX и пр. В следующей части я расскажу как мы делаем свои субмодули, тоже с целью максимальной универсализации.  Схемотехник