Подключение SD карты по SPI (Капсула памяти)

В этом тексте я написал про некоторые особенности работ c SD картами при соединении их с микроконтроллером по интерфейсу SPI.
Разработка электроники

В этом тексте я написал про некоторые особенности работ c SD картами при соединении их с микроконтроллером по интерфейсу SPI.

Я заметил, что в сообществе FPGA многие задают вопросы, которые можно решить с помощью DMA. Сделал поиск по Хабру в поисках чистых статей о том, как запустить DMA и не нашел таких. Поэтому решил в этой статье собрать свои знания в кучу и показать, как пользуюсь DMA . Это будут чистые примеры, без лишней информации, также будут сравнительные тесты разного характера.

Каждую ночь мы поднимаем глаза к небу и видим один и тот же рисунок созвездий, полагая, что наш дом стоит на надежном фундаменте вечности. Это иллюзия, дарованная нам милосердной краткостью человеческой жизни. На самом деле мы — пассажиры, несущиеся сквозь водоворот звездных вихрей с немыслимой скоростью, и наше Солнце — не неподвижный маяк, а пассажирский автобус на опасном галактическом хайвее. Миллиарды лет Солнце уводило Землю от гибельных взрывов сверхновых, проносилось сквозь облака радиоактивной пыли, расходилось на встречных курсах с проносящимися мимо звездами. Мы, смотрящие на звездное небо, не замечаем этой гонки. Куда ведет эта дорога, какие призраки прошлого остались позади и что ждет нас за горизонтом?
Заметил недостаток качественных статей по атомикам. Сам когда-то столкнулся с тем, что хотел прочитать статью, где простым и понятным языком рассказывается об этом, но, к сожалению, найти не смог.

Когда я впервые начал всерьез работать с кодинг-агентами, казалось, что это магия: просишь поправить модуль, а через пару минут у тебя уже пулл-реквест. Но чем больше я ими пользовался, тем чаще ловил себя на одном и том же: агент то ломает билд, то игнорирует важные договоренности по архитектуре, то переписывает код "как ему удобнее". И каждый раз приходилось руками разгребать последствия "умной" автоматизации.
Со временем стало очевидно: проблема не в модели, а в том, как мы ее онбордим в проект. Один и тот же Claude в одном репозитории ведет себя как сильный мидл, а в другом как растерянный стажер. Разница почти всегда в том, что написано (или не написано) в CLAUDE.md и его аналогах для агентов.
Я перепробовал кучу подходов: от огромных "библий" с правилами до минималистичных заметок и автогенерации. Что-то работало, что-то категорически нет. В итоге вырисовались простые, но хорошо проверенные на практике принципы того, каким должен быть CLAUDE.md, чтобы не было мучительно больно ни вам, ни агенту.

Иногда мы решаем вопросы достаточно быстро, как на автомате, а иногда приходится быть полностью включенными, чтобы себя контролировать и находить узкие моменты из-за которых задача нетривиальная и нужно находить индивидуальный подход. Но иногда мы можем перепутать задачи, подобрать некорректный подход к решению. И во всем этом “виновато”наше мышление. Враг оно или друг? Тема касается каждого человека.
Мышление используется ежеминутно для решения множества задач, иногда параллельно решая разноплановые задачи, а иногда полностью погруженным в задач, и все это отражается на наших способностях, когнитивных способностей… Иногда происходит классная эффективность, иногда происходит сбой, перегруз. От чего это зависит и можно ли на это влиять?

Всем привет и наступающими! Захотелось тут сделать пару гаджетов для друзей в их умные дома. И что-то вдруг подумалось - а что они все скучные такие? Давайте же сегодня сделаем датчик в таком форм-факторе, в котором точно не купишь в магазине, будет отличный подарок на Новый Год или Рождество. Ну и ещё чтобы подарить было не стыдно.

Продолжая развивать свою синтезируемую систему-на-кристалле для ПЛИС, о которой я уже написал несколько статей, столкнулся с необходимостью подключать устройства ввода типа клавиатура, манипулятор мышь или джойстик. Если обратиться к тому, чем занимаются ретро-фаны, то проблем особых нет — старый добрый интерфейс PS/2 очень прост в реализации, он позволяет легко взаимодействовать с клавиатурой и мышью с минимальными ресурсами. Фактически PS/2 это последовательный синхронный порт работающий на низких скоростях, реализовать его можно программно. С ретро-джойстиками тоже проблем нет - положение джойстика это всего лишь замыкание контактов, что легко обрабатывается программно. Проблема в том, что всё это «ретро» постепенно уходит из нашей жизни, клавиатуры и мыши с интерфейсом PS/2 всё еще можно приобрести на маркетплейсах, но всё же редкость. И от джойстика хочется чего-то большего чем просто замыкания пяти контактов, а именно — градации положения стика. Такая фича доступна либо на очень старых аналоговых джойстиках, либо на современных геймпадах с USB интерфейсом. В конце концов я разрабатывают хоть и минималистичную, но современную систему с современной архитектурой (RISC-V) предназначенную для современного промышленного применения, а не для ретро-гейминга. ;-) В общем, встал вопрос как подключать простые HID устройства ввода через USB к своей синтезируемой ЭВМ.
Интерфейс шины USB на столько широко вошел в обиход, что мы даже не задумываемся что там внутри: сколько сигнальных проводов в USB кабеле, как они подключены, как передаются по ним данные, на каких скоростях и какие могут быть ограничения. Всё что мы знаем это то, что USB бывает разных версий: 2.0 — медленный и 3.0 — очень быстрый; и что USB устройства бывают с разными видами разъемов: USB type A и, с недавних пор, USB type C. Для большинства пользователей и программистов USB это такая штука, которую «вставил и работает». А если нет, то нужно вынуть, перевернуть устройство два раза вокруг его оси и вставить в компьютер еще раз. Если и так не заработало, то искушенный пользователь возможно вспомнит команду lsusb чтобы выяснить какие сейчас устройства присутствуют в системе или даже заглянет в dmesg чтобы выяснить наличие ошибок при детектировании устройства. Но что означают эти сообщения ? Еще меньшее число пользователей понимает результат вывода команды lsusb -v. Не многим лучше обстоят дела с пониманием USB у разработчиков электроники. Обычно на их уровне USB это четыре провода: GND, VBUS, D+ и D-, при этом каждый электронщик знает что D+ и D- это дифференциальная пара которую требуется трассировать на печатной плате соответствующим образом. Но так ли это на самом деле ?
Раз уж возникла необходимость, то надо погружаться в тему если не по уши, то хотя бы по пояс и выяснить, а на сколько сложно реализовать свой собственный минималистичный USB контроллер. Ведь задача то очень простая — считать пару байт с USB клавиатуры, и, как мне казалось, осилить её можно за пару-тройку ночных сейшнов.

Так сложилось, что программируя микроконтроллеры, разработчик балансирует между двумя крайностями. Все ресурсы под твоим полным контролем — и это кайф (думаю, многие в embedded за этим и идут). Но платой становится сложность встраивания базовых инструментов, которые стали де-факто стандартом в других областях разработки. Сложность хотя бы в том, что они не идут из коробки.
Возьмём обычную задачу: включить фару на устройстве.
На практике наша железка должна загрузиться, зарегистрироваться в LTE-сети, поднять TLS-соединение с MQTT-брокером, синхронизировать состояние и пройти ещё кучу слоёв бизнес-логики. С другой стороны — мобильное приложение и бэкенд для управления этой лампочкой (уже целая система собралась!). Там не меньше логики: от авторизации до “да кто блин так дизайн спроектировал?”. Пока дотапаешься до кнопки, пройдёт вечность.
В итоге, любое простое действие требует либо полного рабочего стека, либо моков с тестовыми сборками и отключёнными проверками. Либо дебагера с брейкпоинтами и ручными правками памяти. Всё работает, но каждый раз жрёт уйму времени и внимания.
Хотелось бы проще. Нужен способ аккуратно вмешаться в работу устройства — без отключения основной логики, без специальных сборок и независимо от режима. Не просто физическая кнопка, а полноценный интерфейс: настраивать параметры, включать/выключать функции, забирать данные.
И стало ясно: нам не хватает shell-интерфейса. Или CLI. Или терминала — называйте как угодно (разницу можно глянуть здесь). Но не просто не хватает — его придётся писать самим. Меня зовут Сергей Шилин, я руковожу разработкой электроники и встроенного ПО в Whoosh. Почему не взяли готовое и чем наш велосипед лучше — расскажу под катом!

В С++ 20 появились coroutines (далее буду называть их корутинами, по‑русски). Если кратко — они позволяют писать асинхронный код также как мы пишем синхронный. При этом асинхронный код это не обязательно должен работать с несколькими потоками. Асинхронным может быть код исполняемый в одном потоке.
Под капотом компилятора корутины — это просто синтактический сахар (syntax sugar). Т.е. корутины не создадут дополнительных потоков. Компилятор заменит корутины вызовом нескольких функций и не более того. Но давайте посмотрим как корутины выглядят в коде.
В этой статье я буду делать простейший таймер на основе корутин. При этом напишу классы, для Awaitable и Promise, которые необходимы для работы корутин.

В новой статье от команды AI for Devs разбираемся, как организовать вайб-кодинг с плагином Kilo Code в VS Code и IntelliJ IDEA из России. Пошагово настраиваем Kilo Code через RouterAI, подключаем Claude, GPT, DeepSeek и другие модели, разбираем роли агента, diff-патчи, правила проекта и нюансы работы с контекстом.

