Как стать автором
Обновить

Комментарии 74

Прям душу травите)

Когда же уже мне его отправят.

До этого хотелось купить потому что "ну клёво же", а теперь еще и siemens-like интерфейс накрыл ностальгией. Уговорили)

легко может быть такая ситуация, когда забыли освободить что-то вы сейчас, а упадет другое приложение потом.
Разработчики flipper'а что-то про MPU говорили, или ни как от этого не защитится?

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

Почему бы не освободить это автоматически при закрытии приложения?

Оверхед на трекинг ресурсов будет равен бесконечности. В больших ОС для этого есть интерфейс сисколов и MMU, у нас ничего.

Так MPU у Вас всё таки используется или нет? Если да, то для чего?

MPU используется для защиты 0x0 от записи.

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

И получится микроядро.

Вы представляете себе какая потребуется сложность аллокатора и оверхед чтобы заставить это работать в реальности? Какой будет сложность взаимодействия между тасками?

Даже основной код прошивки не поместится после этого в память.

Это не я придумал. Вот выдержка из мануала по Cortex M4:
If a program accesses a memory location that is prohibited by the MPU, the processor generates a memory management fault. This causes a fault exception, and might cause termination of the process in an OS environment.
In an OS environment, the kernel can update the MPU region setting dynamically based on the process to be executed. Typically, an embedded OS uses the MPU for memory protection.

Так как вы пользуетесь FreeRTOS, то вынуждены терпеть все её недостатки, которые компенсируются её «универсальностью» ко всем архитектурам, позволяющей лишь видеть знакомые названия API при программировании разных контроллеров. Если хотите чтобы ОС была полноценной, то она должна быть написана конкретно под Cortex M.

Напишите как долно быть и сделайте пул реквест.

У меня нету Flipper'а чтобы его проверить.
НЛО прилетело и опубликовало эту надпись здесь
Раздали бы энтузиастам, уже бы и прошивка давно была готова и дружное комьюнити сразу же образовалось.
Вы «мифический человеко-месяц» читали? :)
Не согласен. Новые программисты, если грамотно ими воспользоваться (тем более бесплатные), помогут тестированию, либо образуют альтернативные версии ПО. А какая разница если будет продаваться?
Не читали. А «как пасти котов»?
Нельзя даже просто залить разработку деньгами и набрать программеров, это не работает. А вы предлагаете сделать тоже самое, но без денег?

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

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

Новые опенсорсные программисты — это люди, пришедшие сюда ради интереса (я много писал об этом вот тут: Как Unix-way убивает десктопный Linux). Они не работают за зарплату, им нельзя поставить KPI, их нельзя вызвать на разговор и сказать «ты сделал плохо, переделай». Они не будут в третий раз переписывать реализацию, потому что вдруг изменился подход в какой-то системной библиотеке. А он будет меняться еще десять раз, потому что софт в стадии развития. А раз они не способны на поддержку своего кода, то он — либо бессмысленная трата времени, потому что он не будет использоваться, либо дополнительная нагрузка на текущих разработчиков, которым придется поддерживать код, сделанный людьми, которые не до конца понимают принципы работы и стиль написания (см. п. 1). Зачастую он такого качества, что проще переписать с нуля, чем отлаживать приложения в попытках найти, где же бага.

Кроме того, вот именно то, что вы предлагаете — раздать разрабам, уже и было сделано на хакатоне, условия которого были очень лайтовые — заявите интересную идею и хоть что-нибудь сделайте. Что там сделали? Из 30 или-сколько-там-человек что-то продолжают писать в ядро и системный функционал — двое или трое. Остальные написали свою аппу, и на этом их разработка закончилась. А, ну еще один, «образующий альтернативную версию ПО», которая идет вразрез с политикой разработчиков флиппера. И хорошо, что их трое, а не 30, потому что см. п. 1 и п. 2, существующие же разрабы зашились бы.
Я понял у Вас стереотипное мышление. Но они продают товар для энтузиастов и подход должен быть соответствующий.
Новые опенсорсные программисты — это люди, пришедшие сюда ради интереса
Этот товар делается в основном для них.
Из 30 или-сколько-там-человек что-то продолжают писать в ядро и системный функционал — двое или трое.
Их должно было быть 3000.
А, ну еще один, «образующий альтернативную версию ПО»
А этих должно быть не один, а двадцать один.
Flipper должен был стать «пластилином» из которого можно легко создать «тулс своей мечты».
Кроме того, вот именно то, что вы предлагаете — раздать разрабам
Да! Это был бы дружественный шаг, на встречу комьюнити. А сейчас ему просто не из чего образоваться.

1) Как решать проблему освобождения памяти когда задача аллоцирует через IPC ресурс в памяти другой задачи\сервиса?
2) Для разделения куч на каждую задачу надо запланировать ее определенный размер и адрес, обеспечивая неперекрываемость адресов размерами из-за некоторых особенностей, см ниже.
3) В MPU может быть только 8 регионов.
4) Гранулярность размера региона задается с шагом в степень двойки (32, 64, 128...), например мы не можем задать регион в 10 килобайт, только в 8 или 16, что обеспечивает очень сложное прогнозирование допустимого размера кучи на задачу.
5) Адрес участка должен быть кратен его размеру. Нельзя защитить восемь килобайт оперативной памяти начиная с третьего килобайта, только с нулевого или с восьмого. Это дает еще больше ада при прогнозировании размеров и адресов куч.

Из-за всех этих особенностей MPU практически неприменим на кортексах-м даже для защиты стека задач.

1) Переписать её память в память другой задачи внутри SVC, так же часть тесно взаимодействующих задач могут быть объединены в рамках одного процесса и быть в одном защищённом регионе.
2) Так это хорошо когда приложению ограничат доступ к общей памяти, оно пусть скажет сколько ему надо, а система подумает пускать его в работу или нет. Иначе оно пойдет в разнос и кому очень надо не достанется.
3) Значит можно выделить 8 независимых heap'ов на процесс, очень даже не кисло. А в M7 даже 16 дают. Некоторые даже все 8 пристроить не могут.
4) Каждый регион может быть разделён на 8 частей — сразу проще стало.
5) Опять же, разделение каждого региона на 8 частей упрощает эту задачу.

Из-за этих особенностей MPU может достаточно легко защитить программы от взаимного повреждения памяти (а так же всех ресурсов МК), и полностью передать её контроль ОС.

1) Сам IPC пишется больно, не представляю (точнее слишком хорошо представляю) боль при том что еще накладываются ограничения на память и передачу указателей. Кстати как решается то что ресурсом должен владеть (пользоваться, читать\писать) и сервис и наша задача? IPC на каждый чих в каждую сторону? Но для IPC так же нужна общая область памяти.

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

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

1) Для IPC не нужна своя память. Вы свободно пользуетесь вытесняющим менеджером, так вот IPC ест ресурсов меньше. IPC должен работать из SVC и (пользоваться, читать\писать) не будет проблем.
IPC на каждый чих в каждую сторону
Ну не попиксельно же передавать изображение.
2) Если невозможно спрогнозировать то давать с адекватным запасом. Но отдавать всё что можно сразу — это уже крайность.

я изучал, очень много изучал разные проекты и подходы к ос
Я понимаю, но этого недостаточно, нужно экспериментировать, с первого раза и у меня не получилось, но со 1001…

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

Ну и если у вас удалось реализовать такой подход - поделитесь им, код сразу решит многие возникшие вопросы.

код сразу решит многие возникшие вопросы
Даже не знаю. Я уже всё расписал как делать. А flipper'а дадите?
НЛО прилетело и опубликовало эту надпись здесь

Потому-что это не "приложение". Вся прошивка есть одно большое приложение :)

И всё же FreeRTOS кажется сложноватой, а как там дела с поддержкой Arduino IDE?
Я считаю что поддержка Arduino IDE очень важна для тех кто ей уже пользуются. Как они смогут приобрести устройство и безболезненно пользоваться им. Тогда со временем у них появится желание перейти на полноценную работу и изучить «правильное» программирование.
Как показывает практика, если человек не хочет осваивать описанное в статье (а оно уж реально несложное, я не понимаю, как описать проще), и хочет писать как и дальше в Arduino IDE, то в 90% случаев желания перейти дальше у него так и не появится.

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

Так что я не очень понимаю, для чего Arduino IDE?
Чтобы не напугать пользователя? Так если его пугает взять готовый каркас приложения и писать в нем, то вряд ли он напишет что-то толковое.
Упростить задачу? А она не упростится, библиотеки переиспользовать нельзя, готовые программы работать не будут, интерфейс надо будет писать с нуля.
Поиграться, написав hello world и поморгав светодиодом? Ну можно, тоже важная штука, но в списке приоритетов далеко не на первом месте.
НЛО прилетело и опубликовало эту надпись здесь

Большая часть библиотек ардуино не портируется под другой камень даже при наличии интерфейсов, из-за регистров и PROGMEM. Еще большая часть - не портируется в RTOS вообще, из-за подхода к памяти как к единоличному ресурсу.

НЛО прилетело и опубликовало эту надпись здесь

Пишутся одновременно под все камни. Например https://github.com/FastLED/FastLED/blob/26baf51559a7f09c580b1c0f38ea6c7675663ea9/src/fastspi.h

Или пишутся отдельно под каждый камень, например https://github.com/jkb-git/ESP32Servo

НЛО прилетело и опубликовало эту надпись здесь

Все возможные существующие библиотеки для Ардуино переписать под Флиппер? Да, сложновато, судя по тому что даже под ESP не все еще переписаны, только самые распространенные.

НЛО прилетело и опубликовало эту надпись здесь

Скажу как ленивый человек, которому приходилось вылезать из теплого уютного arduino ide.

Ломка проходит очень быстро. И без всех этих digitalWrite и пр., живётся вполне себе нормально. И нет большой разницы, пишешь ли ты код с использованием новой для тебя библиотеки в arduino ide или любой другой си библиотеки.

Если ты не знаешь самых основ, да, становится менее уютно.

НЛО прилетело и опубликовало эту надпись здесь
ну так то дигитал врайт\реад, wire конечно сложно реализовать, я понимаю


Вам что, надо #define DigitalWrite hal_gpio_write? Так это и сейчас можно сделать.
НЛО прилетело и опубликовало эту надпись здесь

Еще раз повторю, базовые библиотеки (те что в поставке самой Ардуино) делаются относительно несложно и они у нас в планах. Только они не обеспечат совместимости со всеми остальными библиотеками (те что за пределами поставки Ардуино), так как в каждой библиотеке свой собственный слой совместимости с железом, плюс подходы к работе с железом в этих библиотеках не учитывают ОС, и сделать PR для поддержки нашего железа в каждую библиотеку мы не сможем.

НЛО прилетело и опубликовало эту надпись здесь

А можно пару-тройку примеров?

НЛО прилетело и опубликовало эту надпись здесь

Слой совместимости, к слову, не очень сложно делается. Только на одних analog read и gpio write далеко не уехать, большая часть сложностей в GUI и работе с файлами, и в ардуино для этого нет подходящих абстракций. А если нужно что-то изучать в любом случае, то почему не изучить сразу голый апи Флиппера?

То есть без шансов, сазу в бой, без обучения!

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

слоя для базовой совместимости
Этого вполне достаточно.

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

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

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

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

Подскажите, сколько места они занимают изначально, из тех 256 кб оперативки?

256 это на самом деле 192 + 32 + 32.

Где 32 + 32 отдается второму ядру и IPC.

Из оставшихся 192 мы используем 70.

Остается 120к.

НЛО прилетело и опубликовало эту надпись здесь

Чтобы не нарваться на страйк платежных систем рассылаем постепенно. Использовать свой купон на предзаказ вы можете по этой инструкции https://t.me/zhovner_hub/1516

НЛО прилетело и опубликовало эту надпись здесь

Полторы недели рассылаем.

Не подскажите более современные аналоги, которые не устарели?

НЛО прилетело и опубликовало эту надпись здесь

Proxmark всё же больше по части NFC и 125/128 кГц. И ноутбук с линуксом и знанием специфичных команд для него требует, емнип. По крайней мере, я себе 125 кГц чипы запорол, не указав пароль и с тех пор не могу перезаписать. Только NFC остался.

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

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Еще эта реализация не потокобезопасна

Хм, заставило задуматься. На x86 не происходит ничего страшного, если один тред инкрементит значение поля структуры, а второй его по тому же адресу читает для отрисовки. Отрисованное значение всегда будет корректным, актуальным на момент чтения. На ARM'е хуже обстоят дела? Не понимаю за счет чего. Слабая модель памяти вроде не должна повлиять...

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

Концептуально нету разницы между армом и x86 для того что мы написали. Есть общие проблемы дизайна lock-free алгоритмов и структур данных. Самый просто пример это когда модель не помещается в машинное слово и её частичное обновление приводит к крашу, в этом случае явно нужно ее гардить каким-либо примитивом синхронизации ОС.

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

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

Так в итоге в вашем примере может упасть или нет? Не очень понял.

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

Так в итоге в вашем примере может упасть или нет? Не очень понял.

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

Возможно, я что-то не понимаю, но в момент выделения counter_app_alloc и counter_app_free в alloc выделяется память под структуру CounterApp с помощью furi_alloc. А в counter_app_free эта память не освобождается. То есть утекает...

Да, free(app) потерялся, mea culpa. Поправил.

У ребят на сайте сказано, мол

Flipper's main components are written in C, C++, and Rust

Интересно, на двух последних языках процесс разработки приложений что примерно из себя представляет?

Rust нету, его дропнули давно. Всё ядро на С, а С++ можно найти во фрэймворке гуйовых приложений и приложениях RFID, IR, iButton.

Почему, интересно, дропнули

Обскурно и прилично добавляет сложностей в экспорте api.

НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации