Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Я хочу получать рассылки с лучшими постами за неделю
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
Создавая аккаунт, я соглашаюсь с правилами Пикабу и даю согласие на обработку персональных данных.
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam

Топ прошлой недели

  • Oskanov Oskanov 8 постов
  • alekseyJHL alekseyJHL 6 постов
  • XpyMy XpyMy 1 пост
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

Нажимая кнопку «Подписаться на рассылку», я соглашаюсь с Правилами Пикабу и даю согласие на обработку персональных данных.

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Новости Пикабу Помощь Кодекс Пикабу Реклама О компании
Команда Пикабу Награды Контакты О проекте Зал славы
Промокоды Скидки Работа Курсы Блоги
Купоны Biggeek Купоны AliExpress Купоны М.Видео Купоны YandexTravel Купоны Lamoda
Мобильное приложение

Avr

С этим тегом используют

Arduino Микроконтроллеры Электроника Своими руками Самоделки Программирование Все
63 поста сначала свежее
yh.853aaa
yh.853aaa
1 год назад
Умный дом

Assembler и C в рамках маломощных микроконтроллеров⁠⁠

У меня есть свой крупный проект по автоматизации, который можно применить для умного дома.

И есть линейка своих собственных исполнительных устройств, модулей, датчиков и т.п. реализованных на AVR(в основном это ATmega168).

При этом данная линейка - это хобби, ее я реализую для себя и вкладываю туда функционал нужный мне, и пишу соответственно на том, что нравится мне. А не Вам, и не ради моды.

Меня часто спрашивают, почему я пишу прошивки для AVR микроконтроллеров на ассемблере.

Часто слышу стереотипы - ассемблер никому не нужен, очень сложный, нет переносимости, большие трудозатраты. И даже такие, как - на нем никто не пишет и Вы не должны, в общем я кому-то, получается, что-то должен.

Первое и пожалуй главное - ничто не научит работать с периферией лучше, чем кодинг на ассемблере.

Я применяю МК по прямому назначению - работа с периферией, если мне потребуется рисовать UI или считать математику я буду смотреть в сторону SoC или вообще в сторону микрокомпьютеров типа всяческих PI, где буду использовать более подходящий высокоуровневый язык чем Си.

Кстати по этой причине мне не особо интересны STM микроконтроллеры.

Второе - ассемблер не сложный, он имеет всего несколько десятков команд, это сложно запомнить? Главная сложность в том, что на ассемблере программист многие алгоритмы составляет сам, чем и добивается существенной оптимизации. Т.е нужно уметь думать головой. И дело не в том, что компилятор что-то может или не может, дело в принципе в подходе к самому программированию. В Си вы не задумываясь воспользуетесь тяжелой функцией, вместо пары тройки команд на ассемблере.

Более того, у вас буквально ассемблер с несколькими десятками команд, чистая периферия МК и все, ничего лишнего. Вам не нужно знать третье звено - как работает компилятор! А в Си Вам придется с ним разбираться, если конечно вы не пишете студенческую работу и ограничены в ресурсах МК.

Третье, как вообще можно отлаживать даже программу на Си для МК, не зная ассемблера? Как можно написать оптимальный бутлоадер не зная ассемблера? Как посчитать такты в критических по времени местах? Как на 512 байт ОЗУ контролировать ресурсы(тот-же stack) в крупном проекте? Да никак, поэтому вы все на Си и на STM где больше ресурсов. Потому что тупо не можете. А я вот например могу на Cortex асме писать код для STM и периферию я их гораздо лучше понял взявшись за асм после Си.

Четвертое - трудозатратно. Не особо, возможно на багфиксинг утечек памяти на Си вы потратите не намного меньше времени, чем я на реализацию на асме. Здесь ключевое - наработки - сообщество Си наработало огромный пласт кода, и вы не задумываясь его используете считая свой код основными трудозатратами. При этом говоря про асм все почему-то думают о пустом листе, на котором все, все, все нужно писать с нуля. С чего бы? Переносимость? Об этом ниже. На асм можно точно также наработать(и это было ранее) все теже функции, что и вы используете в Си. Но нет, популяризация Си свела на нет наработки на асм.

Пятое - переносимость кода, да это главный минус в асм. Однако умение строить алгоритмы существенно снижает трудозатраты. Так же как и разделение кода на уровни. Я лично наработал операционку с кучей функций, я не пишу математику и другие процедуры с нуля, я их просто подключаю и вызываю также как это делаете вы в Си. Более того, мой код(особенно код верхнего уровня) без проблем переносится между МК семейства AVR. И потом, как вы вообще представляете перенос сложной программы на Си с AVR скажем на STM, да никак. Где ваша хваленая переносимость Си?

Если мне нужно что-то по быстрому накидать для периферии - я возьму микрокомпьютер и за минуты накидаю на Java то, на что вы потратите в несколкьо раз больше времени на Си.

Если мне нужна сложная логика - я не буду это делать на микроконтроллере, я возьму что-то типа SoC или опять же микрокопьютер.

Если мне нужна примитивная логика для работы с периферией да еще и с минимальными затратами, я возьму МК и накидаю быстро вызовы уже реализованных процедур на асме.

Я не вижу по большей части где и для чего использовать Си. Это просто мода.

Даже используя ESP я предпочту микро питон, а не все эти глючные библиотеки HAL написанные на си, хотя наверное вы привыкли и не замечаете какой откровенно плохой код вы используете.

А если мне нужно будет говнокодить, с целью быстренько что-то где-то копипастить и выдать за свое решение, срубить бабла по бытрому, тогда да, я возьму STM и буду писать на Си. Но мне такая работа не интересна.

Показать полностью
[моё] Arduino Си Assembler Avr Stm Инструменты Самоделки Холивар Длиннопост Текст
76
12
yh.853aaa
yh.853aaa
1 год назад

DIY. RS-485 мини реле на 10А⁠⁠

Это мое хобби.

Кроме крупного проекта по автоматизации(который можно применить для умного дома) я также занимаюсь проектированием линейки своих устройств.

Вот мое мини реле (не пугайтесь, ручная пайка, прототип):

1/4

RS-485 мини реле на 250В 10А (ручная пайка, прототип)

Характеристики прототипа:

1) Управление по шине RS485(две витых пары), поддержка до 128 устройств, допустимое расстояние - сотни метров(зависит от свойств кабеля).

2) Компактный протокол, среднестатистический запрос-ответ выполняется за 15-20 миллисекунд.

3) Уникальная идентификация каждого устройства.

4) Обнаружение всех устройств на шине в течении нескольких секунд.

5) Ведение истории устройством (записывается изменения показаний, рестарт устройства и команды реле с учетом источника команды).

6) Информирование Java контроллера о событиях(изменено состояние реле или показание температуры и прочее) в течении 30 миллисекунд

7) Поддержка порта расширения для датчика температуры(DS18B20) или датчика температуры и влажности(AM2301) или кнопки без фиксации для управления реле или выключатель(кнопку с фиксацией) (также, в будущем, планирую добавить таблетку DS1990A)

8) Возможность обновления прошивки без дополнительных манипуляций, функционалом можно воспользоваться прямо в клиенте.

9) Съем потребляемой мощности нагрузкой на базе тока(напряжение не учитывается, используется константа) *(доступно только для реле с датчиком тока)

10) Поддержка таймера с минимальным интервалом в 10 миллисекунд

11) Защита от частого переключения реле (максимальная частота - 2Гц)

12) Поддержка триггеров, позволяют управлять реле на базе условий по показаниям температуры, влажности, потребляемой мощности нагрузкой.

13) Возможность блокировать каналы управления реле (ручной, шина, таймер, триггер)

14) Размеры, не более, 20х20х35мм (можно разместить в стакане обычной розетки)

15) Потребление(при 5В) менее 20ма/80ма

16) Поддерживаемое напряжение 5-36В (постоянный ток)

17) Индикация: вкл/выкл реле(синий), опрос датчиков(зеленый), передача по шине(красный)

18) Опрос датчиков - каждые 5 сек, информирование Java контроллера при изменении состояния реле, dT>=1, dH>=3, dW>=200

19) Коммутируемый ток - характеристики реле: 10А(250V AC)

20) Трех контактная колодка: вход, НО, НЗ.

Практически все мои устройства реализованы на базе ATmega168, прошивка реализована полностью на ассемблере на базе операционной системы реального времени core5277(естественно с переносимстью кода, пока в рамках семейства AVR).

Протокол передачи данных проприетарный, собственной разработки, базируется на RS-485.

Прошивка проприетарная, но в принципе ничто не мешает залить свою.

P.S. Это устройство требовательно по току к шине, всетаки 80мА много. Гирлянду таких не подключишь, есть дугой вариант, немного дороже и чуть больше, но с питанеим реле от сети. Позже выложу. Есть и другие варианты исполнения.

P.P.S. планирую добваить поддержку Modbus своим устройствам, но будет ограничение по функционалу.

С этого момента я прекращаю отвечать на необоснованную критику. Считаю автоматически Вас за тролля и просто игнорирую. Причина тому несколько пользователей пытавшихся поднять свою самооценку выливая на меня ушат помоев. Спасибо.

Показать полностью 4
[моё] Электроника Умный дом Своими руками Arduino Avr Длиннопост
24
yh.853aaa
yh.853aaa
1 год назад
Умный дом

Продолжение поста «Альтернативный взгляд на 'умный дом'»⁠⁠1

Решил, на базе полученных комментариев, немного дополнить свой пост. Думаю это я проделаю много раз, если будет интерес у публики.

Не менее 90% моего проекта - это комплекс программного обеспечения(как минимум сервер, контроллер и клиент). Остальное - это по сути необязательные допы, типа линейки своих конечных устройств(датчики, устройства управления, модули, шлюзы и прочее).

Вот с программной частью и с дополнительными услугами коммерция вполне возможна.

Расскажу про те самые 10%

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

Я знаком с CAN, и все же RS-485(без Modbus) подходит лучше. Физика не отличается, отличаются протоколы. Я использую свой проприетарный протокол, который существенно более функциональнее Modbus. И он закрывает все необходимое для домашней автоматизации. Более того, я также разрабатывал в другом проекте аналогичное решение но с более богатым функционалом, например там устройства свободно могут общаться друг с другом без мастера, находясь на одной RS-485 шине. В данном проекте такое мне пока не нужно.

Ну и CAN требует больше финансовых затрат, драйвера дороже, документация закрыта, реализация значительно сложнее и прочие прелести.

STM вероятно сейчас дешевле чем AVR и точно функциональнее и богаче ресурсами. Но лично меня устраивает функционал и цена за МК(ATmega168) в пределах 80-100 рублей. Большего мне в конечных устройствах не нужно.