Продолжаем серию «C++, копаем вглубь». Цель этой серии — рассказать максимально подробно о разных особенностях языка, возможно довольно специфичных. Это девятая статья из серии, список предыдущих статей приведен в разделе 6. Серия ориентирована на программистов, имеющих определенный опыт работы на C++. Данная статья посвящена специальным функциям-членам.
В C++ жизненный цикл экземпляра класса/структуры/объединения (объект, представляемый в коде переменной) начинается с инициализации, то есть задания его начального состояния. Далее, почти всегда, объект копируется, выполняются присваивания или их перемещающие аналоги. Эти операции необходимы для работы функций, контейнеров, алгоритмов. Финальной точкой жизненного цикла объекта является его уничтожение. Именно для поддержки этих операций в C++ и предназначены специальные функции-члены.
Важная особенность специальных функций-членов — это то, что в их реализации принимает участие компилятор. Реализации специальной функции-члена частично (а в ряде случаев и полностью) может быть сгенерирована компилятором. Кроме того, во многих случаях программист не вызывает явно специальные функции-члены в своем коде, эти вызовы генерируются компилятором в определенном контексте.
Итак, попробуем рассказать о специальных функциях-членах максимально подробно.

Данная статья — это своего рода продолжение Верификация цифровых схем. Обзор.. В ней хотелось показать некоторые типы тестовых окружений для функциональной верификации и особенности работы с ними.
Хотя у каждой компании/проекта есть свой маршрут функциональной верификации, возникший в определённых обстоятельствах — порождение опыта, ошибок и обстоятельств, — не всегда применяемые там решения являются предметом гордости.
И если вам случилась такая удача — разработать новое тестовое окружение или переработать существующее, — данный материал может подтолкнуть в сторону оптимального варианта в некоторых случаях. Может, и не подтолкнуть… или подтолкнуть не туда...
Хочу обратить внимание на слово функциональный: в данной статье я не буду затрагивать формальную верификацию и эмуляцию, т.к. эти темы довольно большие сами по себе.

Статей про Docker много не бывает.
В этом материале мы разберём базу: что такое Docker, как он работает и зачем нужен, а затем пошагово пройдём путь от установки до запуска первого контейнера.

Перед вами детальный разбор TCP — движущей силы интернета, в котором мы шаг за шагом рассмотрим принципы этой технологии на подробных примерах.
Интернет — невероятное изобретение. Людей от него за уши не оттащишь. Вот только есть у этого изобретения проблемы с надёжностью — пакеты теряются, каналы перегружаются, биты путаются, а данные повреждаются. Ох, какой же опасный мир! (Буду писать в духе Крамера).
Хорошо, почему же тогда наши приложения вот так просто работают? Если вы выводили своё приложение в сеть, то процесс вам знаком: socket()/bind() здесь, accept() там, возможно, connect() вон там и, вуаля — данные надёжно текут в обе стороны упорядоченным и целостным потоком.
Сайты (HTTP), сервисы e-mail (SMTP) или удалённый доступ (SSH) — всё это построено на основе TCP и просто работает.

RDP — самый распространённый протокол и клиент для удалённого доступа к рабочему столу. Но у него тоже есть свои недостатки: низкая производительность и ненадёжность. Поэтому приходится использовать альтернативы вроде Sunshine+Moonlight, которые в некоторых случаях обеспечивают лучшее качество.
Однако для удалённого управления сервером RDP остаётся признанным стандартом. Что же делать, если RDP тормозит? Как «ускорить» удалённый рабочий стол, если соединение с сервером неустойчивое? Эта тема актуальна для фрилансеров, админов, игроков, удалённых сотрудников и др. Они могут оптимизировать настройки своего ПК и удалённого сервера (если есть доступ), чтобы уменьшить лаги.

Данный пост посвящён детальному разбору вещественного типа данных с плавающей точкой удвоенной точности double

TunerPRO это бесплатный бинарный редактор прошивок. Это аналог STM32Studio.
Эта программа позволит вам редактировать константы в готовом bin файле. Минуя стадию повторной пере сборки всего проекта прошивки. Можно сказать, что TunerPRO хакерская tool-а.
Эта утилита связывает воедино всю информацию про переменные. Это адрес ячейки памяти в бинаре, название физической величины, размерность переменной, размер параметра, формат ее хранения в памяти, имя переменной, множитель, единицу измерения, максимальное и минимальное значение. В то время как тот же *.map файл дает только сведения про имя адрес в памяти и размер.

В программировании микроконтроллеров порой надо сделать так, чтобы после сборки артефактов в прошивке глобальные константы оказались в строго заданных адресах NOR Flash памяти. Причем при пересборке проекта эти адреса оставались прежними.
Это особенно полезно, если вы решили конфигурационные и калибровочные выделить в отдельный интервал Flash памяти.
Потом это требование международного стандарта программирования ISO-26262.
Делается для того, чтобы появилась возможность менять значения в этом интервале утилитой TunerPRO перед прошивкой бинаря.
Фиксированные адреса констант позволят вам всегда иметь один и тот же *.xdf файл для утилиты TunerPRO.

Я давно хотел написать статью или пост на эту тему, поскольку заметил проблему с некорректным пониманием синтаксиса так называемой «деструктуризации» в JavaScript. Эта информация будет особенно интересна разработчикам, использующим React, где деструктуризация (например, в хуке useState) встречается повсеместно.