Комментарии 82
FreeRTOS, это только ядро (потоки и многозадачность), и программировать под нее мало чем отличается от программирования для bare metal. Те же обработчики прерываний, те же сторонние библиотеки и "если нужно задействовать модули WiFi, Bluetooth, протоколы вроде 1wire, I2C e.t.c. Требует полный спектр знаний в аппаратной части и электронике, в цифровой логике, во внутренней периферии микроконтроллера ...", а то, о чем вы пишите (ESP-IDF), это Espressif IoT Development Framework — Фреймворк разработки IoT (Интернет Вещей) только для платформы ESP32.
В данном случае FreeRTOS, это как ядро Linux в любом дистрибутиве, тогда как состав различных программ в каждом отдельном дистрибутиве может быть разным. Точно так же как и ядро для дистрибутива может быть заменено на какое нибудь другое (например на FreeBSD или на оборот, хоть это и не просто).
Поэтому когда вы пишите "Выбор и настройка компонентов FreeRTOS через 'idf.py menuconfig' ", то это неправильно. Это настраивается ESP-IDF и к FreeRTOS он не имеет никакого отношения (точнее FreeRTOS является одним из множества компонентов этого фреймворка, точно так же как и при настройке компонентов прошивки под STM32).
Чем отличается RTOS от обычной OS? Можно даже на примере. Взяли 3 одинаковых железки, на них запустили RTOS, Ubuntu, Windows и запустили одинаковую задачу. Windows запустила дефрагментатор реестра, а задачу отложила на потом, на Ubuntu была запущена другая программа, которая нагрузила процессор, и только на RTOS задача была решена за приемлемое время.
А то есть статья на эту тему на Хабре: RTOS или не RTOS вот в чем вопрос .
Тем что для выполнения любого (задачи / функции / действия) можно установить лимит по времени и если RTOS не успевает, то эта (задача / функция / действие) вываливается с ошибкой TIMEOUT. Реакцию на такое событие уже должен заложить программист, только вот часто не закладывают...
Здесь дело не в производительности а в гарантии того что тебе будет известно успела ли система все вовремя или нет.
Основное отличие FreeRTOS от линукса и винды в том что у винды минимальные требования к памяти измеряются в гигабайтах, у линукса в мегабайтах, у фриртос в килобайтах, так что это продукты из совсем разных категорий.
С практической стороны, всё что она гарантирует с точки зрения RT - то что каждую миллисекунду (можно реже, а вот чаще - фиг, если без хаков) будет вызвано прерывание и оно переключит исполнение на самую приоритетную из неспящих задач. Если на линуксе и винде отключить запуск пользовательских программ, то можно добиться примерно тех же гарантий, вполне есть реалтайм системы и на том и на том. Но реалтайм систему явно проще сделать (и проще сертифицировать) на фриртос где все задачи создаются в твоей программе, чем на винде, где какой-нибудь драйвер будет вызывать синий экран смерти а ты узнаешь об этом только во время эксплуатации.
фриртос на есп - просто библиотека классов, позволяющая манипулируя компактными очередями, семафорами и т.п. создавать задачи и в соответствии с их приоритетом передавать им по очереди управление каждую миллисекунду или с другим квантом. Т.е. это просто повышает удобство написания программы - сенсоры и актуаторы распихиваются по разным потокам и работают как бы не зависимо. Т.е. работа с одним устройством сосредоточена примерно в одном месте кода - проще искать косяки. Да, такое можно сделать и без фриртос. но с ним удобнее.
>чтобы любое действие было гарантированно обработано. На этом познания об этой системе у большинства айтишников заканчиваются
И чем это гарантируется))? В рамках какой концепции ОСРВ?) Познания айтишников..
минусуют...ну давайте разберём
These systems must provide absolute guarantees that a certain action will occur by a certain time.
Под action совсем не имеется ввиду гарантированная обработка действия. Action может быть и прекращение этой обработки, если она не может быть завершена в пределах заданного времени.
Есть пара замечаний
После прочтения данного текста, у "самых маленьких", на которых ориентирован материал, может возникнуть ложное впечатление, что это именно FreeRTOS обеспечивает простой доступ к периферии, но это не так. FreeRTOS лишь обеспечивает многозадачность и предоставляет элементы синхронизации, на этом ее функции исчерпываются. Упрощенный доступ к периферии предоставляют библиотеки среды esp-idf, не имеющие непосредственного отношения к FreeRTOS.
Не стоит забывать, что ESP32 не входит в число платформ, официально поддерживаемых FreeRTOS. Так что все претензии к стабильности работы должны предъявляться не к разработчикам RTOS, которая сама по себе является крайне надежной системой, а к разработчикам esp-idf, которые осуществляли портирование данной операционки на платформу ESP32.
ПС: пока писал комментарий, @rsashka уже написал примерно то же, что у меня в первом пункте, но более развернуто и с примерами.
Достаточно поверхностная статья, хоть и подразумевается "Для самых маленьких". Собственно, ничего не говорится о том, что же такое ОСРВ, какие есть типы систем реального времени (т.н. мягкое и жесткое реальное время), почему для МК стоит выбирать ОСРВ а не запихивать весь проект внутрь какого-нибудь while(1), и так далее.
Если касаться FreeRTOS, то стоило на мой взгляд, начать с перевода начала книги (Например главы 1.1.4 Why use an RTOS ?) Mastering the FreeRTOS Realtime Kernel. Книга доступна бесплатно.
Да и в целом, большинство ответов как, зачем и почему достаточно хорошо изложены в ней.
вообще говоря как минимум не для всякого МК стоит выбирать какую-либо ОС и даже РВ. Очень даже спокойно весть проект может быть запихнут в while(1); а все остальное жить в прерываниях
Все зависит от проекта в первую очередь. Что-то простое и небольшое, наверное да. Но в основном как только появляется необходимость использовать больше 3-5 интерфейсов - USB, Ethernet, много микросхем подключенных по SPI/SSP/что-то еще (Например, сразу 6 микросхем АЦП), возможно дисплей и др. - while(1) моментально упирается в потолок адекватной скорости внесения изменений, и главное, отладки временной диаграммы работы платы/прибора/устройства.
Ну и существует стандартная история - это когда человек пишет такой код в стиле while(1), потом понимает что всё, все глючит и не работает - увольняется (или его увольняют) т.к. более он не в состоянии понять, как довести работу до конца.
Наверно всё таки не совсем так - while это же разновидность планировщика, только не в ос, а в приложении. Если подходить с этой позиции то можно обойтись и им, правда второй вопрос будет - зачем так, если есть ос.
в ОСРВ у вас есть вытесняющая многозадачность с набором всевозможных примитивов синхронизации и т.п.
while(1) с прерываниями - будете либо много тратить время в обработчиках прерываний (а вложенность весьма конечна и быстро вход/выход работает только на архитектуре ARM), либо ждать пока исполнение в while(1) доберется до нужного места. Будете вносить изменения внутрь while(1) - без контроля у вас начнут разъезжаться обработчики интерфейсов, особенно много ошибок можно наделать в USB. И вам придется каждый раз тратить много усилий на контроль всего этого.
У вас там никаких гарантий по времени перехода скорее всего не будет. Ну либо будет, но цена затраченных усилий будет скорее всего не соответствовать итоговому решению.
Я видел реальную систему многоканальной обработки на 4ядерном процессоре, работающая с двумя eth интерфейсами, блоком разделяемой памяти и хост интерфейсом. По таймеру каждому каналу предоставлялось время на вызов последовательности функций обработки соотв буфера, в том числе из 3d party библиотеки. Управление через хост интерфейс и разделяемую память позволяло менять параметры обработки, обратно работал printf для логгирования. Модернизация сводилась к изменению -созданию функций, пока производительности хватало. Я там копался в паре мест -ни разу не сталкивался с проблемами в спланированных вычислениях, только табличку расширял для контроля загрузки
Система была реального времени, так как гарантировала время обработки данных, реакции на команду и загрузку системы. Другое дело, что она была не как её, интерактивная)
И была причина, почему там не было никакой ОС -лицензия стоила существенные деньги, существенно дороже, чем МонтаВиста, которая стояла на хосте, и где кроме rt_fifo ничего, вродебы, не использовалось.
Я никоим образом не пытаюсь принизить достоинств осрв, особенно для систем с мышкой и юзером, или если там ещё и полноценные приложения, но while до сих пор имеет право на жизнь, имхо
простое и небольшое, наверное да
или что-то непростое и быстрое
моментально упирается в потолок адекватной скорости внесения изменений,
скорее скорости написания/освоения... и тут вылазят библиотеки на все случаи жизни от андурины и тут после невидимого while(1) появляется loop().
Что-то непростое и быстрое прекрасно пишется и с использованием FreeRTOS.
Причем тут библиотеки не очень понятно. Никто вам их не запрещает использовать при таковой необходимости и с FreeRTOS - только могут быть нюансы в настройке софтверного таймера, если библиотека использует такое понятие для своей внутренней работы.
быстрее прерываний ничего не сделать. Использование оберток от FreeRTOS скорости не добавляет. (Это утверждение не в контексте ESP, если не очень понятно о чем речь)
только могут быть нюансы в настройке софтверного таймера,
В ардуиновских библиотеках могут быть где угодно нюансы, но в среднем они таки работают и много времени экономят
В Tesla Model S прошивки практически всех блоков написаны были в стиле while(1). Если где и была RTOS то чаще всего в ней создавали задачи типа task_1ms, task_10ms, task_100ms и в них уже в том же стили крутили логику.
Конечно не для всякого проекта это надо, но как только "вырастаем" до реального проекта с HTTP, WiFi, управлением периферией вроде моторов, то разбиение на таски ой как облегчает жизнь.
Да, так и не понятно почему не запихивать внутрь грамотного while?
В принципе, я бы сказал так - грамотный while это фактически прообраз (или очень приближенный) к ОСРВ код сам по себе.
Потому что вам все равно требуется некий системный таймер с прерыванием, чтобы контролировать то, что сейчас выполняет ядро МК - контроль за процессорным временем. Например, если вы не успеете обработать USB, из-за внесенных изменений в код - то он у вас отвалится. Потому что в это время МК будет занят чем-то другим, и без ОСРВ выйти из обработки у него не выйдет - только там в обработчике еще через n-времени проверять некий статус, надо ли вернуться куда-то там, т.к. нет программных приоритетов и нет вытесняющей многозадачности.
Либо/вместе с тем же код в остальных прерываниях начнет пухнуть из-за всяких проверок на что где заполнилось или не пришло/не отправилось, что отрицательно влияет на общую структуру программы в целом, не говоря уже об ограничениях вложенности и скорости входа/выхода в этих функциях в зависимости от архитектуры МК.
Отдельная категория проблем - это организация подобной программы с архитектурой while(1) для работы в различных режимах энергопотребления и переключения между ними. Тут я только могу пожелать удачи и хорошего настроения тому человеку, что все это будет отлаживать каждый раз после внесения изменений, на большом проекте в условиях командной работы, когда над проектом работает несколько и более программистов.
В целом, на эту тему можно развернуто написать довольно большой текст.
это супер старая проблема, в сложных случаях всегда старались разделить обработку прерывания на быструю и медленную часть, и делать отдельно, по возможности иметь несколько видов процессов - типа с быстрым переключением контекста, и с более медленным, комбинация while + switch напоминает переключение таких быстрых процессов, также часто используется для парсинга пакетов, например dpi,
про командную работу верно замечено, типа много лет приходилось наблюдать, со временем привыкаешь
А кто нибудь пробовал RIOT OS ? Это настоящая многозадачная операционная система для микроконтроллеров и простого железа.
LED на микроконтроллере ESP32 должен мигать
А возможно и не замигает потому что спалит порт. Никогда-никогда не подключайте светодиод к выходу без токоограничивающего резистора.
Можно использовать светодиод из светодиодной ленты - у него падение напряжения около 3В, питание процессора 3.3В, за счет минимальной разницы напряжений ток будет небольшим.
Ну, просто светодиодов можно феном кучу навыпаивать за пару минут, а проводной резистор, удобный для эксперимментов, не микроскопический SMD - еще найди сейчас в загашниках...
за счет минимальной разницы напряжений ток будет небольшим.
У него слишком крутая вольт-амперная характеристика на рабочем напряжении. И даже с таким минимальным разбросом нужно ставить соответствующий резистор. А еще лучше не ставить светодиоды с такой маленькой разницей между рабочим напряжением и напряжением падения светодиода.
Ну, можно считать что это такой лайфхак "не по правилам".
Оно работает. А вот красненьким ярким светодиодом спалить порт вполне можно
Ну, можно считать что это такой лайфхак "не по правилам".
По правилам китайской электроники если можно что-то сэкономить - значит нужно.
В "Искусстве схемотехники", ещё 1986 года издания, была фраза типа "если элемент повышает надежность, то он должен стоять в схеме". Но в последнее время часто вижу схемы где этим пренебрегают. Буквально конструкция выходного дня (в понедельник уже не работает, сгорела).
Абсолютно надежным считается устройство, которое проработает первые несколько минут после распаковки - столько, сколько нужно среднестатистическому покупателю условного алиэкспресса на то, чтобы подтвердить получение товара и поставить пять звезд продавцу. Это одновременно ответ и вам, и @kuzzdra на один камент выше. :)
Вообще у esp32 можно настраивать выходной ток, так что можно и без резистора..
PWM что-ли?
К слову, совсем незачем огорчаться, "если у вас только ESP8266". Для всяких полезных в хозяйстве вещей ее возможностей более чем достаточно, а там где недостаточно - уже можно и об одноплатнике из тв-бокса подумать
это сначала кажется, что ее возможностей достаточно. А потом выясняется, что памяти там кот наплакал
Да не только памяти. Аппаратных возможностей тоже маловато. И зачастую задумываешься о небольшой переплате за ESP32, где с аппаратными возможностями все гораздо лучше.
Для хоббийных проектов абсолютная разница в цене настолько ничтожна, что нет никаких разумных причин выбирать ESP8266 при наличии в свободном доступе любых ESP32, коих целая линейка на самом деле, даже если они многократно избыточны. Здесь избыточны, там уже не очень - а платы в коробке запасены для неизвестно чего и, вот, как раз понадобились. Ну, я так думаю. Для производства, где десятки центов, а то и единицы долларов на сотнях тысяч дают весьма ощутимые деньги, этот подход, конечно, неприменим.
Для производства, где десятки центов, а то и единицы долларов на сотнях тысяч дают весьма ощутимые деньги, этот подход, конечно, неприменим.
Ну, например ESP8266 можно легко заменить на ESP32-C3, который на копейки дороже, но имеет встроенные 4Мб флеш-памяти.
Не могу говорить за любое производство, потому что в каждом случае есть своя индивидуальная совокупность факторов и еще и субъективная оценка весов этих факторов. Например, кому-то покажется, что есть смысл переходить на ESP32-C3 из-за масштабируемости/унификации, когда по сути одна и та же прошивка используется на разных моделях похожих изделий - чтобы и памяти, и производительности было на вырост, пусть сейчас и не нужно, особенно при не слишком больших тиражах, когда цена разработки уже чувствуется в себестоимости, а не размазывается на сотни тысяч или миллионы изделий. На больших тиражах, уверен, многие производства будут смотреть на безумные с точки зрения хоббийщика решения вроде контроллеров с одноразовой записью, подобранные максимально в обрез по своим возможностям, потому что каждый цент на миллионе изделий - это довольно много.
Вы знаете, я в подобный аргумент перестал верить, обнаружив в одноразовой "дудке" контроллер "PY32F002AF15" (ARM-M0 с парой килобайт оперативки), который с прошлого года у меня на даче управляет автополивом (благо, и вход от "датчика давления" и выходы на два нагревателя у него штатно были распаяны, и площадки для перешивки были в наличии). Сейчас планирую всё снести к чертям и завести на нормальный комп, т.к. ковыряясь с HAL-подборками так и не понял, как нормально работать с периферией (датчики влажности и температуры), а для PC есть вполне высокоуровневые библиотеки, ну и внешние интерфейсы (LAN, WiFi...) более доступны.
Вы знаете, я в подобный аргумент перестал верить, обнаружив в одноразовой "дудке" контроллер "PY32F002AF15" (ARM-M0 с парой килобайт оперативки)
Во первых, я не могу настаивать на абсолютной применимости моего тезиса, потому что все частные случаи имеют какий-то бекграунд в том числе в виде опыта разработчиков с той или иной элементной базой. Во вторых, а какова цена PY32F002AF15 в крупном опте? Быть может, они вполне подходят под такую техническую характеристику как "как можно дешевле"?
Сейчас планирую всё снести к чертям и завести на нормальный комп, т.к. ковыряясь с HAL-подборками так и не понял, как нормально работать с периферией (датчики влажности и температуры), а для PC есть вполне высокоуровневые библиотеки, ну и внешние интерфейсы (LAN, WiFi...) более доступны.
А это опосредовано подтверждает другой мой тезис, что для разовых DIY проектов цена компонентов обычно имеет крайне малое значение - применить многократно избыточное аппаратное обеспечение, в вашем (да и моем, чего уж там) случае ради упрощения разработки - вполне оправдано, потому что хоббийные проекты скорее ограничены человеко-часами, которые можно на них выделить, а вовсе не стоимостью деталей, из которых проект собирается.
проще RPi Pico тогда использовать. Там уже все есть.
Без WiFi/BT или еще какой-то связи с внешним миром за те деньги - это что-то на расточительно-транжирском.
Для себя обнаружил, что использование списываемых ПК очень даже экономно (ну, если не считать электропотребление около 70 кВт-ч в месяц, что по текущему тарифу составит рублей 300), и с точки зрения разработки прототипов, и с точки зрения вложений "на старте".
Я про что и говорю в своих постах регулярно. Вокруг столько техники летит в мусорку, только успевай лопатой загребать. Причем, с ARM системами и по электричеству не будет перерасхода. Тяп-ляп и в продакшн:
https://habr.com/ru/companies/ruvds/articles/769942/
я конечно могу ошибаться но помоему под ESP32 (в отличии от 8266) в принципе невозможно писать не под freеrtos, даже если вы "типа не под freertos" на си пишете, исполняется это как задача в среде rtos.
Если не прав поправьте аргументированно.
На всех esp32 вы создаете проект только в составе idf (экосистема esp с freertos, готовыми дровами под периферию,)
Создать проект на несколько сот байт, который условно дергает gpio в цикле, невозможно. Как бы все open source, но примеров как завезти контроллер с нуля производитель не дает. Вы даже свой загрузчик сделать не можете, загрузчик вшит и закрыт. Может и есть какие то потуги сделать "обезжиренный" проект, но от энтузиастов и неясного качества
меня покоробило несколько шероховатостей во введении. вроде мелкие придирки, но люди такое читают, запоминают как неперерекаемую истину .....
Будем играть в "Угадай мелодию" или "Советский партизан на допросе у врага" ?
по разделу "начнем" может сложиться впечатление что какие то ОС "ставят" на микроконтроллер, очень упрощенное пояснение.
По разделу linux может сложиться впечатление что под linux еще проще будет помигать лампочкой, что уже не так. При этом не указано про сложности с реализации реального времени и зачем вообще тогда нужны эти rtos. кстати самые дешевые платы с linux есть чуть ли не дешевле 700 руб.
после чего начинающих добивают словом оверхед, прерывания, на самом деле еще и калбэки, а добиваем резко заклинанием idf.py menuconfig хотя idf мы еще не поставили. пожалуй уже не для самых маленьких.
дальше все довольно красиво, но кидает начинающего в командную строку. а есть между прочим express-ide, а там еще и отладчик и монитор встроенные. эти вещи не вот уж прямо про rtos но в esp все глубоко завязано, плюс всякие присущие тонкости, которые было бы полезно знать начинающим rtos ерам
Интересно было бы увидеть статью про elf-loader(espressif/elf_loader) под esp32
Хотелось бы понять сферу, где это может понадобиться с учётом того, что обычные Linux ELF бинарники не подходят от любой платформы и даже собранные под ESP32 не будут иметь практически ничего из привычных классических аттрибутов повседневной ОС: диска, драйверов, библиотек, API ядра и многого другого.
потому что это офигенно :) на самом деле можно построить свою ОС с подгружаемыми программами пользователя, чтобы не компилировать не всю прошивку а маленький elf. что то такое есть в flipper zero ив некоторых других системах. профит от этого сомнителен когда исполняемый код находиться только во флеш и очевиден когда грузиться в оперативку. но в esp32 да и в stm32 подход к этому довольно гибридный, так что профит не очевиден.
Присоединяюсь к комментариям выше про то, что FreeRTOS фактически планировщик с набором сервисов синхронизации. Также замечу, что есть порт для win/lin, может пригодится при осваивании или эмуляции.
На сколько помню порт основан на posix тредах. Причем после того, как фриртос попала в руки Амазон, они что-то сломали в этом порте. Не помню, что, но помню, что легко было исправить, больше было похоже на опечатку, может быть поправили уже.
Вот моя репа с зарисовками по запуску фриртос+cmake на компе, это форк другого проекта с моими мелкими испавлениями, может кому-то пригодится
Понадобилось в Ардуино распараллелить две задачи - использовал xTaskCreatePinnedToCore - результат так себе. Вроде бы процессы исполняются на разных ядрах, а взаимозависимость сохраняется и никакие настройки не позволяют получить два не влияюших друг на друга процесса (по задержкам и стабильности работы).
это наверное на esp32 тоже? там ядра крутят еще bt и wifi задачи, у меня и вообще вылеты пошли когда я ядра назначал, а отлаживать что и как в данном случае неудобно
Да, ESP32. Я ожидал, что если процессы выполняются на разных ядрах, то не будут влиять друг на друга.
В реальности если активен один процесс, то "заикается" другой. Настройки приоритетов и прочие не помогают.
И это разные ядра :) что у них там происходит на одном ядре даже проверять не хочу :)
В реальности если активен один процесс, то "заикается" другой.
А вы уверены, что задача запускается именно на другом ядре?
Не все ESP32 двухядерные.
xTaskCreatePinnedToCore может возвращать ошибку.
Используемый фреймворк может быть настроен на использование только одного ядра.
Да, сама модель ESP32 двухядерная и функции идентификации ядра для потока возвращают разные ядра.
Весьма странно. А не пробовали аналогичный код не через Arduino, а на чистом ESP-IDF, может проделки Arduino?
Чистый ESP-IDF будет, вероятно, в следующей жизни :)
На всякий случай, под "заиканиями" я понимаю джиттер потока данных на MOSI с частотой SPI 4 МГц. Возможно это так и должно быть на такой частоте, но SPI аппаратный и потоки на разных ядрах - вроде бы мешать друг другу не должны.
Может DMA попробовать использовать? Вот тут кой какие примеры есть: hideakitai/ESP32DMASPI: SPI library for ESP32 which use DMA buffer to send/receive transactions
Стоит посмотреть сколько процессов вообще крутится на ESP32 uxTaskGetNumberOfTasks. У меня 11 показывает в скетче осуществляющем только соединение Wi-Fi.
Всего 13. Видимо 11 стандартных, как у вас, и 2 моих, раскиданных по двум ядрам.
И что это нам даёт?
Одно ядро обслуживает динамическую LED матрицу, другое ядро - веб-сервер. Как только веб-сервер начинает выдавать страницы, матрица начинает мигать.
На какой частоте процессор при этом?
а матрица какая? я тут как раз недавно нашел библиотеку для матриц которая через dma работает
Это универсальная платформа, управляет любой иллюминацией. В частности, проверялось на LED Cube по SPI и на лентах WS2812 - результат один и тот же.
и на лентах WS2812
Надеюсь, для вывода данных на адресные светодиоды вы использовали RMT?
матрицы покрупнее используют интерфейсы HUB75, HUB10, HUB12
для них esp32 тянет простой ногодрыг, потом замарочались на dma, но более серьезные аппараты используют fpga
Ну это то понятно. Просто слышал, некоторые для вывода на адресные светодиоды используют SPI, да и тут частота примерно совпадает, вот и подумал. Но в случае ESP32 для адресных светодиодов гораздо эффективней использовать встроенный модуль RMT, хоть он и не для этого изначально создавался, но прекрасно справляется с этой работой сильно разгружая процессор.
FreeRTOS для самых маленьких на примере ESP-IDF