В моих железках не используется конкретно RTOS, у меня своя realtime OS написана полностью на ассемблере(существенная разница в размере потребления ресурсов). Да, конечно, размер прошивки в небольших программах заметно меньше для кода без ОС, особенно под конкретную задачу. Но если у Вас богатый функционал, то не важно Си это или ассемблер - у вас будут большие трудозатраты. Использование ОС эти трудозатраты существенно снижает. Здесь просто нужно смотреть на поставленную задачу. У меня богатый функционал, и использование ОС заметно более выгодно. Ну и разработка на ассемблере существенно оптимизирует размер прошивки и использование других реусрсов МК.

Теперь по поводу комментария, что у меня проект совсем не похож на умный дом.

Конечно у меня есть сценарии. На базе их контроллер(а не сервер) управляет всеми устройствами. Главное преимущество - большинство сценариев описываются в виде UI формы, там нет ни скриптов, ни конфигов, ни программирования. Хотя если будет действительно сложная задача - можно подключить Java код.

Кроме того для своей линейки у меня наработан почти полный функционал триггеров(пока не ввел в работу), т.е. устройства сами могут выполнять простейшую автоматизацию, в том числе и на базе показаний других устройств. Подобное я уже делал. И все это на ATmega168(в край 328).

Как уже сказал, сценарии выполняет контроллер. Он может быть установлен в квартире, может быть виртуальным в облаке. А может и не быть. Клиентская программ сама может взять на себя функционал контроллера, но в этом случае сценарии работают только тогда, когда работает клиент.

Для автоматизации сервер не нужен, он вообще не выполняет автоматизацию - у него другие задачи, типа агрегации данных, предоставление доступа пользователям, информирование и прочее.

Спасибо за внимание.

Насчет холивара Си и ассемблера я напишу отдельно. Можно будет устроить срачь, шучу.

UPD:

В моем посте завелись тараканы. Я их не вижу, но они гадят. Постоянно приходят сообщения как только кто-то из них нагадит.

Будьте осторожны, я не вижу этих тараканов и не знаю что оне там постят.

Показать полностью
[моё] Умный дом Интернет вещей Avr Технологии Arduino Электроника Изобретения Ответ на пост Текст
68
yh.853aaa
yh.853aaa
1 год назад
Умный дом

Альтернативный взгляд на 'умный дом'⁠⁠1

Я не копирайтер и никогда не практиковался в написании постов, я практикуюсь в разработке ПО(профессионально и давно) а также в схемотехнике(хобби). Здесь не будет красивого изложения.

К тому же я хочу донести общий смысл, а не заострять много внимания на деталях.

В общем я даже не буду пытаться соответствоать шаблону крутого спеца. Просто прошу обращать внимание не на мою личность, и форму подачи материала, а конкретно на вопросы о которых буду писать.

И да, у меня будут проскакивать различного рода ошибки, прошу прощения, а также прошу проходить мимо, если Вас это напрягает. Я здесь не для того, чтобы показать какой я умный и на сколько хорошо знаю правила Русского языка.

А пишу я этот пост, просто потому, что меня(в том числе и как портебителя) очень сильно напрягает положение дел касаемо домашней автоматизации. И я вижу альтернативное решение. Благо я волен сам выбирать как функционал ПО, так и оборудование на котором строю свое решение.

Приступим.

Я всегда стараюсь исходить из задачи. Задача - я хочу автоматизацию в квартире, гараже. А далее на даче, когда она у меня будет. Да и вообще где угодно, автоматизация везде полезна.

Конкретно, для квартиры я хочу следующее:

Вода: счетчики на горячую и холодную воду(т.е. автоматический съем с них показаний и либо передача в центр приема показаний или информирование мне). Проверка на протечку и перекрытие поступления воды от стояков. Съем температуры со стояка горячей воды. Съем показаний с теплосчетчика(если получится его использовать, в моем случае проблемы с нашими законами, а не техническая).

Климат: Датчики температуры, влажности, в каждом помещении(и С02 датчики в жилых помещениях). Управление запортной арматурой батарей отопления(для регулировки тепрературы в помещении). Управление вентиляцией.

Безопасность: Датчики открытия на каждое окно, входную дверь(и на некоторые двери внутри квартиры). Датчики дыма.

Электрика: Димирование ламп накаливания(я не сторонник светодиодного освещения), управление светом для остальных типов ламп(вкл/выкл). Управление(очень желательно) каждой розеткой в доме. Съем показаний с электросчетчика. Управление электрозамком на входной двери и еще в паре мест в квартире соленоидом.

Ну и прочее: Съем температуры в ларе(морозильник), метеостанция, счетчик гейгера и прочее, прочее, прочее. А вот еще - универсальный модуль в каждую жилую комнату, который сможет управять кондишкой, телевизором и прочим по ИК, сможет принимать команды по ИК от пульта, сможет работать ночником и прочее. А еще можно подружить WiFi точку доступа или клиента с сценариями для управления охранкой и открытием двери, домофоном и прочее.

В общем размах очень большой. При этом я не рассматриваю всякие системы типа умных чайников и прочая лабуда мне оно откровенно не нужно. Также как и всякого рода шпионы типа умных колонок с Алисой.

Главное, я могу написать софт сам, а еще мне интересны микроконтроллеры типа старых ATmega 8(AVR), которые несколько лет назад изучил очень детально(без Ардуино). И которые, во всяко случае были, намного дешевле остального на рынке. Я могу писать и на STM но я не любитель Си, я люблю ассемблер, а ассемблер у корексов мне не приятен.

Главный вопрос, в какую сумму мне все это встанет? Как мы видим, здесь только одних умных розеток будет несколько дестяков. В общей сложности всех устройств будет явно больше сотни.

Разумно ли в этом случае рассматривать беспроводные решения? Я считаю, что это совершенно не разумно. Вот причины:

1) Wi-Fi забит соседями, сам стандарт не рассчитан, чтоб на небольшом простанстве было такое количество устройств - проблемы со связью будут обеспечены.

2) Безопасность, любой радио интерфейс могут заглушить и вероятно прослушать, подменить. Т.е. датчики на окнах и дверях могу быть просто заглушены, и мы никогда не узнаем, что дверь открывали.

3) Питание. Автономное от батарей - значит через некоторый период придется менять ближе к сотни батарей. Не автономное - значит у вас в квартире будет около сотни импульсных блоков питания(чревато возгоранием и влиянием на здоровье)

4) Безопасность. Более того, насколько мне известно в России никому не интересны Российские разработки в данной отрасли, все просто покупают кастомизацию американских решений(типа Tuya), даже китайцы типа Midea. Все эти железки в вашем доме соединяются с зарубежными серверами тех стран, которые явно нам не дружественны. Технически вас могут слушать, воровать ваши личные данные(теже пароли введенные через беспроводную клавиатуру). И кто знает как они могут повлиять на ваши исполнительные устройства. Самое просто, что они могут сделать - это окирпичить весь ваш умный дом просто отказав от обслуживания.

5) Ну и такие мелочи как высокая цена, большие размеры устройства, электромагнитное излучение, высокочастотный слышимый шум.

* конечно, где-то что-то реализовано по уму и есть исключения, но общую картину я думаю описал достаточно верно.

И исходя из вышесказанного, плюс из того, что я могу сам создать устройства и софт, я конечно выбрал свой велосипед.

Решение представляет собой сервер, контроллер(оптимально ставить один контроллер на одну локациию, например квартиру), клиент и конечные устройства(датчики, устройства управления, модули, шлюзы и прочее).

Я использую проводное решение. Смотрим RS-485. Устройства вашаются параллельно, шина. Достаочно одного кабеля. Т.е. одна шина(две витых пары, подойдет сетевой компьютерный кабель Ethernet). Желательно поставить шлюз с гальванической развязкой и отдельным питанием на каждое большое помещение. И да, главная сложность провести эту шину до всех устройств. Я, в основном, использовал плинтуса. Буду делать ременот - уберу все в стены. Также как и компьютерную сеть.

Занимаюсь я этим чуть более 5 лет. Довольно редко, ведь это хобби. Какие-то устройства ставлю, какие-то снимаю. И я подустал, многое снял(снял старые малофункциональные версии, а новые многофункциональные - пока просто не дошли руки). Установка и съем никак не повлияли на стандартную электрику! Сейчас у меня около 10 умных розеток, управляемое освещение во всех комнатах, несколько датчиков дверей, своя охранка, несколько датчиков температуры. Есть очень много различных наработок, что-то даже спаяно и это просто нужно подключить. Например в ближайшее время я буду менять 4 счетчика воды. Уже лежат для замены(с импульсными выходами). Платы модулей для них начерчены, надо заказать печать PCB, паяю пока сам. ПО написать - пара, тройка вечеров, так как много универсального кода уже написано.

И главное, поштучное изготовление устройства(это очень важно, так как массовое значительнр снижает цену единицы) для меня выходит где-то 150-500 рублей. Т.е. я могу обвешать всю квартиру датчиками и срденяя цена за каждый будет 200 рублей(можно и дешевле, если делать устройство под конкретную задачу). Умная розетка чуть дороже, где-то 300-400 рублей.

При этом, как говорил ранее, я профессиональный системный программист. Функционал в устройствах достаточно широкий. К примеру, что первое в голову пришло: обнаружение устройств на шине, обновление прошивки, история событий, сенсорное, клавишное, кнопочное управление(обычный выключатель), порт расширения, датчики тока и прочее.

А про программную часть(сервер, контроллер клиент) я даже и говорить не буду. Функционал очень богатый и закрыты многие технические вопросы, о которых такие как ксиаоми скорее всего даже и не задумывались.

Конечно есть области в которые я не добрался, что-то реализовано поверхностно, что-то содержит не критические баги. Клиент вообще без дизайна.

А гараж, в гараже было решение, временно снял. Доработал модули, но не доходят руки дописать и доделать некоторые вещи(например модуль бесперебойного питания и модуль радиоинтерфейса на базе LoRaWAN). По большей части потому, что там сейчас охранять нечего.

И ведь это не законченное решение, так как по большей части им пользуется только моя семья. И никто больше. Почему? Потому что:

1) Я не копирайтер, я не могу подать материал так, чтобы в нем кого-то заинтересовать в мире заваленном кучей беспроводных устройств с сильной реклаой

2) Я не дизайнер и не могу его отточить для удобоваримого восприятия конечным пользователем.

3) У меня скудная документация и скудная поддержка сторонних стройств(да, мой проект может и будет поддерживать сторонние устройства)

