Comments 42
Много картинок, много рассуждений, а самое главное не написали - ваши таймстампы будут сильно зависеть от температуры, от точности настройки rtc и т.д. Так, побаловаться пойдет, а что-то серьёзное на них не построить.
Удивился на цитату. Ну что же, тогда вот и мои три копейки. Не критика, а просто в дополнение.
По совпадению, примерно с месяц назад откопал свою старую макетку STM32F4 DISCOVERY и решил оживить. Последний раз я что то кодил для мк более 10 лет назад, и тогда же последний раз писал на Си, т.е. забыл почти все по этой теме. Но, мне было очень интересно как LLM может помочь в эмбиддерстве. Что я сделал:
- спросил чатгпт, какой софт ставить. Был дан ответ, ставить STM CubeMX и CubeIDE. Поставил, запустил.
- спросил чатгпт, как сгенерить профиль в CubeMX для проекта VirtualCom port для моей платы. Не сразу, но по наводящим вопросам удалось пробиться через конфиги и сгенерить проект. Т.е. все изложенное в этой публикации я проделал под четким руководством чатагпт буквально минут за 15, без чтения документации/гайдов, и вообще не включая мозг (гордиться нечем, знаю, но сам факт).
- попросил чатгпт сгенерить мне код для VirtualCom port, включая небольшой обработчик команд / эмуляцию консоли. Заработало почти сразу: Я копипастил код в IDE, запускал, ошибки копипастил обратно в чатгпт, и следовал его указаниям. После нескольких таких итераций все заработало.
- потом еще спросил чатгпт от файн-тюнить код для максимальной пропускной способности виртуального компорта. Ну и заодно спросил хороший терминал для винды, чтобы все это погонять в железе.
Что я хочу сказать. У меня несколько знакомых программистов сейчас сидят без работы. Компании сокращают штат в пользу LLM, отсюда массовые увольнения. Похоже, это скоро коснется и эмбиддеров. А там и до меня доберутся. Но! Есть и плюсы. Для хоббистов теперь открыты все возможности, порог вхождения опустился ниже плинтуса.
Сейчас модно ембеддидь на RP2350. А ещё у него есть к основному ядру маленькие ядра PIO, привязанные к GPIO. Эти PIO работают на частоте ядра (150 МГц), у них есть простенький ассемблер из 7 комманд, а также несколько сдвиговых регистров и линий для прерывания основного ядра. Код и для основного ядра и для PIO пишется на Питоне. Разумеется код на Питоне пишут сейчас при помощи LLM.
Так что вероятно, плату с STM32F4 можно отложить обратно на полку :)
Очень тонкий ответ ;) Как и сама статья в ответ на статью одного из "экспертов" (по крайней мере мне так показалось) :)
Они сидят без работы, потому что экономика хромает, а не из-за ИИ. Эмбедеры будут нужны, потому что у них есть лапки, а у ИИ нет.
Попробуйте что-то посложнее. Скажем, что то несложное для джуно-миддла в эмбедде. Например - "напиши на HAL для STM32F4 рабочий драйвер датчика AM2302. Вывод результатов через UART. Постарайся написть так, чтобы можно было просто подставить твой код в пустой проект STM32CubeIDE". Результат ИИ вас разочарует. Мягко говоря, придется подебажить и совершить много итераций.
Я сам использую ИИ и рад такому инструменту. Но реклама его возможностей, на мой, субъективный взгляд, пока опережает эти возможности.
Чат умеет читать даташиты, использовал его для поиска ОУ на замену, в частности искал аналоги TI у AD, и наоборот. Для такой задачи работает, но - требовать написать драйвер на основе описания регистров в даташите, конечно же перебор. Т.е. в данном примере я бы попросил сгенерить код для чтения/записи по интерфейсу (I2C?), а вот уже с регистрами команд и данных этого конкретно датчика разбирался бы вручную. Проверять как это сработает в реале не буду, разумеется. Просто мысли с дивана :-)
У себя по работе (топология ИС) тоже теперь часто использую ИИ. Буквально за последний год все изменилось, стало проще накидать промт, чем кодить самому. Но - не агитирую, и не спорю что пока это костыли, а не тул
У себя по работе (топология ИС) тоже теперь часто использую ИИ.
Ого. Круто. Прямо кристаллы проектируете? Приятно, что эксперты вашего уровня есть в русскоязычном коммюнити.
У себя по работе (топология ИС)
Кстати, любопытно, что происходит с топологом после того, как микросхема выпущена в производство?
Я имею ввиду, что в до-ИИ-шные времена линейные программисты какого-нибудь энтерпрайза могли работать в режиме "фигак-фигак-в-продакшн", а потом долго сидеть "на поддержке".
С электронщиками всё сложнее. Пока устройство разрабатывается, электронщик нужен, но он не приносит доход бизнесу. Как только устройство выпущено, бизнес начинает получать прибыль, однако электронщик, вообще говоря, перестаёт быть нужным.
Но в электронике хотя бы порог входа исчисляется сотней долларов. Простенькая плата в Резоните тысяч 5; МК, рассыпуха, монтаж - тоже плюс-минус также.
То есть
во-первых при наличие серъезных проблем с первой версией изделия всё-таки есть возможность выпустить версию №2;
во-вторых есть возможность работать над единичными устройствами.
А в разработке микросхем как?
Как представляется, единичное производство - это вообще не про микросхемы.
Да и выпуск ver.2, ver.3, ver.100500 - тоже накладен.
Прогоняет ли менеджмент такую тему, типа:
"Мы всё понимаем и искренне ценим ваш вклад. Но и вы нас поймите, мы коммерческая организация. После успеха нашего чипа мы ориентированы на масштабирование его производства и расширении сбыта. На данный период мы заинтересованы скорее в большем количестве маркетологов. Но мы помним о вас и обратимся, если решим расширить линейку. Просто сейчас для этого не самый подходящий момент"?
Кстати, любопытно, что происходит с топологом после того, как микросхема выпущена в производство?
Вы все верно написали. Чем больше штат, тем больше заказов, и эффективнее загрузка инженеров работой. Не говоря уже про лицензии на софт.
Разовые проекты интересны инженеру только если это твой стартап, либо если работаешь как ИП с несколькими клиентами. Понятно, что в РФ мало кто так может, поэтому предпочитают сидеть на зарплате ровно и пинать балду между проектами. Так же и менеджменту интереснее работать с ИП, а не содержать штат, но на деле мало кто готов бодаться с налоговой (за работу с ИП "кошмарят").
Еще потихоньку развиваются аутстафф сервисы, но туда идут работать только с иностранцами (китайцами), во всех остальных случаях это никому не выгодно - ни инженерам, ни их клиентам. Могу ошибаться.
Чем больше штат, тем больше заказов, и эффективнее загрузка инженеров работой. Не говоря уже про лицензии на софт.
Как представляется, выпускать каждую неделю по принципиально новой микросхеме ни у какого отдельного заказчика нет необходимости. А значит, команда разработчиков будет сбиваться в инжиниринговый центр и "засасывать" все возможные заказы, чтобы пустить равномерный поток работы через себя.
Если с разработкой смартфонов происходит именно так (Ваш Xiaomi — это не Xiaomi. Кто делает китайские телефоны на самом деле?), то уж с разработкой микросхем, как кажется, - и подавно должно.
Но укрупнение и концентрация ресурсов должны приводить к монополии.
А монополия - к унификации и отсутствию конкуренции. По идее.
И, типа, варианты для решения какой-то технической задачи:
- либо, условно, покупается готовый MIK32 Амур;
- либо "разрабатывается кастомная микросхема", но она будет разрабатываться в том же центре, где разрабатывался Амур, людьми, лучше всего разбирающимися в Амуре, и она будет чрезвычайно похожа на Амур.
Второй вариант приводит к мысли, а не проще ли тогда всё-таки использовать первый вариант? Не проще ли, условно, сделать свой SoM на базе Амура и дискретных компонентов, чем заказывать разработку новой микросхемы?
это пока жэлезка на столе, в полях чатжпт разработчика не заменит
Если взять STM32U031R с максимальной частотой тактирования ядра в 56 МГц и попытаться охватить периодом измерения 1 год, обеспечив при этом максимально возможную точность
интересно зачем может потребоваться год измерения с такой точностью?
Но если в прерываниях таймера просто инкрементировать 32-битный ИНТ, то на месяц вполне хватит значения счетчик таймера+32 бит переменная, и таймеры соединять не надо (и никого продавать не надо, как говорил дядя Федор). Но максимальная точность (=тактовой частоте проца) у вас все равно не получится потому что нужно время чтобы считывать значения, а в это ВРЕМЯ может произойти прерывание... и не только от этого таймера.
Перефразируя классика можно сказать что, "вопросы времени самые сложные вопросы в программировании (а может и вообще в технике)".
Спасибо за статью.
В постановке задачи генерации абсолютных временных меток есть не упомянутая в статье сложность. Понятие абсолютного времени предполагает привязку либо к мировой инфраструктуре синхронизации времени (условно, NTP), либо к другим устройствам, использующим эти же абсолютные временные метки.
По указанной причине рассматривать применение RTC для генерации точных абсолютных меток некорректно без учёта точности значения, лежащего в самом RTC. А если в рассмотрение взять синхронизацию абсолютного времени, то точность абсолютного времени будет зависеть в большей степени от него.
Для задачи измерения длительности интервала времени проще использовать интерфейс 64-битного бегущего счётчика. Такой можно построить на основе 32-битного системного таймера в STM32.
таймстампы будут сильно зависеть от температуры, от точности настройки rtc и т.д.
применение RTC для генерации точных абсолютных меток некорректно без учёта точности значения, лежащего в самом RTC.
Уже второй комментарий в этом не слишком бурном обсуждении со словосочетанием вроде "точность самого RTC". Есть точность тактового сигнала, используемого RTC, это да.
А что такое "точность самого RTC"?
Часы реального времени хранят текущие дату и время. В сответствие с тактовым сигналом, от которого запитан RTC, происходит увеличение текущего значения времени. В этом процессе играет роль точность генератора тактового сигнала RTC (сдвиг частоты генерации от заявленной производителем, стабильность частоты генерации).
Но надо не забывать, что часы реального времени начинают отсчёт с некоторого значения, которое тоже может быть неточным. Это может играть роль только если значение абсолютного времени, полученного из этого RTC, сопоставляется со значением времени, полученным из другого RTC (на какой-то другой машине).
Если сопоставлять таймстемпы событий нужно только в рамках одной машины, то RTC здесь не единственное решение, и более точный результат по измерению длительности интервала времени обычно дают счётчик или таймер, но не часы реального времени.
На STM32 системный таймер 32-битный, и требуется обрабатывать прерывания по переполнению. rdtsc на x86, конечно, удобнее.
Если сопоставлять таймстемпы событий нужно только в рамках одной машины, то RTC здесь не единственное решение, и более точный результат по измерению длительности интервала времени обычно дают счётчик или таймер, но не часы реального времени.
Дано: вам нужно собирать таймстампы и измерять между ними интервалы времени длительностью, скажем, до 10 суток, ядро микроконтроллера затактировано от внешнего кварцевого генератора (HSE). Также от HSE через делитель затактированы RTC.
Расскажете, как таймер окажется точнее, чем RTC?
Предлагаю решение для STM32F4, т.к. документация под рукой (точность решения оценочно 1 мкс).
Оно задействует только SysTick из Cortex M4.
Рекомендованная частота тактирования RTC: RTCCLK = 1 МГц.
По дереву тактирования можно настроить хоть HSE/2 (регистр RCC_CFGR, биты RTCPRE),
но в описании предделителя указано, что требуется настроить входную частоту RTC в 1 МГц.
В любом случае, интересно сравниться с 1 МГц.
Для SysTick максимальная частота тактирования - это частота шины AHB, т.е. частота HSE.
Размер счётчика SysTick - 24 бита. Для HSE=100МГц его хватит на пару секунд, это сильно меньше требуемого интервала времени.
Поэтому текущее время в наносекундах будем хранить в 64-битной переменной counter (точнее, старшие 40 бит).
Для счётчика SysTick настроим прерывание с частотой 100 Гц. Для частоты HSE=100МГц RELOAD_VALUE = 10000000, это помещается в 24 бита.
В обработчике прерывания будем инкрементировать значение переменной counter на RELOAD_VALUE, т.е. на 10000000.
Для получения текущего значения счётчика в цикле:
Считываем переменную counter:
- Считываем младшие 32 бита counter.
- Выполняем барьерь dmb во избежание переупорядочивания транзакций на шине.
- Считываем старшие 32 бита counter.
Считываем текущее значение счётчика SysTick
После барьера памяти (dmb) заново считываем младшие 32 бита переменной counter.
Если младшие 32 бита счётчика изменилились, то переходим к этапу 1 цикла.
После цикла текущее значение счётчика SysTick необходимо сложить с текущим значением переменной counter, при этом не забывая, что SysTick - убывающий счётчик.
По сути, SysTick - это младшие 24 бита метки времени, а counter - это старшие 40 бит.
Цикл необходим для синхронизации с обработчиком прерывания SysTick. При этом оборотов цикла будет не более двух, т.к. прерывания SysTick достаточно удалены друг от друга.
С учётом того, что тут десятка два инструкций (реализация на ASM), решение всё-таки не даст точности больше 1 мкс при HSE=100 МГц.
Но оно как будто бы и не хуже решения с RTC. 10 суток в 64 битах помещаются.
Если что, я его не выдумал, оно вполне себе работает.
4.Если младшие 32 бита счётчика изменилились, то переходим к этапу 1 цикла.
кажется возвращаться в начало цикла смысла уже нет если вам нужен тайм-стамп события которое запустило измерение,то есть произошло до начала цикла. Можно просто вернуть инкрементированное значение старших битов с младшими установленными в ноль, а для лучшей точности надо декремент делать старших битов и соединить с изначальным значением младших. Очень внимательно надо смотреть что вы хотите получить! Это значение времени (в относительных тиках) непосредственно до измерения или в определенный момент во время измерения. Погрешность измерения разных моментов будет разная в течении периода измерения и расчета измеренного значения. Но для тех кто привык уже работать с помощью промтов уровня: " как сгенерить профиль в CubeMX для проекта VirtualCom port для моей платы." (это как пример, а не в упрек автору промта, я и сам иногда такие промты пишу, то есть с них начинаю выяснение по теме теперь, имеются ввиду те кто не хочет уже идти глубже этих промтов) все детали этого решения вряд ли получится осознать.
Но оно как будто бы...
кажется возвращаться в начало цикла смысла уже нет...
Очень внимательно надо смотреть что вы хотите получить!
...или использовать готовое аппаратное решение и стандартные библиотечные функции. Ага.
Мой изначальный вопрос относился к вашему тезису:
более точный результат по измерению длительности интервала времени обычно дают счётчик или таймер, но не часы реального времени.
И таймер и RTC, в своей основе имеют счётчики, считающие импульсы. Мне было интересно, за счёт чего вы предполагаете увеличение точности первого в сравнении со вторым, если они могут быть затактированы от единого источника?
На этот вопрос вы вполне ответили:
С учётом того, что тут десятка два инструкций (реализация на ASM), решение всё-таки не даст точности больше 1 мкс при HSE=100 МГц...
вы перепутали это не мои тезизы. Но я могу пояснить почему
более точный результат по измерению длительности интервала времени обычно дают счётчик или таймер, но не часы реального времени.
это не корректно:
И таймер и RTC, в своей основе имеют счётчики, считающие импульсы
так как И таймер и RTC имеют в своей основе генераторы импульсов (частоты), но для RTC используются генераторы частоты повышенной точности и с подстройкой этой частоты, правильнее наверно говорить повышенной стабильности. Например погрешность-изменение от времени частоты обычного кварцевого генератора обычно это отклонение (неопределенность) в шестом знаке значения частоты, если посчитать что это значит например на 10МГц, это будет что-то в районе отклонения на минуты в сутки. Для RTC это отклонение не должно превышать какие-то милли секунды в сутки, это достигается в том числе за счет того что частота гораздо RTC ниже (медленнее). Это обычно принципиально разные генераторы.
Простое лучше, чем сложное. Стандартное лучше, чем необычное. Готовое лучше, чем костыли.
Если есть таймер с аппаратным захватом события и DMA - почему бы не сделать стандартно? И программно останется реагировать только на периодические переполнения таймера. И гарантированное время реакции будет, и запас по производительности при любой частоте событий.
Не нужно в пол-статьи оправдываться, как, зачем, и почему вы применили именно это решение. Было железо - применили, это круто. Будет железо с другими особенностями - будет другое решение. Хоть Padauk, хоть Миландр, хоть питание от CR2032 не 10 лет. Железо ведь тоже меняют не ангелы по воле Божьей, а такие же соседи-инженеры, и за немалую мзду.
Про "социальный конструкт" - ответив "да", я имел в виду не конкретную схемотехнику, а в принципе человеческую потребность в нашей работе. Потребность не сильно-то большая. "Нас нет" (с)
Не нужно в пол-статьи оправдываться, как, зачем, и почему вы применили именно это решение.
Обычно это делается быстрее и короче, например так: "я не применяю RTC для таймстампов потому, что RTC можно затактировать лишь от 32768 Гц. Который даст точность в 30мкс, а вдруг нам понадобится 1мкс".
Это простое, понятное, неправильное объяснений.
Правильное было бы: "я ни разу не использовал аппаратные таймстампы, предчувствую забег по граблям и потому лучше использую привычные мне приёмы". Но признаваться в таком неприятно :)
Признаюсь. Я ни разу не использовал аппаратные временные метки в таком виде. Не читал многие закоулки тех.описаний. Опыт интересный, да. Забег по граблям, если есть ТЗ на минимальный интервал между метками, я бы начал тестить с генератором сигналов. Так уж мы, железячники, устроены, наше всё - вовсе не JTAG-отладчик.
Статья крута, да, и полезна. Наверное, стоило начать с этой фразы, а я тут с ноги дверь вышибаю. Извините.
Но я не об этом. Я про нытьё во второй половине статьи, натянутое на какую-то философию. То, что технических решений может быть много, и они должны быть к месту (в том числе в 4-мерном пространстве-времени) - про это я полностью согласен. Я про то, что, наверное, не нужно при этом писать такое длинное оправдательное заявление.
Звучит просто как: "Ну да, совершил", "Был пьян, каюсь", "Больше такого не повторится". М.П. Подпись.
Статья крута, да, и полезна. Наверное, стоило начать с этой фразы, а я тут с ноги дверь вышибаю. Извините.
Технический аспект статьи лично я не считаю сильно полезным. Честно :)
технических решений может быть много, и они должны быть к месту
В том всё и дело. Периодически, технических решений много, но абсолютно каждое из них не к месту.
Уместно ли писать свой програмный "велосипед" при наличие аппаратной поддержки функционала? Ну, как бы, такое себе...
Уместно ли использовать аппаратный функционал, который представляет из себя стопку заплаток над порядком устаревшим легаси, при том, что сведения о функционале именно что находятся в "закоулках тех.описаний", куда почти никто не заглядывает? Уместно ли его использовать лишь потому, что он, типа, есть? Точно также - такое себе...
Это первый аспект.
Второй для вас, возможно, менее актуален, если вы фрилансер, лично выполняющий проект от и до.
Многие проекты выполняются в команде. В команде старший должен махнуть шашкой и сказать "Хорошего выбора нет. Будем делать криво, но единообразно. Из всех вариантов я авторитарно выбрал для нас кривой способ N2". На чём будет основан этот выбор? Короткое, понятное, (и неправильное) техническое обоснование подвести можно под что угодно. Но по сути, это будет не технический выбор.
"Ну да, совершил", "Был пьян, каюсь", "Больше такого не повторится"
Оправдываться у меня в планах не было :) Скорее, я хотел показать различные решения с различных сторон без шаблонного сюжетного приёма "а на самом деле правильно вот так".
Почти всегда есть какие-то объективные критерии выбора. Стоимость, переносимость, сложность, надёжность, покупаемость, какие-нибудь технические характеристики. И на их основе вполне можно сравнивать то, или иное решение.
Поскольку критериев может быть очень много, найти глобальный оптимум бывает сложно и дорого. И часто приходится просто остановиться хотя-бы на каком-то приемлемом варианте. Но по большому счёту нам за это и платят, чтобы мы подводили начальников к осознанному выбору.
Я точно также часто работаю, как часть команды, потому что в одиночку сделать что-нибудь серьёзное за приемлемые сроки очень сложно, и быть специалистом во всём сразу не получается.
скажите, а какое _практическое применение у вас для таймштампов с точностью 1мкс?. и осмелюсь напомнить про имеющийся в ядре арм счётчик тактов процессора. не помню, 32 или 64 бит он. для оценки времени исполнения кусков кода он прекрасно был использован
скажите, а какое _практическое применение у вас для таймштампов с точностью 1мкс?
Это вы можете спросить непосредственно у зилота вот здесь :)
арм счётчик тактов процессора. не помню, 32 или 64 бит
32 бита. И у Cortex-M0/0+ (STM32U0) он отсутствует, а у Cortex-M3/4 по нему нет прерываний - он именно для отладки. Хотя для своих целей - измерять время исполнения участков кода при отладке - он идеально подходит.
ну если вы делаете что-то серьезнее чем подергать ногами, например приемник спутникового радио, вам придется измерять миллисекундные тайм-ауты по прерываниям фреймов, например, и тогда не обойтись без таймеров с микро- или даже с нано-секундным разрешением. Считать годы, месяцы или даже недели с таким разрешением действительно вряд ли где то нужно.
Если вы делаете ПИД регулятор оборотов коллекторного двигателя, не говоря уже о асинхронных двигателях, тоже миллисекунды надо измерять, ...
Но вообще говоря много разных спец-приложений где нужно просто дергать ногами (генерировать фронты на пинах процессора-контроллера) с точностью долей микросекунд.
атомарные чтение и запись 16битных таймеров через 8битную шыну реализована через синхронный буферный регистр в ПИКах 100500 лет назад. неужели в стм32 этого нет?
атомарные чтение и запись 16битных таймеров через 8битную шыну
В STM32 16-битные таймеры читаются через 32-битную шину.

Электроника как социальный конструкт: микросекундные таймстампы на STM32