Pingvin писал(а):
Я вот хочу попробовать все таки разбить проект на функциональные библиотеки.
Пользователю оставить только главный цикл с игровой логикой и API функции библиотек.
Это же удобно - подключаешь библиотеку в проект, инклюдиш хедер - и пользуйся.
То, что вы описываете - это нормальная архитектура любого проекта, а не какая-то особая идея. Любой хороший код состоит из библиотек (статических, или просто пар .c/.h), максимально изолированных друг от друга (а ещё на эти библиотеки пишут юнит-тесты, советую ознакомиться).
Парадигма ООП развивает такой подход дальше: есть объекты, и пользователь их использует. Объекты можно подключать друг к другу, заставлять взаимодействовать через интерфейсы. Именно так в Caustic и сделано.
Просто берем класс, например, отвечающий за парсинг MilesTag2, подсоединяем к нему класс, принимающий ИК-сигнал с одной стороны и класс, обрабатывающий "системные вызовы" с другой, и готово, всего несколько строк на стороне пользователя, и заработал датчик. Хотим зоны поражения - ещё один уровень абстракции, пара интерфейсов - и снова 10 строк кода активируют всё, что нужно.
Если говорить таким языком - просто возьмите мой код. Там всё уже сделано, разделено на библиотеки и изолировано. Разве только не скомпилировано в отдельные статические либы (хотите - можно разделить на либы, это тривиально, но ухудшает компактность прошивки на выходе).
Насчет одного "главного цикла", в котором "пионер" напишет "игровую логику" - это только самую простую игровую логику получится описать. Для сложной нужна асинхронная обработка множества событий, несколько стейт-машин (aka конечных автоматов). Для этого нужны свои уровни абстракции, фреймворки. Иначе получится адский спагетти-код.
Чтобы научиться строить правильную архитектуру приложения (даже самого простого), нужно знать и уметь применять основные шаблоны проектирования (design patterns) для данного языка и нужен опыт. ИМХО, где-то после сотни тысяч строк написанного кода приходит понимание, и архитектура становится нормальной.
В целом написать правильно структурированную программу проще на C++, чем на C. Для того его и придумали.
Pingvin писал(а):
Но тямы пока не хватает.
Как решается вопрос, если нужно присвоить значение глобальной переменной из либы, а переменная объявлена в коде пользователя?
Через указатель?
Во-первых, должен быть самый минимум глобальных переменных в любом коде. Каждая глобальная переменная увеличивает связанность разных частей программы непрозрачным образом. Ну и много других причин, почему не должно быть глобальных переменных.
Если либа должна использовать внешнюю переменную, лучше передать в либу указатель на неё на стадии инициализации. Либа будет хранить указатель приватно (в static-переменной). Тогда глобальной переменной не будет, и из кода инициализации либы будет явно следовать: либа использует вот эту вот переменную, и все.
На худой конец можно определить переменные в этой либе, а снаружи брать их через extern. Тогда при линковке они будут взяты из того места, где определены.
Pingvin писал(а):
Можно ли симофоры отдавать из либы, если симофоры у нас объявлены как глобальные переменные в коде пользователя?
Может объявить их глобальными переменными в либах, а в коде пользователя объявить как extern?
Семафоры - это такие же переменные, с ними всё то же самое можно делать. Просто посмотрите, как они реалиованы во FreeRTOS, благо кода не много.
Pingvin писал(а):
Как реализовывать callback функции?
Буду искать, пробовать...
Если хотите писать принципиально на чистом C, то коллбэки - это просто функциональные указатели, про них есть много где информация. Если все-таки на C++, то правильнее использовать функторы (std::function<>). Про это тоже много где написано.
Pingvin писал(а):
И вообще - иметь набор библиотек для различных железяк, которые можно легко подключить к любому проекту - разве плохо?
Порог вхождения в сообщество "прошивкописателей" снизился бы.
Эдакая лазертаг-ардуино...
На самом деле любой проект X в идеале представляет из себя X-ардуино, даже если там нет микроконтроллера
Про это писал выше. Мой проект вполне себе ардуина - просто берем и используем классы, как хотим. Так, например, я за короткое время сделал контрольную точку без копипасты кода, описав только логику её работы и использовав классы, написанные ранее (правда сейчас временно забросил точку за более интересными задачами)
Pingvin писал(а):
Пробовал вчера собрать Андроид приложение из проекта Каустик - что то ему не понравилось, версия чего то там...
Если правильно понял - там в сообщении об ошибке появляется что-то типа ссылки - кликайте на неё, и среда сама установит нужные компоненты.