4) Ну и пожалуй главное - у меня нет капитала, который я был бы готов вложить в серьзеное развитие этого проекта. Достаточно того, что я вложил кучу своего опыта и личного времени.

В итоге, что я мог бы предложить в сравненнии с современными решениями:

1) Бесплатное ПО(с минимальными ограничениями) в виде AS-IS(кроме сервера). При этом весь код написан на Java - любой знающий может проверить решение на вредоносный функционал. А клиентская часть реализована на GluonHQ, что позволяет практически один и тот-же Java код запускать почти везде.

2) Возможность ввести в систему любое не проприетарное устройство. В том числе и беспроводные шлюзы и устрйоства.

3) Исполнение контроллера на широком списке различных устройств(почти все где можно запустить Java SE8

4) Информирование и различные точки управления типа Telegram, Алиса, СМС и прочее

5) Свой набор конечных устройств с проприетарным ПО

6) Рабочую систему даже без сервера и контроллера(но с ограничениями в функционале естественно)

7) Открытый основной код конечных устройств - операционная система реального времени для AVR на ассемблере.

8) Полностью Российское решение, за исключением некоторых открытых библиотек и JRE

9) Конечно-же богатый функционал типа сценариев, скриптов и т.п.

10) И важно, не нужно никакого умения и знаний в программировании или в написании конфигураций. Нужно просто понимать, что за устройство у вас в руках, как оно работает и как подключается. Но, никто вам не запрещает создавать свои устройства со своей прошивкой. Также в проект заложена возможность писать сценарии на Java.

Да, получилось сумбурно, знаю, но я даже не представляю как весь свой труд проделанный в течении многих лет описать в один пост. Это просто не возможно.

Но я думаю этого пока хватит.

И главное. Я ни на что не расчитываю, просто хотел показать как оно, по другому, бывает.

P.S. Опыт мне подсказывает, что огребу я здесь по полной, от простых троллей у которых нет ни знаний, ни понимания, максимум шалоны. Модератор, готовсь :) Что-ж посмотрим.

Показать полностью
[моё] Умный дом Интернет вещей Avr Технологии Arduino Электроника Изобретения Длиннопост Текст
18
128
monobogdan
monobogdan
1 год назад
TECHNO BROTHER

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI?⁠⁠

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

Зачастую в процессе разработки собственных устройств или моддинга уже существующих, встаёт задача выполнения стороннего кода: будь то ваши собственные программы с SD-флэшек, или программы, написанные другими пользователями с помощью SDK для вашего устройства. Тема компиляторов и кодогенерации достаточно сложная: чтобы просто загрузить ELF или EXE (PE) программу, вам нужно досконально разбираться в особенностях вашей архитектуры: что такое ABI, релокации, GOT, отличие -fPIE от -fPIC, как писать скрипты для ld и т. п. Недавно я копал SDK для первых версий Symbian и основываясь на решениях из этой ОС понял, каким образом можно сделать крайне «дешевую» загрузку любого нативного кода практически на любом микроконтроллере, совершенно не вникая в особенности кодогенерации под неё! Сегодня мы с вами: узнаем, что происходит в процессе загрузки программы ядром Linux, рассмотрим концепцию, предложенную Symbian Foundation и реализуем её на практике для относительно малоизвестной архитектуры — XTensa (хотя она используется в ESP32, детали её реализации «под капотом» для многих остаются загадкой). Интересно? Тогда добро пожаловать под кат!

❯ Как это работает?


Думаю, для многих моих читателей реализация процесса загрузки exe-программ и dll-библиотек в память процесса оставалась эдаким чёрным ящиком, в детали реализации которого вдаваться не нужно. Отчасти это так и есть: современные ОС разруливают процесс загрузки бинарников в память сами, не требуя от программиста вообще ничего, даже понимания того, куда будет загружена его библиотека или программа.

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост




Давайте для общего понимания вкратце разберемся, как происходит загрузка программ в Windows/Linux:

1. Система создаёт процесс и загружает в память программы секции из ELF/PE. Обычные программы для своей работы используют 3 секции: .text (код), .data (не-инициализированный сегмент памяти для глобальных переменных), .bss (сегмент памяти для инициализированных переменных). Каждому процессу выделяется собственное адресное пространство, называемое виртуальной памятью, которое не позволяет программе испортить память ядра, а также позволяет не зависеть от разметки физической памяти на выполняющей машине. Концепцию виртуальной памяти реализует специальной модуль в процессоре, называемый MMU.

2. Если бы наши программы не использовали никаких зависимостей в виде динамических библиотек, то на этом процесс загрузки можно было бы закончить: каждая программа имеет свой адрес загрузки, относительно которого линкер строит связи между обращениями к коду/данным программы. Фактически, для самых простых программ линкеру остаётся лишь прибавить адрес загрузки программы (например, 0x100) к каждому абсолютному обращению к памяти.
Однако современные программы используют десятки библиотек и для всех предусмотреть собственный адрес загрузки не получится: кто-то где-то всё равно будет пересекаться и вероятно, портить память. Кроме того, современные стандарты безопасности в Linux рекомендуют использовать позиционно-независимый код, дабы использовать преимущества ASLR (Address Space Layout Randomization, или простыми словами возможность загрузить программу в случайное место в памяти, дабы некоторые уязвимости, завязанные на фиксированном адресе загрузки программы перестали работать).

3. Поэтому для решения этой проблемы придуман т. н. динамический линкер, который уже на этапе загрузки программы или библиотеки патчит программу так, чтобы её можно было загрузить в любой участок памяти. Для этого используются данные, полученные от обычного линкера а этапе компиляции программы: помимо .text, .data и .bss, линкер создаёт секции .rel и .rel-plt, которые называются релокациями. Если объяснять совсем условно, то релокации — это просто запись вида «какой абсолютный адрес в коде программы нужно пропатчить» -> «на какое смещение его пропатчить». Самая простая релокация выглядит вот так:

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

Где по итогу:

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

.rel-plt же служит для резолвинга вызовов к dll/so: изначально программа ссылается на заранее определенные в процессе компиляции символы, которые уже в процессе загрузки патчатся на физические адреса функций из загруженной библиотеки.

И казалось бы — всё очень просто, пока в дело не вступают GOT (Global Offset Table — глобальная таблица смещений) и особенности реализации конкретного ABI. И ладно бы x86 или ARM, там всё разжевано и понятно, однако на других архитектурах начинаются проблемы и не всегда очевидно что и где за что отвечает.

А ведь чаще всего нужно просто загрузить небольшую программу, которой не нужны комплексные загрузчики: немного кода, немного данных и всё. И тут у нас есть три выхода:

  1. Писать полноценный загрузчик ELF-бинарников. ELF может оказаться громоздким для некоторых окружений и его реализация может оказаться тривиальной не для всех.

  2. Зарезервировать определенный сегмент в памяти (пусть с 0xFFF по 0xFFFF) и скомпилировать нашу программу с адресом загрузки 0xFFF с параметром -fno-pic. В таком случае, линкер сгенерирует обращения к памяти по абсолютным адресам — если переменная лежит по адресу 0xFFF, то программа будет обращаться сразу к этому адресу памяти, без необходимости что либо динамически линковать. Именно такой подход использовался во времена ZX Spectrum, Commodore 64 и MS-DOS (однако там роль «виртуальной памяти» выполняла такая особенность 8086, как сегменты). У такого подхода есть и минусы: относительная невозможность загрузки сразу нескольких программ одновременно, зарезервированное пространство линейно отъест небольшой кусок памяти у основной прошивки, нет возможности динамической аллокации секций. Зато такой код теоретически будет работать быстрее, чем PIC.

    Проблемы реализации такого способа: иногда нужно лезть в систему сборки основной прошивки и патчить скрипт линкера так, чтобы он не трогал определенный регион памяти. В случае esp32, например, это требует патча в сам SDK и возможного «откола» от мейнлайн дистрибутива.

  3. Использовать программу с относительной адресацией, однако без сегментов .bss и .data. Самый простой в реализации способ, который к тому же очень экономичен к памяти, позволяет загружать программу в любое место и пользоваться всеми фишками динамического аллокатора и не требует вмешательств в основную прошивку, кроме примитивного загрузчика программ. Именно его я и предлагаю рассмотреть подробнее.


Недавно мы сидели в чате ELF-сцены (разработка нативных программ под телефоны Siemens, Sony Ericsson, Motorola и LG с помощью хаков) и думали, как же можно реализовать загрузчик сторонних программ на практически неизвестных платформах. Кто-то предлагал взять ELF под основу — однако с его реализацией под некоторые платформы есть трудности, а кто-то предлагал писать «бинлоадер» — самопальный формат бинарников, который получается из, например, тех же эльфов.

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

В это же время я копал SDK для Symbian и хорошо помнил, что в прикладных приложениях для этой ОС нет поддержки глобальных переменных вообще. Да, сегмент .data и .bss полностью отсутствует — переменные предлагается хранить в структурах. Почему так сделано? Всё дело в том, что каждая программа в Symbian — это dll-библиотека, которую загружает EKA и создаёт экземпляр CApaApplication. И дабы была возможность загрузить dll один раз для всех программ (что справедливо для системных библиотек), ребята полностью выкинули возможность использования любых глобальных переменных. А ведь идея интересная!

Однако в таком подходе есть несколько серьезных ограничений:

  • Отсутствие глобальных переменных может стать проблемой при портированиии уже существующего софта, хотя вашим программам ничего не мешает передавать в каждую функцию структуру с глобальным стейтом, который можно при необходимости изменять. Кроме того, нет ограничений на использование C++ (за исключением необходимости ручной реализации new/delete и отсутствием исключений).

  • Отсутствие преинициализированных данных. Вот это уже может стать относительно серьёзной проблемой, у которой, тем не менее, есть свои обходные решения. Например если вы храните команды для инициализации дисплея в таблице, или какие-либо калибровочные данные — вы не сможете их объявить, просто используя инициализаторы в C. Тоже самое касается и строковых литерал. Тут есть два варианта: часть таблиц можно вынести на стек (если эти самые таблицы достаточно маленькие), либо подгружать необходимые данные из бинарника с помощью основной прошивки (например, LoadString и т. п.).


Давайте же на практике посмотрим, имеет ли право на жизнь такой подход!

❯ Практическая реализация


Формат нашего бинарника будет до безобразия прост: небольшой заголовок в начале файла и просто сырой дамп сегмента .text, который можно экспортировать из полученного elf даже без необходимости писать скрипт для линкера. При этом нужно учесть, что ESP32 — это микроконтроллер частично Гарвардской архитектуры, т. е. шина данных и кода у него расположены отдельно. Однако у чипа есть полноценный MMU, который позволяет маппить регионы физической памяти в виртуальную память, чем мы и воспользуемся в итоге!

Заголовок нашего бинарника будет выглядеть вот так:

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

Программа общается с основной прошивкой посредством псевдо-syscall'ов: функции, которая в качестве первого аргумента ожидает номер нужной службы и один 32х-битный указатель для описания структуры с параметрами. Реализация syscall'ов — одна из самых простых и неприхотливых с точки зрения обратной совместимости с будущими прошивками.

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

Концептуально всё очень просто: GetGlobalStateSize сообщает нашему загрузчику размер структуры для хранения глобального стейта, в то время как Start уже фактически заменяет main() в нашей программе. Необходимости в crt0 нет, поскольку весь необходимый инит выполняет бутлоадер ESP32. Впрочем, при желании вы можете выделить отдельный стек для вашей программы — это повысит надежность, если выполняемая программа удумает испортить стек.

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

Собираем нашу программу:

xtensa-esp32-elf-cc.exe test.c -fno-pic -nostdlib -nostartfiles -Wl,--section-start=.text=0x0

xtensa-esp32-elf-objcopy.exe --only-section=.text --output-target binary a.out run.bin

-fno-pic отключает генерацию кода, зависимого от GOT, -nostdlib и -nostartfiles убирает из билда crt0 и stdlib, благодаря чему мы получаем только необходимый код. --section-start задает смещение для загрузки секции .text на 0x0 (в идеале это делать необходимо из скрипта для ld).
objcopy скопирует из полученного ELF только необходимую нам секцию .text.

Как же это работает на практике? Давайте дизассемблируем выходной бинарник и посмотрим, что у нас дает на выхлопе cc:

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

Обратите внимание, что Start вызывает подфункции с помощью инструкции CALLX8, которая в отличии от обычного Immediate-версии CALL8, выполняет переход относительно текущего адреса в PC, благодаря чему переход полностью независим от адреса загрузки программы в памяти. А благодаря тому, что все данные, в том числе и указатель на глобальный стейт передаются через стек, нет необходимости релокейтить сегменты данных.

По итогу всё, что нужно от загрузчика бинарников — это загрузить программу в память для инструкций, выделить память для структуры с стейтом программы и передать управление Start. Всё!
Конкретно в случае ESP32, у нас есть два возможных решения задачи загрузки программы в память:

  1. Загрузить программу в IRAM. Такая возможность теоретически есть, однако на практике загрузчик ESP32 устанавливает права только на чтение и выполнение на данный регион памяти. Попытка что-то скопировать туда закончится исключением SIGSEGV. Кроме того, сегмент IRAM относительно небольшой — всего около 200Кб.

  2. Самопрограммирование. Для этого, в esp32 есть два механизма — Partition API и SPI Flash API. Я выбрал Partition API для простоты реализации.


Для нашей прошивки необходимо будет переразметить флэш-память. Для этого запускаем idf.py menuconfig, идём в Partition Table -> Custom partition table CSV. Создаём в папке проекта partitions.csv, куда пишем:

# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M,
executable, data, undefined, 0x110000, 0x10000

Для заливки программы можно использовать соответствующее Partition API, либо parttool.py:

parttool.py --port "COM41" write_partition --partition-name=executable --input "run.bin"

Переходим к загрузчику программы:

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

Прошиваем ESP32:

idf.py build

idf.py flash

idf.py monitor

И смотрим результат:

SysCall 25

SysCall 35

SysCall 15

Всё работает!

❯ Заключение


Как видите, ничего сложного в выполнении сторонних программ при условии соблюдении некоторых ограничений нет. Да, в таком подходе есть как серьезные плюсы, так и минусы, однако он делает своё дело и позволяет реализовать запуск игр на кастомных игровых консолях, или сторонних программ на самодельных компьютерах. Ну и конечно же не стоит забывать про плагины! Авось в вашем решении нужна возможность расширения функционала устройства, однако предоставлять исходный код или даже объектные файлы нет возможности — тогда вам может пригодится и такая методика.

Пожалуй, стоит упомянуть ещё один… очень своеобразный метод, который я иногда встречаю при реализации самодельных компьютеров. Люди пишут… эмуляторы 6502/Z80 :)
И если такой подход ещё +- применим к ESP32, то в AVR просадки производительности будут слишком серьезными. Так зачем, если можно использовать все возможности ядра на максимум?

Полезный материал?
Всего голосов:
Приходилось ли загружать сторонний код в ваших устройствах?
Всего голосов:
Показать полностью 9 2
[моё] Опрос Гаджеты Программирование C++ Avr Arduino Esp32 Embedded Своими руками Самоделки Esp8266 Assembler Железо Микроконтроллеры Длиннопост
12
7
Аноним
Аноним
1 год назад

Блок AVR для генератора HAMMER flex gn6000t⁠⁠

Дорогие Пикабушники, решил обратиться за помощью, может кто знает, может кто владеет этим чудогенератором, благодаря нерадивому мастеру не могу найти оригинальный блок AVR,не найти от слова совсем, мне бы хотябы фото, там мудрено по подключению 8 проводов 3 клеммы. Очень надеюсь на Силу Пикабу)))) может и мне повезет

[моё] Сила Пикабу Помощь Благодарность Электричество Генератор Avr Текст
0
11
user4242
2 года назад
Лига Радиолюбителей

Конструктор для AVR с программатором⁠⁠

Всем привет!

В университетское время занимался микроэлектроникой и программированием на AVR. Сейчас появилось время и желание вернуться к данному увлечению, только вот незадача: не могу найти подходящий стартовый набор. Ардуино, конечно, классная вещь, но не вижу практического смысла брать набор под нее, если в финале все равно буду паять все на одной плате.

Посоветуйте, пожалуйста, хороший конструктор с макеткой и программатором, ну или объясните в чём я не прав)

Avr Макетная плата Конструктор Радиолюбители Самоделки Микроэлектроника Электроника Arduino Текст
39
572
DELETED
2 года назад
TECHNO BROTHER
Серия Делаем автоматику

Пишем софт для посудомойки ч.4. Смотрим результаты. Испытания "минимально жизнеспособного продукта"⁠⁠

Всем привет. Прошло уже около 2 месяцев с тех пор, как я занялся этим проектом и выложил по этой теме первый пост. Собственно, в последнее время разработка чуточку затормозилась, т.к. внезапно во время занятий спортом ощутимо повредил ногу, а затем занимался её лечением. Но речь не об этом. Уже можно воскликнуть: "Ура! Машина работает!". В общем, учитывая все предыдущие этапы, программу удалось довести до какого-то "рабочего" варианта (хотя назвать это даже альфа-версией язык не повернётся), который позволяет, тем не менее, проводить тестовые мойки и даже эксплуатировать машину по назначению. Итак, по порядку:
1. Прописал состояния программы.

Пишем софт для посудомойки ч.4. Смотрим результаты. Испытания "минимально жизнеспособного продукта" Электроника, Техника, Avr, Автоматика, Длиннопост, Посудомоечная машина, Самоделки

Пришлось немного отступить от задуманной ранее полуторачасовой программы. На текущий момент реализована программа мойки "экспресс": сразу идёт мойка горячей водой в течение 20 минут, а затем одно ополаскивание. Время мойки при этом составляет около 30 минут. Количество воды на программу: 6 литров. Электроэнергия: примерно 0,5 кВт*ч (зимой, возможно, будет больше). Для моих нужд этих процедур достаточно.

2. Постепенно начал переносить плату из прототипа в рабочий вариант.
В моём случае это заключается в том, что макетные DuPont провода постепенно заменяются на МГТФ, припаянные в соответствующих местах к родному модулю. На данный момент процесс завершен частично.

Пишем софт для посудомойки ч.4. Смотрим результаты. Испытания "минимально жизнеспособного продукта" Электроника, Техника, Avr, Автоматика, Длиннопост, Посудомоечная машина, Самоделки

3. Провёл десяток тестовых моек
На данный момент провёл определенные тестовые мойки, в результате которых были найдены некоторые баги в прошивке, которые, однако, пока не исправил. Например, иногда программа может зависнуть в момент запуска двигателя. Вызывается это, судя по всему, помехой от двигателя. Попытка установить доп. конденсаторы на данный момент ничего не дала, варианты решения прорабатываются. Тем не менее, керамическая посуда вымыта достаточно качественно, не докопаешься:

Пишем софт для посудомойки ч.4. Смотрим результаты. Испытания "минимально жизнеспособного продукта" Электроника, Техника, Avr, Автоматика, Длиннопост, Посудомоечная машина, Самоделки

Готовая принципиальная схема прибора (чукча не рисователь схем, так, набросано на скорую руку):

Пишем софт для посудомойки ч.4. Смотрим результаты. Испытания "минимально жизнеспособного продукта" Электроника, Техника, Avr, Автоматика, Длиннопост, Посудомоечная машина, Самоделки

4. Исходный код
В первом посте обещал выложить исходный код.. Конечно, в таком варианте, как сейчас, его применение сильно ограничено - багов там целый вагон, да и настроить сможет только специалист. Тем не менее, выкладываю пока так:
https://github.com/ritsudo/DishWasher328
Если у кого-то есть желание, можете его доработать до вменяемого вида. Я тоже попытаюсь это сделать, но не уверен, что у меня хватит времени, т.к. другие проекты тоже требуют внимания.

На этом всё, спасибо всем, кто следил за веткой, на всякий случай прикладываю также список всех предыдущих частей:
Часть 1. Изучаем устройство машинки
Часть 2. Создаем проект
Часть 3.1. Работаем с расходомером.
Часть 3.2. Работаем с ТЭНом.

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

С вами был Kekovsky.

Показать полностью 4
[моё] Электроника Техника Avr Автоматика Длиннопост Посудомоечная машина Самоделки
47
Посты не найдены
О Нас
О Пикабу
Контакты
Реклама
Сообщить об ошибке
Сообщить о нарушении законодательства
Отзывы и предложения
Новости Пикабу
RSS
Информация
Помощь
Кодекс Пикабу
Награды
Команда Пикабу
Бан-лист
Конфиденциальность
Правила соцсети
О рекомендациях
Наши проекты
Блоги
Работа
Промокоды
Игры
Скидки
Курсы
Зал славы
Mobile
Мобильное приложение
Партнёры
Промокоды Biggeek
Промокоды Маркет Деливери
Промокоды Яндекс Путешествия
Промокоды М.Видео
Промокоды в Ленте Онлайн
Промокоды Тефаль
Промокоды Сбермаркет
Промокоды Спортмастер
Постила
Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии