TechSavant & BootstrapJedi
TechSavant TechSavant
Привет, ты когда-нибудь пробовал подрубать датчики в режиме реального времени прямо на микроконтроллер с использованием JavaScript? Я вот думаю, как Espruino или JerryScript сравниваются с C++ по скорости работы и энергопотреблению. Хотелось бы узнать твое мнение о компромиссах, если у стартапа нет возможности заморачиваться с железом.
BootstrapJedi BootstrapJedi
Да, подключал ESP32 к Espruino раньше, и он на удивление шустрый. Задержка всего на пару микросекунд больше, чем у написанного от руки цикла на C++, но для большинства опросов датчиков все равно меньше миллисекунды – вполне достаточно для стартапа, который не хочет заморачиваться. JerryScript может быть ещё легче, если выкинуть из стандартной библиотеки только самое необходимое, тогда контроллер больше времени проводит в спящем режиме и экономит энергию. Но есть нюанс – сборщик мусора. Может будить микроконтроллер, если не соблюдать осторожность. Мой трюк в том, чтобы самую тяжёлую работу выносить в крошечную C-рутину, которая передаёт данные небольшому JS-циклу, который запускается только при срабатывании датчика. Так вы получаете нужный вам контроль, не привлекая полноценный фреймворк. Если не можете позволить себе переусложнение, сведите всё к абсолютному минимуму, минимизируйте выделение памяти и пусть кофе поддерживает вас бодрым.
TechSavant TechSavant
Отличный ход – объединить лаконичный C-core с небольшим JavaScript-обёрткой, чтобы держать сборщик мусора под контролем. Ты проводил тесты, чтобы понять, как часто он включается при пакетной обработке данных с датчиков? Даже один лишний аллокации может вытащить ESP32 из глубокого сна на несколько миллисекунд, а это ощутимо влияет на цикл работы, если он рассчитан на два часа. Интересно, рассматривал ли ты фиксацию буферов через `espruino.heap` или использование статического кольцевого буфера, чтобы JavaScript-код никогда не вызывал `malloc`. Кстати, способ пробуждения по прерываниям от датчиков – умное решение, но проверь тайминги ISR – любые колебания там могут сбить с толку цикл событий и превратить твою "маленькую JavaScript-петлю" в нервную пляску. Не прекращай варить кофе и следи за объёмом используемой памяти – не хочется, чтобы микроконтроллер бился за каждый килобайт, когда мог бы спокойно спать.
BootstrapJedi BootstrapJedi
Понял, я уже попробовал несколько вариантов с фиксацией памяти и статическими буферами. Сборщик мусора запускается только тогда, когда я реально выделяю новые объекты в цикле. Если все держать в заранее выдеренном кольцевом буфере и просто добавлять индексы, он не просыпается. Видел паузы сборщика мусора в 4 миллисекунды на ESP32, когда он все-таки запускается, но это происходит только если я достигаю порога сборки мусора за один раз. Стараюсь держать размер пакетов меньше 32, чтобы этого избежать. По поводу прерывания – оно максимально простое: устанавливаю флаг и выхожу. Главный цикл проверяет флаг и обрабатывает пакет. Замерял примерно 200 микросекунд на прерывание, так что пропусков почти нет. Если увеличишь частоту сенсора, добавь второе прерывание для фильтрации – и все будет хорошо. Короче говоря: фиксируй буфер, не выделяй память в прерывании и “голодай” сборщиком мусора, сбрасывая счетчик кучи после каждого пакета. Вот как получить спокойный МК, который при этом работает быстро, как JavaScript. Не забывай про кофе, следи за размером кода, и энергосбережение последует.
TechSavant TechSavant
Отлично! Только не забудь перепроверить тайминги сброса счетчика кучи — если сброс произойдет непосредственно перед вызовом ISR, может получиться выделение памяти посередине пакета и запустится еще одна сборка мусора. Следи за этим, и у тебя будет идеально спокойный и очень быстрый ESP32. Не прекращай пить кофе!
BootstrapJedi BootstrapJedi
Спасибо, подстроюсь под сроки и буду следить за счетчиком. Кофе – моя секретная фишка – никаких прожорливых фреймворков, только чистый JavaScript с небольшой примесью C. Следите за обновлениями, не забывайте про кофе.