Solonovatiy 0 17 ноября, 2022 Опубликовано 17 ноября, 2022 (изменено) · Жалоба Здравствуйте. Хотел бы поговорить о некоторых базовых аспектах архитектуры ПО встраиваемых систем. У меня есть несколько мыслей и\или вопросов, хотел бы услышать о них мнение\контраргументы или ответы. 1. Мне кажется, что с RTOS надо быть предельно осторожным. До того, момента, пока RTOS используется лишь для взаимодействия с периферией, а сама бизнес логика (далее БЛ) работает синхронно в одном потоке - все хорошо. Зло начинается, когда БЛ начинает требовать асинхронности, начинается создание каких-то монстров, модули БЛ обзаводятся стейтами очередями, им приходится писать обработки таймаутов очередей, синхронизации и т.п. Не говоря уже про то, что лишний таск жрет ОЗУ и не мало, даже по современным меркам. Короче мысль такая - всех асинхронных сущностей RTOS надо стараться избегать пока не припрет по полной, стараться до конца делать однопоточную БЛ, деля ее только тогда, когда кол-во оверхеда для синхронной работы сильно (именно сильно) превысит оверхед для асинхронности. Насколько по вашему это правильное мнение? 2. Я давно и долго не могу определиться, надо ли избегать по максимуму "активных" модулей (не уверен в термине, т.е. имеющих возможность самостоятельно начать некую цепочку действий, грубо говоря, модули имеющие методы\функции Process(void), Handler(void) и т.п. Т.к. это по факту асинхронность для бедных и возникают все те же самые проблемы вроде наличия некого "состояния", которое может неявно(для другого модуля) менятся. Пример: Spoiler main: Head.Process(); Legs.Process(); Head : if(stupid_thought) : Legs.Jump(); else if(nice_thought) : Legs.WalkTo(nice_thought.destination); Код содержит ошибки, т.к. мы можем попытаться пойти, а уже ноги прыгнули. Пример рудиментарный, но помимо ног, могут быть руки, ноги, жопа или электродвигатель на пару десятков киловатт. Что делать ногам в таком случае? Или может сделать очередь команд? Голове придется убеждаться, что с ногами все хорошо и т.д. и т.п. С другой стороны можно обмазаться абстрактными сущностями (вроде ThougtsRouter) и\или разделить голову на множество других, которые будут отвечать за свои "ноги" и работать только с ними. И я не знаю какой правильный и к какому стремиться. Оба ведут к сильному усложнению кода, первый к невероятно запутанным и многофункциональным "ногам" и "голове" занимающейся постоянной возней с состоянием ног (привет ОКР), второй ведет к тонне абстракций, что тоже увеличивает шанс сделать макаронного монстра, особенно когда они потекут... 3. Я не знаю ничего кроме MVP, что пойдет для отображения данных. А MVP очень туго ложиться на С и туговато на С++, да и вообще, если делать его по феншую, надо ему систему ивентов заводить, а это привет лишняя асинхронность, да и тяжеловато. В то же время делать синхронный MVP это тоже чудище, которое добавляет зависимости. Есть какие-нибудь альтернативные пути? 4. Бонусом к 3ему, идет если данные надо передавать во вне. Это же их надо СЕРИАЛИЗИРОВАТЬ. А сериализация на С\С++ это чертова боль, огромное кол-во бойлерплейта и вообще пахнет хидерами на 2000 строк. Ну или если у вас есть доступ к последнему стандарту С++ можно накинуть шаблонного чернокнижия, но вы проклянете свою душу и сами себя через несколько месяцев. 5. Я не знаю как сохранять данные на бинарный носитель (еепром какой), иначе, как хреначить какой очередной хидер на 2000 строк, в котором вы обязательно ошибетесь во время очередных правок\удаления адресов. Это вообще больная тема, я наверно с ней близок к тому, что для этого написать какую кодогенерацию всей этой фигни на JS. Может существует какая волшебная пилюля? Изменено 17 ноября, 2022 пользователем Solonovatiy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 17 ноября, 2022 Опубликовано 17 ноября, 2022 · Жалоба 10 минут назад, Solonovatiy сказал: Короче мысль такая - всех асинхронных сущностей RTOS надо стараться избегать пока не припрет по полной, стараться до конца делать однопоточную БЛ, де Рассмотрите вариант кооперативной ОС: требует поменьше ресурсов и диспетчер будет вызываться только вручную, там где вы явно укажете delay или yield. При таком подходе, примитивы синхронизации уже не столь необходимы. Возможно, следует пересмотреть архитектуру БЛ. 18 минут назад, Solonovatiy сказал: Ну или если у вас есть доступ к последнему стандарту С++ можно накинуть шаблонного чернокнижия, но вы проклянете свою душу и сами себя через несколько месяцев. Постоянно думаю, что пора бы освоить плюсы, но как-то мотивации не хватало. Теперь точно не хватит) 20 минут назад, Solonovatiy сказал: Я не знаю как сохранять данные на бинарный носитель (еепром какой), иначе, как хреначить какой очередной хидер на 2000 строк, в котором вы обязательно ошибетесь во время очередных правок\удаления адресов. Это вообще больная тема, я наверно с ней близок к тому, что для этого написать какую кодогенерацию всей этой фигни на JS. Если вы собираетесь каждый адрес описывать в хидере, то даже ЖС не поможет. Сишные структуры вам в помощь Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 17 ноября, 2022 Опубликовано 17 ноября, 2022 · Жалоба 31 minutes ago, Solonovatiy said: Может существует какая волшебная пилюля? Нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 17 ноября, 2022 Опубликовано 17 ноября, 2022 · Жалоба 27 минут назад, Solonovatiy сказал: Зло начинается, когда БЛ начинает требовать асинхронности, начинается создание каких-то монстров, модули БЛ обзаводятся стейтами очередями, им приходится писать обработки таймаутов очередей, синхронизации и т.п. Не говоря уже про то, что лишний таск жрет ОЗУ и не мало, даже по современным меркам. Короче мысль такая - всех асинхронных сущностей RTOS надо стараться избегать пока не припрет по полной, стараться до конца делать однопоточную БЛ А почему ваша БЛ на RTOS - требует асинхронности, а без RTOS - не требует? Или другими словами: Почему некая БЛ без RTOS может выполняться однопоточно, а с RTOS такая же БЛ - не может? Что это за БЛ такая, которую соседство с RTOS так портит? Разберитесь в этом вопросе... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 17 ноября, 2022 Опубликовано 17 ноября, 2022 · Жалоба 1 минуту назад, jcxz сказал: Что это за БЛ такая, которую соседство с RTOS так портит? Видимо, очень сложный бизнес - очень сложная логика)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Solonovatiy 0 17 ноября, 2022 Опубликовано 17 ноября, 2022 · Жалоба 15 minutes ago, tgruzd said: Рассмотрите вариант кооперативной ОС: требует поменьше ресурсов и диспетчер будет вызываться только вручную, там где вы явно укажете delay или yield. При таком подходе, примитивы синхронизации уже не столь необходимы. Да, думал попробовать полапать FreeRTOS в кооперативном. Но это не какая-то серебряная пуля. Сами примитивы не проблема, проблема в том, что асинхронный модуль он как его не крути и не запускай будет требовать не мало дополнительного кода и скорее всего будет иметь свое состояние, которое так или иначе придется синхронизировать. (Пример: модуль двигателя, получает команду из другого потока на запуск, а он в транзитном состоянии - останавливается например. Вам придется обрабатывать такое, а значит и описывать состояние и поведение в этом состоянии. В то время как в синхронном модуле, весь этот головняк будет на управляющем модуле. Пример надуманный и простой, но все же). Quote Постоянно думаю, что пора бы освоить плюсы, но как-то мотивации не хватало. Теперь точно не хватит) Ну после даже базовых шаблонов на чистом С уже совсем неприятно писать становится. 20 minutes ago, jcxz said: А почему ваша БЛ на RTOS - требует асинхронности, а без RTOS - не требует? Или другими словами: Почему некая БЛ без RTOS может выполняться однопоточно, а с RTOS такая же БЛ - не может? Что это за БЛ такая, которую соседство с RTOS так портит? Разберитесь в этом вопросе... Я не говорил такого. Я вполне себе написал, что "До того, момента, пока RTOS используется лишь для взаимодействия с периферией, а сама бизнес логика (далее БЛ) работает синхронно в одном потоке - все хорошо". Случай асинхронной БЛ без РТОС я не рассматривал ввиду бессмысленности (ну будет там самокостыльная микроРТОС), ну а как вы еще сделаете асинхронную БЛ еще? Если упростить - вопрос скорее про то, что асинхронность БЛ кажется очень стрёмным и излишне сложным путем и лучше ее пытаться делать синхронной, даже когда это неудобно (до определенной грани). 30 minutes ago, tgruzd said: Если вы собираетесь каждый адрес описывать в хидере, то даже ЖС не поможет. Сишные структуры вам в помощь А как вам помогут структуры то? Автоматом определять размер? Ну допустим. А следующий адрес как высчитывать? Вот есть модульА и модульБ. Где размечать адреса? Ну разметим для модуляА прям у него, взяли адресок стартовый, взяли размер конфига, ок.А модулюБ где брать адрес? Знать хидеры модуляА? Я однажды имея мало ОЗУ и много ПЗУ тупо писал в ПЗУ по адресу ОЗУ, ну а че? Зато кода строк 50 на это дело и расширяемость бесконечная (пока ОЗУ не кончится) = ) Я короче вас тут не понял. Далее - даже если так. Автогенерация адресов из самих СИ не может решить проблему. Тут же запрещает переносимость данных между версиями ПО. Причем там даже не всегда надо данные менять то, компилятор вполне может поменять че сам, если это плюсы какие (в си наверно нет, мне не известно такого). Для переносимости данных, да даже что бы иметь возможность их если что руками вычитать и интерпретировать (авария, разборы, дебаг и т.п.) вам потребуется бить адреса руками. Либо нужен механизм однозначной генерации адресов по неким правилам, но мне он неизвестен (только подключая кодогенерацию). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 17 ноября, 2022 Опубликовано 17 ноября, 2022 · Жалоба 19 минут назад, Solonovatiy сказал: А как вам помогут структуры то? 19 минут назад, Solonovatiy сказал: ПЗУ тупо писал в ПЗУ по адресу ОЗУ, ну а че? 23 минуты назад, Solonovatiy сказал: Для переносимости данных, да даже что бы иметь возможность их если что руками вычитать и интерпретировать (авария, разборы, дебаг и т.п.) вам потребуется бить адреса руками. Может, ну их нахер эти микронтроллеры, а? 23 минуты назад, Solonovatiy сказал: Либо нужен механизм однозначной генерации адресов по неким правилам, но мне он неизвестен (только подключая кодогенерацию). Сишные структуры, сэр Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Solonovatiy 0 17 ноября, 2022 Опубликовано 17 ноября, 2022 · Жалоба 6 minutes ago, tgruzd said: Может, ну их нахер эти микронтроллеры, а? Сишные структуры, сэр Пример. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 17 ноября, 2022 Опубликовано 17 ноября, 2022 · Жалоба 1 час назад, Solonovatiy сказал: Я не говорил такого. Я вполне себе написал, что "До того, момента, пока RTOS используется лишь для взаимодействия с периферией, а сама бизнес логика (далее БЛ) работает синхронно в одном потоке - все хорошо". Ну как же "не говорил"?! У нас все ходы записаны: 1 час назад, Solonovatiy сказал: Зло начинается, когда БЛ начинает требовать асинхронности Не передёргивайте! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Solonovatiy 0 17 ноября, 2022 Опубликовано 17 ноября, 2022 (изменено) · Жалоба 9 minutes ago, jcxz said: Ну как же "не говорил"?! У нас все ходы записаны: Не передёргивайте! Ну? А причем тут связь с RTOS? Я искренне не вижу, где вы тут зависимость на RTOS нашли? БЛ может требовать асинхронности, но это не зависит от наличия или отсутствия RTOS, это требование исходя из задач и архитектуры самой БЛ. Не суть. Я позицию прояснил. Я не утверждаю, что RTOS заставляет делать асинхронную БЛ. Спрашиваю кратко: Quote Если упростить - вопрос скорее про то, что асинхронность БЛ кажется очень стрёмным и излишне сложным путем и лучше ее пытаться делать синхронной, даже когда это неудобно (до определенной грани). Или развернуто в заглавном посте. Изменено 17 ноября, 2022 пользователем Solonovatiy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 17 ноября, 2022 Опубликовано 17 ноября, 2022 · Жалоба 24 минуты назад, Solonovatiy сказал: вопрос скорее про то, что асинхронность БЛ кажется очень стрёмным и излишне сложным путем и лучше ее пытаться делать синхронной В целом, так и есть. Я, может быть, как-то не так понимаю асинхронность, но, по-моему, там, где есть асинхронность -- нет логики. Да, какие то процедуры могут выполняться асинхронно в системе, но как только вы захотите логику, вам потребуется их синхронизировать. То есть, изначально БЛ должна быть логичной, простите за "масло маслянное". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Solonovatiy 0 18 ноября, 2022 Опубликовано 18 ноября, 2022 (изменено) · Жалоба 23 minutes ago, tgruzd said: В целом, так и есть. Я, может быть, как-то не так понимаю асинхронность, но, по-моему, там, где есть асинхронность -- нет логики. Да, какие то процедуры могут выполняться асинхронно в системе, но как только вы захотите логику, вам потребуется их синхронизировать. То есть, изначально БЛ должна быть логичной, простите за "масло маслянное". То что потребуется синхронизировать, не противоречит тому, что модули могут быть асинхронными. Например хз, вот из последнего, что подбешивало, модуль писательЛогов и остальной софт, писателю логов очень удобно быть асинхронным, т.к. он будет блокироваться на всякие filesystem IO вызовах. Другое дело, является ли писательЛогов бизнес логикой? Spoiler А это уже зависит. У меня этот модуль принимал бинарные данные и уже сериализировал их перед самой записью. Не очень правильно, но это имеет меньший оверхед, чем писать инфраструктуру для пинания строк по всему приложению. Поэтому да, являлся. Наверно можно было бы заморочиться и родить неблокирующее fsio, но это еще дополнительная инфраструктура + это один фиг потребует "асинхронность для бедных" вроде очереди на запись и всех танцев с нею. Изменено 18 ноября, 2022 пользователем Solonovatiy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 18 ноября, 2022 Опубликовано 18 ноября, 2022 · Жалоба 6 минут назад, Solonovatiy сказал: синхронизировать, не противоречит тому, что модули могут быть асинхронными Да, наверное, мы по-разному понимаем асинхронность. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Solonovatiy 0 18 ноября, 2022 Опубликовано 18 ноября, 2022 · Жалоба 2 minutes ago, tgruzd said: Да, наверное, мы по-разному понимаем асинхронность. А как ее можно по разному понимать? Это не совпадение по времени. В данном случае - выполнения. МодульА не знает когда точно будет выполнятся код МодуляБ. Остальное уже вытекающее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 18 ноября, 2022 Опубликовано 18 ноября, 2022 · Жалоба Если бы ваш писатель писал логи, не зная, просил ли об этом другой модуль, то да: чистая асинхронность. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться