Домашняя страница
Арго Фреймворк Википедия
Содержание
- Введение *
- Назначение и Основные Принципы Арго Фреймворка
- Архитектура Фреймворка
- Модуль Ядра (Кернел)
- Менеджер Приложений
- Менеджер Установки
- Сокет Приложений
- Плеер
- Менеджер Ресурсов
- Менеджер Данных
- Менеджер Файловой Системы
- Менеджер Событий
- Менеджер Тем
- Менеджер Системных Сообщений
- Утилиты Фреймворка
- Отладочный Терминал
- Генератор Бинарных Файлов
- Программный интерфейс
- Корневой Интерфейс - Библиотека Приложений
- Библиотеки Поддержки
- Функции Интеграционного Уровня
- Дополнительные Библиотеки
- Установка Фреймворка
- Приложения Фреймворка
- Создание Приложений
- Примеры Приложений
- Структура Приложений
- Структура Управляющих Элементов
- Утилиты Фреймворка
Назначение и Основные Принципы Арго Фреймворка
Назначение Арго фреймворка - это создание насыщенного графического пользовательского интерфейса с минимальными затратами времени на разработку. Также, фреймворк требует минимальных затрат ресурсов системы для отображения и управления пользовательским интерфейсом. Фреймворк разрабатывается как мультиплатформенное решение и способен работать на различных операционных системах и аппаратных платформах. Требования к операционной системе минимальны: наличие дисплея и соответствующих драйверов, наличие системы пользовательского ввода (сенсорный экран, мышь, клавиатура и т.д.) и возможность получать события от этих устройств. Фреймворк позволяет реализовать пользовательский интерфейс на устройствах в условиях очень ограниченных ресурсов по быстродействию процессора и оперативной памяти.
Основные архитектурные принципы определяют мультиплатформенность фреймворка, адаптивность к различным областям применения, отказоустойчивость системы на базе фреймворка и многие другие свойства. К основным принципам относятся использование языка “Си”. Компоненты фреймворка представляют собой объекты модулей, реализованных как псевдо-классы на “Си”. Это напоминает Component Object Model (COM), но реализация таковой не является. Это позволяет сделать весьма компактный и удобочитаемый код с минимальным количеством ошибок. Отдельные модули могут быть глубоко протестированы автоматическими тестами с целью выявления багов и обеспечения масимального кодового покрытия (Line Coverage).
Вторым базовым принципом фреймворка является отказ от использования каких либо стандартных заголовочных файлов и стандартных библиотек в коде ядра фреймворка и сопутствующих библиотек. Все внутренние операциии производятся исключительно средствами фреймворка. Общение с операционной системой выполняется через специальный интеграционный уровень (Integration Layer), который транслирует вызовы ядра в вызовы операционной системы или стандартных библиотек. Интеграционный уровень обеспечивает адаптацию фреймворка к операционной системе. Основная адаптация долна быть выполнена для отрисовки фреймбуфера на дисплее и получения событий пользовательского ввода. Остальная часть интеграционного уровня написана с использованием POSIX стандарта и требуются лишь минимальные изменения на POSIX совместимых ОС.
Основной возможностью фреймворка является полноценный уровень приложений, который позволяет предустанавливать некий набор приложений, устанавливать новые в процессе работы или удалять ранее установленные приложения. Разумеется, уровень приложений отвечает за запуск приложений (автоматически или по вызову от пользователя), взаимодействие приложения с подсистемами фреймворка, выгрузку или перевод приложения в фоновое состояние.
Второй основной возможностью является поддержка нескольких дисплеев на уровне ядра фреймворка (количество дисплеев не ограничивается). Разумеется, при этом требуется поддержка дисплеев и на интеграционном уровне. В терминах фреймворка дисплеем может считаться любое устройство ввода/вывода: физический дисплей, сенсорная панель (touch pad), клавиатура. Это позволяет легко настраивать фреймворк под различные конфигурации оборудования и обрабатывать события от него унифицированным методом. Например, мы хотим использовать клавиатуру как некий виртуальный дисплей (это не обязательно, конечно, фреймворк может получать события от клавиатуры напрямую). Все кнопки при этом представляются как некие “пикселы” в матрице. Нажатие на кнопку будет интерпретировано как некое событие, эквивалентное нажатию на сенсорный экран. Такие события перенаправляются фреймфорком в приложение-сервис, которое обслуживает события в этом виртуальном дисплее и трансформирует их в стандартные события, соответствующие нажатию кнопок - по сути так работает и виртуальная клавиатура, отображаемая на физическом дисплее.
Каждый дисплей содержит один или несколько виртуальных суб-дисплеев. Виртуальными они являются, потому что не содержат физической памяти для отрисовки изображений и определяют лишь границы, в которых будет отрисовываться окно приложения, привязанное к этому суб-дисплею. Количество суб-дисплеев также не ограничивается, но последовательность объявлений определяет приоритет суб-дисплея: самый первый определенный суб-дисплей имеет минимальный приоритет, все последующие идут с увеличением приоритета. Суб-дисплеи могут занимать все пространство дисплея или только часть его, перекрываться друг с другом. Основное назначение суб-дисплеев - это определение приоритетов окон приложений. Например, на экране присутствует приложение с нормальным приоритетом (приоритетом по умолчанию). В этот момент происходит некое событие, которое вызывает запуск системного предупреждения, и на экране должно отобразится соответствующее окно. Это окно будет запущено в высоко приоритетном суб-дисплее, который полностью перекрывает суб-дисплей с нормальным приоритетом. В результате окно предупреждения перекроет текущее приложение, и оно будет недоступно до тех пор, пока пользователь не отреагирует на это предупреждение. Любой высокоприоритетный суб-дисплей прозрачен, если в нем нет активированных окон, и становится непрозрачным, как только в нем активируется привязанное к нему окно. Этот механизм позволяет очень легко управлять приоритетами окон.
Помимо конфигурации интеграционного уровня фреймворк, обеспечивает еще несколько механизмов конфигурирования. Первый механизм - конфигурирование начальных стартовых параметров через специальный файл, или через переменные окружения, или опции командной строки запуска. Эти механизмы имеют свои приоритеты: параметры, установленные в конфигурационном файле, могут быть переопределены переменными окружения, те же, в свою очередь, могут быть переопределены параметрами командной строки.
Второй механизм - конфигурационное XML описание, это основной механизм. Какое конфигурационное описание будет использовано - определяется стартовыми параметрами. Конфигурационное XML описание определяет все параметры системы: дисплеи и их размеры, виртуальные суб-дисплеи; графические и прочие ресурсы системы (точнее определяет файлы, в которых ресурсы описаны); системные базы данных для хранения каких либо параметров/переменных; список предустановленных приложений и их параметры; пути к файловым системам, которые доступны приложениям; стили окон приложений и доступные языки системы.
Также в описании могут быть переопределены некоторые глубинные параметры системы - это третий механизм конфигурации системы. Конфигурационные параметры содержат некоторые значения по умолчанию и используются при старте системы: определяют размеры внутренних буферов или глубину очередей для передачи событий - т.е. позволяют производить тонкую настройку системы. Значения по умолчанию могут быть переопределены в системном XML описании.
Архитектура Фреймворка
На самом верхнем архитектурном уровне фреймворк состоит из следующих компонент: библиотека ядра фреймворка, модуль системы (там по сути только функция main()), библиотеки интеграционного уровня и набор вспомогательных библиотек (библиотека для формирования бинарных файлов и их загрузки, библиотеки приложений, библиотека для отрисовки графики, библиотека для управления оперативной памятью и некоторые другие).
Библиотека ядра фреймворка состоит из двух частей: собственно операционное ядро системы и SDK библиотеки. Операционное ядро выполняет все операции внутри фреймворка за исключением парсинга XML описаний. Большая часть обработки сосредоточена непосредственно в ядре, но некоторые процедуры вынесены в сопутствующие библиотеки, перечисленные выше. SDK библиотека предназначена для парсинга XML описаний, проверки корректности описаний и формирования внутреннего бинарного описания. Бинарное описание используется ядром и может быть выгружено в бинарный файл. Такой бинарный файл далее может использоваться вместо XML описаний. SDK версия фреймворка содержит обе эти части и может использовать XML описания на этапе разработки. Продуктовая версия не содержит SDK библиотеки и может использовать только подготовленные бинарные описания. Бинарные описания обеспечивают большой выигрыш по времени загрузки по сравнению с XML (загрузка в десятки раз быстрее), поэтому использование XML в конечном продукте нецелесообразно. Исходный код компонентов ядра недоступен в SDK и представлен в виде набора построенных библиотек.
Как уже упоминалось, модуль системы содержит только функцию main() и выполняет две основные и простые операции: создает экземпляр (объект) интеграционного уровня и производит вызов функции sysmain() ядра фреймворка. Реализация модуля системы зависит от OS (например, в Windows должна быть функция winmain()), поэтому код системного модуля открыт в SDK. По мере дальнейшего развития фреймворка модуль может быть усложнен, допустим, система запускается под root пользователем, а фреймворк под другим. На данный момент, для SDK, рутовый пользователь для запуска не требуется.
Интеграционный уровень содержит некоторый набор библиотек: основную (common) библиотеку для реализации необходимого фреймворку API за исключением механизмов ввода/вывода; библиотеку для реализации ввода/вывода - обслуживание дисплея и получения событий пользовательского ввода; библиотеку для логирования (logger); отдельные библиотеки для работы с сокетами и терминальным вводом/выводом - эти библиотеки не используются фреймворком и нужны только для SDK утилит фреймворка. Весь исходный код интеграционного уровня открыт и может модифицироваться разработчиком в соответствии с его запросами. Однако модифицировать API не позволяется, только его реализацию. Также надо учитывать, что модификации могут вызвать сбой ядра фреймворка.
Ниже кратко рассмотрим основные модули операционного ядра фреймворка.
Модуль Ядра (Кернел)
Модуль ядра, или далее везде кернел, отвечает за запуск и выгрузку модулей ядра в определенном порядке и в соответствии с базовыми параметрами и конфигурационным описанием. По базовым параметрам он определяет, где ему взять конфигурационное описание (XML или бинарный файл), получает бинарное описание системы (через SDK библиотеку или через библиотеку загрузки бинарных файлов) и производит загрузку в соответствии с этим описанием. Когда фреймворк выгружается, кернел производит выгрузку модулей в соответствии с заданным порядком.
Менеджер Приложений
Менеджер приложений предназначен для реализации всех операций, связанных с запуском приложений, переводом приложений в фоновое состояние и обратно, закрытием приложений. Также он отвечает за взаимодействие приложения с графической подсистемой ядра и взаимодествие с другими модулями и с другими приложениями. Менеджер относится к приложению как к некоторой абстрактной сущности - он знает, как его запустить, он может получать от него события и отправлять ему сообщения, у него есть информация активно приложение или нет. Вся эта информация сосредоточена в единой структуре экземпляра приложения, и менеджер оперирует только этой информацией и иформацией сообщений. Для запуска приложения он получает начальную информацию от менеджера установки, создает структуру экземпляра приложения и запускает так называемый сокет приложения - собственно механизм общения менеджера с приложением. Также в соответствии с установочной информацией, менеджер активирует графическую подсистему для отрисовки окон приложения. Выгрузка приложения выполняется удалением структуры экземпляра из списка запущенных приложений и последующей выгрузкой сокета и окон приложения (делается автоматически при удалении из списка).
Менеджер Установки
Менеджер установки отвечает за сохранение параметров приложения при их установке и удалением установочной записи, если приложение удалено. Приложения разделяются на предустановленные или системные, т.е. прописанные в системной конфигурации и размещенные на файловой системе по определенным правилам (Core applications), и на пользовательские, установленные по запросу от пользователя (User applications). Существует три главных и единственных отличия между этими группами: системные приложения не могут быть удалены, системные приложения могут иметь специальные привилегии доступа к подсистемам фреймворка, пользовательские приложения имеют ограничения в многодисплейной системе (только основной и выделенный суб-дисплей могут использоваться по умолчанию). При установке нового приложения менеджер добавляет информацию в специальный файл, и она будет далее доступна после перезагрузки системы. По запросу от менеджера приложений установочная информация ему будет предоставлена для запуска приложения.
Сокет Приложений
Когда менеджер приложений запускает новое приложение, он создает экземпляр сокета приложения. Сокет приложения, в первую очередь, отвечает за передачу событий от фреймворка к приложению (Downlink messages) и от приложения к фреймворку (Uplink messages). Сокет также отвечает за трансляцию событий в обоих направлениях (это некоторое преобразование изначального события - добавление или удаление служебной информации в зависимости от направления передачи). Также сокет создает экземпляр библиотеки приложения, которая непосредственно взаимодействует с приложением и предоставляет ему API для взаимодействия с фреймворком.
Плеер
Плеер - это корневой модуль графической системы и предназначен собственно для отрисовки окон приложений, обработки пользовательского ввода (обработка событий с сенсорного экрана или событий от клавиатуры, например). Для каждого дисплея создается свой экземпляр плеера, и он обслуживает все операции с данным дисплеем. Это крайне сложный модуль, который обслуживает все графические операции с окнами приложений:
- Поддерживает оконный стек и работу виртуальных суб-дисплеев.
- Обслуживает все встроенные виджеты (встроенные виджеты также легко кастомизуются, термин “встроенный” обозначает лишь то, что фреймворк знает, как обрабатывать поведение таких виджетов) и выполняет все графические операции с такими виджетами (нажатие/отжатие кнопки, ввод текста в поле ввода).
- Поддерживает работу с кастомными виджетами, используя специальные DLL для обработки поведения (в отличие от встроенных).
- Детектирует пользовательский ввод и отправляет в приложение соответствующие события (например, нажатие или отжатие кнопки). Плеер имеет специальную архитектуру, которая позволяет легко добавлять новые встроенные виджеты в виде новых суб-модулей плеера.
Для отрисовки графических элементов плеер запрашивает графические ресурсы у менеджера ресурсов. Также плеер плотно взаимодействует с менеджером приложений: создание и удаление окон, передача сообщений в приложение и получение запросов от приложений. Окна приложений, графические виджеты создаются с использованием соответствующих XML описаний и после парсинга этих описаний обрабатываются плеером (парсинг, как уже говорилось выше, выполняется SDK библиотекой).
Плеер выполняет отрисовки графических элементов в специальном фреймбуфере. Как только все операции с этим буфером завершены, плеер запускает механизм рендеринга дисплея - обновление содержимого экрана из этого фреймбуфера.
Менеджер Ресурсов
Менеджер ресурсов предназначен для управления различными типами графических ресурсов системы и отдельных приложений. В общем случае фреймворк использует идентификаторы ресурсов, прописанные в специальных конфигурационных XML файлах. Менеджер ресурсов обеспечивает:
- Загрузку ресурсных файлов с файловой системы в оперативную память, конвертацию различных файловых форматов во внутренний универсальный формат (плеер не может обрабатывать графические файлы в каком-либо формате, кроме этого внутреннего формата, поэтому, например, bmp файлы конвертируются в этот формат),
- Управление загрузкой/выгрузкой ресурсов по запросу от системы или приложения.
- Оптимизацию расхода оперативной памяти для ресурсных файлов. Например, если некий ресурс уже загружен в память и, если этот ресурс потребуется другому приложению, то повторно он уже загружаться не будет, и менеджер просто отдаст ссылку на уже загруженный экземпляр ресурса. Разумеется, менеджер обладает всеми средствами для выгрузки и очистки ОП при выгрузке приложений и системы в целом.
Ресурсы находятся в двух доменах: системные ресурсы и ресурсы приложений. Системные ресурсы могут использоватся явно или неявно любыми приложениями (например, стиль окна по умолчанию - это неявное использование системных ресурсов, как и использование ресурсов из темы). Напрямую системными ресурсами без ограничений могут пользоватся системные приложения. Однако, приложения в пользовательском режиме тоже могут использовать системные ресурсы если у разработчика есть доступ к описаниям системных ресурсов. Обычно, пользовательские приложения могут использовать только стиль окна по умолчанию, доступные элементы темы или обходиться собственными ресурсами. Ресурсы приложения могут использоваться только данным приложением, точнее, всеми экземплярами этого приложения.
Менеджер позволяет также создавать динамические ресурсы по запросу от приложения, например, для отображения пользовательских фотографий или пользовательских иконок.
Помимо основной функции менеджер ресурсов отвечает за смену языка системы. В корневом конфигурационном файле (resources/argo/system/argo_system.fml) прописывется список доступных языков, эта информация также обрабатывается менеджером. При объявлении ресурсных файлов могут может указываться атрибут lang со значением из этого списка. Ресурсы из этого файла (текстовые!) будут использоваться только в случае, когда соответствующий язык установлен в менеджере ресурсов. При этом в нескольких ресурсных файлах, для разных языков, идентификаторы ресурсов должны быть идентичны, а строковое значение соответствовать нужному языку. При использовании таких идентификаторов текст в пользовательском интерфейсе будет изменятся автоматически при смене языка. Менеджер также создает специальную автоматическую переменную LANGUAGE которая предназначена для сохранения значения текущего языка при перезагрузке системы и может быть использована для уведомления системных приложений о смене текущего языка.
Менеджер Данных
Менеджер данных предназначен для сохранения некоторых строковых, целочисленных, перечислимых данных, а также массивов для различных целей: обмена данными между приложениями, сохранения данных при перезагрузке системы, оповещения о событиях в системе и тому подобное. Другие типы данных (с плавающей точкой, например) пока поддерживаются не в полной мере.
По аналогии с менеджером ресурсов есть два домена для хранения данных: системные и данные приложений. Также, в целом, действуют и правила доступа к ним. Однако, есть и разница. Фреймворк создает две дополнительные базы данных - автоматическую и общую, это делается независимо от пожеланий разработчика системы.
Автоматическая база данных предназначена для хранения параметров системы, таких как количество дисплеев, язык системы и других внутренних данных. Переменные в этой базе имеют предустановленные имена (или формат имен) и доступны только для чтения системными приложениями. Пользовательские приложения читать их не могут (пока не могут, это будет пересмотрено). Разработчик системы может только сконфигурировать этот механизм, чтобы сохранять эти данные между перезагрузками системы или отключить это сохранение.
Общая база данных позволяет читать переменные любому приложению, но создавать и записывать переменные могут только системные приложения. Эти переменные, в первую очередь, предназначены для обмена данными между приложениями и посылки уведомлений. Общая база данных никогда их не сохраняет между перезагрузками системы.
Системные базы данных определяются в конфигурационном XML файле системы и предназначены для общей информации, нужной системным приложениям. Пользовательские приложения к ним доступа не имеют. Системные приложения могут записывать, читать или включать для себя уведомления от этих переменных. Также переменные могут сохраняться на файловой системе.
Базы данных приложений доступны только приложению и могут быть использованы для обмена данными для нескольких экземпляров приложения. Также могут сохранятся данные которые нужны после перезагрузки приложения.
Менеджер данных также поддерживает создание локальных баз данных по запросу от плеера. Эти данные создаются и используются плеером и недоступны извне.
Менеджер Файловой Системы
Менеджер файловой системы управляет доступом фреймворка и приложений к определенным директориям на файловой системе. Каждая такая директория представляется как некая виртуальная файловая система и так же будет отображаться в пользовательском интерфейсе. Список таких файловых систем определяется в конфигурационном XML файле.
Менеджер собирает информацию о файлах внутри таких директорий и предоставляет полную информацию по запросу от системных приложений. Пользовательские приложения эту информацию получить не могут (механизм еще не доработан, чтобы скрывать системные папки).
Менеджер создает две дополнительные виртуальные файловые системы:
- Систему для хранения системной информации (var), которая используется исключительно фреймворком для хранения внутренней информации (например, для хранения автоматической базы данных).
- Домашнюю папку (home) для размещения файлов приложений.
Создание и управление этими папками выполняется через системное XML описание.
Менеджер может получать и обрабатывать уведомления о подключении новых реальных файловых систем, например, USB диска. При получении уведомления менеджер зарегистрирует такую файловую систему, и она будет доступна приложениям. Также он обеспечивает уведомление для подписанных приложений, что файловая система была добавлена или удалена. Уведомление о подключении/отключении может быть отправлено только системным приложением. Нотификация о состоянии файловых систем тоже может быть доставлена только системному приложению.
Менеджер Событий
Фреймворк является системой, которая реагирует только на события от пользователя или от приложений. Сам по себе никаких событий (events) он не генерирует. Но поступившие события должны быть обработаны быстро и правильно. Для этой цели существует менеджер событий, который отвечает за передачу сообщений между модулями системы.
Это довольно простой модуль, шутка… Сам по себе модуль весьма прост, но, в целом, механизмы внутреннего мессаджинга не так тривиальны. Все модули-менеджеры объединены в единую сеть, которую и поддерживает менеджер событий. Модуль-передатчик создает тело сообщения и отсылает по адресу/идентификатору того модуля, куда он сообщение передает. Адресация, выбор, пересылка и доставка ответа полностью лежат на менеджере событий. Сообщения могут быть синхронными, т.е. происходит прямой вызов интерфейсов вызванного модуля (это используется редко) или асинхронными, когда событие попадает в очередь на обработку, и вызывающий модуль не блокируется. В последнем случае модуль-передатчик сам должен позаботиться о том, чтобы получить ответ, если ему надо.
С точки зрения приложений эти внутренние механизмы могут повлиять только на быстродействие. Разработчик системы может ограниченно влиять на эти процессы через конфигурационные параметры (резервирование памяти для очередей событий, например). С точки зрения разработчика приложений таких механизмов вообще нет.
Менеджер Тем
Как и во многих современных графических системах, во фреймворке есть механизм изменения графического представления с использованием механизма изменения темы. Тема включает в себя разнообразные параметры: общая цветовая гамма (светлая, темная, цветовая), общие ресурсы (управляющие элементы), элементы стиля окон и тому подобное. Элементы темы имеют фиксированные текстовые идентификатры, имена, которые могут использоваться как идентификаторы ресурсов (например, кнопки по умолчанию), цвета конкретного элемента (например, цвета рисованного виджета) и в других случаях. Основной список идентификаторов сам по себе фиксирован и не может быть изменен со стороны разработчика, но есть возможность добавления пользовательского элемента для разработчика системы. Этот механизм позволяет унифицировать представление приложения в рамках требований, т.е. приложение будет отображаться так, как требуется, без знания конкретных ресурсов системы. Это особенно полезно разработчикам сторонних приложений, которым, пользуясь фиксированным набором элементов, не надо знать о ресурсах конкретной системы, о которых сторонний разработчик и знать не может.
Менеджер ресурсов также позволяет выбирать ресурсы в соответствии с темой. В описание ресурсных файлов добавлен атрибут theme (так же как и существующий атрибут lang), который привязывает ресурсы к конкретной теме (как и lang привязывает ресурсы к языку системы). Системные приложения могут быть информированы о смене темы, используя автоматическую переменную THEME для соответствующего уведомления. Эта переменная также сохраняет значение текущей темы между перезагрузками системы.
Одна из тем явно или неявно маркируется как тема по умолчанию, она выбирается при первом запуске системы. Тема по умолчанию должна содержать определения всех параметров. Остальные темы могут определять не все параметры, при отсутствии определения параметр возмется из темы по умолчанию. Если параметр нигде не определен, то при его использовании система выдаст ошибку загрузки приложения.
На данный момент темы могут быть объявлены только в рамках системы, создание пользовательских тем пока не поддерживается. Для этого нужно расширение API менеджера и собственно создание приложения, которое позволит создать такую тему (может быть, это будет добавлено в приложение настроек).
Пока список параметров темы не документирован, но их имена и определения можно найти в файлах конфигурации системы: resources/argo/system/fs0/sysres/theme_res_blue.fml и resources/argo/system/fs0/sysres/theme_res_green.fml. Добавление файлов темы находится в корневом конфигурационном файле: resources/argo/system/argo_system.fml.
Менеджер Системных Сообщений
Менеджер системных сообщений в первую очередь предназначен для получения и обработки сообщений о каких-либо проблемах, связанных с запуском и последущей работой приложений. Также он получает сообщения об аварийной выгрузке приложения. Проблемы с запуском чаще всего связаны с отсутствием исполняемых бинарных файлов или динамических библиотек, невозможности найти функцию запуска (она всегда ищется с использованием dlopen/dlsym) или иных причин, препятствующих запуску приложения. Проблемы, связанные с работой приложений, связаны с ошибочным статусом вызова коллбэков приложения, это происходит при возврате любого ошибочного статуса, за исключением одного специального случая (статус FRMREJECT из suspend коллбэка - нужно чтобы заблокировать приостановку или выгрузку приложения). Наконец, приложение может выгрузится ненормально, с крэшем или по сигналу, в этом случае также отправляется сообщение, и происходит выгрузка приложения со стороны фреймворка.
Менеджер классифицирует пришедшее сообщение и делает соответствующие операции. Во всех случаях желательно, чтобы пользователь увидел сообщение о проблеме в пользовательском интерфейсе и сделал свой выбор, что делать дальше. Вывести сообщение об ошибке фреймворк самостоятельно не может (только в собственный лог), поэтому нужно специальное приложение-сервис, которое и выведет сообщение об ошибке на основании данных, предоставленных менеджером.
Это системное приложение регистрируется со специальным именем сервиса - sysalert (можно найти строчку service=“sysalert” в корневом конфигурационном файле resources/argo/system/argo_system.fml). При запуске системы сервис с таким именем будет зарегистрирован в менеджере сообщений, и менеджер будет отправлять сообщения об ошибках именно ему и получать от него информацию, что делать дальше. Например, при аварийной выгрузке приложения появляется выбор: принять как есть или попытаться перезагрузить приложение. В случае сбоя в работе коллбэков также есть выбор: продолжить работу приложения или выгрузить его.
Этот сервис на данный момент связан только с менеджером сообщений и не может получать сообщения непосредственно от других приложений. В дальнейшем это, возможно, будет сделано для вывода сообщений от приложений (сообщения об ошибках или информационные сообщения). Также, возможно, передача таких сообщений будет сделана через менеджер сообщений (через соответствующий API, которого пока нет).
Утилиты Фреймворка
Утилиты фреймворка это приложения, которые облегчают отладку приложений, API фреймворка и разработку ресурсов системы. В данный момент, это обычные консольные приложения запускаемые из командной строки Linux. В SDK доступны две утилиты: отладочный терминал (frmdbgterm) и генератор бинарных файлов (frmbingen). Ниже кратко рассматривается их назначение.
Отладочный Терминал
Отладочный терминал используется для управления системным отладочным приложением фреймворка (Debug Shell). Это приложение запускается автоматически при старте системы и предназначено для управления фреймворком “изнутри”. Оно способно выполнять различные операции с API фреймворка и очень полезно при отладке новых API и новых приложений. Некоторые функционалы фреймворка до сих пор доступны только через это приложение (например, создание новой категории приложений). При старте приложение реализует TCP/IP сервер к которому и подключается отладочный терминал. Подключение происходит каждый раз при запуске фреймворка, если фреймворк не запущен терминал ожидает сервер. Таким образом терминал можно запустить один раз, в отдельной консоли, и он будет переподключаться автоматически, каждый раз при запуске системы, при этом сохраняя всю историю команд (стрелочки вверх/вниз на клавиатуре очень полезны :))
Отладочный терминал при подключении считывает список доступных команд отладочного приложения и предоставляет пользователю возможность ввода команды в терминале и получения ответа на запрос. Например, текущий список команд:
WS$ frmdbgterm
Tue 22 Jul 2025: 14:06:16
-------------------------------------------------------------
Welcome!
Copyright (C) 2026 Andrey Dedukhin (adedukhin@gmail.com)
Framework Debug Terminal v1.0.0
dbgterm>
dbgterm>
Copyright (C) 2026 Andrey Dedukhin (adedukhin@gmail.com)
Framework Debug Shell Application v1.0.0
Press ENTER to continue
dbgshell> lscmd
List of Commands:
quit - Terminal: Debug terminal exit
help - Terminal: Print debug terminal help
info - Terminal: Print debug terminal and server info
history - Terminal: Print commands history. See help for options
lbstart - Terminal: Loopback server start
lbstop - Terminal: Loopback server stop
lscmd - Terminal: Print list of available commands
dbgshell - Server: Get debug shell application info
pid - Server: Get applications PID list
closeapp - Server: Close application by public ID
runapp - Server: Run applications using private ID or install name
wakeup - Server: Wake up application windows using public and/or private IDs
sysinfo - Server: Get system info content
appinfo - Server: Get application info content
shell - Server: Execute shell command
install - Server: Install application
uninstall - Server: Uninstall application
category - Server: Command to list, add and delete install categories
language - Server: Command to list available languages and set one of them
variable - Server: Command to control available databases and variables
theme - Server: Command to control available themes and set one of them
dispctl - Server: Command to view display info and set background
dbgshell>
Команды отмеченные как “Server”, это команды поддерживаемые отладочным приложением. Обычно у них много ключей для выполнения разных операций. Для получения справки можно использовать ключ -h:
dbgshell> pid -h
The 'pid' command is intended to get application info using public or private identifiers.
Command prints list of active and wait applications if no options set.
Usage:
pid [-h|-i] [-p identifier]
Options:
-h Print help message. Other command options are ignored.
-i Print applications install list if -p option not set.
Print application install info according to private ID defined by -p option.
-p Define public or private ID according to -i option presence (Public ID if option not set).
Examples:
Prints list of active and wait applications:
dbgshell> pid
Prints this message:
dbgshell> pid -h
Print application info according to public identifier:
dbgshell> pid -p 0x2001001
Print list of installed applications:
dbgshell> pid -i
Print application install info according to private identifier:
dbgshell> pid -i -p 0x1001002
Application List Flags:
1 [A|W] A - Active application. W - Wait application.
2 [B|F] B - Background application. F - Foreground application.
3 [C|S|U] C - Core application. S - Service core application. U - User application.
4 [S|D|R|W] S - Static mode. D - Dynamic mode. R - Remote mode. W - Remote wait mode.
Install List Flags:
1 [R|N] R - Active or wait application. N - Not run.
2 [B|F] B - Background application. F - Foreground application.
3 [C|U] C - Core application. U - User application.
4 [S|D|R|W] S - Static mode. D - Dynamic mode. R - Remote mode. W - Remote wait mode.
dbgshell>
Примеры использования команд можно найти на других страницах вики. Более подробное описание возможностей терминала и отладочного приложения находится на странице Утилиты Фреймворка.
Генератор Бинарных Файлов
Как следует из названия, эта утилита предназначена для создания бинарных описаний из FML описаний, но не только. Она может создавать бинарные описания шрифтов (в том числе, из TrueType шрифтов), выполнять другие операции со шрифтами (export, dump), а также генерировать бинарные файлы ресурсов и другие бинарные описания (управляющих элементов, приложений и системы).
Утилита активно используется в процедуре сборки фреймворка. Она использует специальные скрипты (bgs скрипты), которые помогают размещать ресурсные файлы на файловой системе при сборке. Скрипты также позволяют создавать требуемые бинарные описания, и это используется как для создания системных бинарных файлов (скрипты config/bingen.bgs и config/install.bgs), так и для создания бинарных файлов приложений. Скрипты могут использовать обычные команды shell-скриптов, но, в отличие от них, результат всегда проверяется. Также скрипты могут автоматически использовать переменные окружения фреймворка или создавать свои переменные. На других страницах википедии есть несколько примеров для написания скриптов. Можно посмотреть команду “frmbingen help” для деталей. Пока подробнее на этой утилите останавливаться не буду, но она играет очень важную роль в постройке фреймворка.
Программный интерфейс
Приложения фреймворка должны с ним взаимодействовать, начиная с процесса запуска приложения и заканчивая его выгрузкой. За все это отвечает программный интерфейс приложений. Программный интерфейс включает в себя корневой интерфейс - функции непосредственно библиотеки приложений, это основной интерфейс; функции интеграционного уровня - для взаимодействия с операционной системой (необязательно, но предпочтительно, по возможности); функции библиотек поддержки (support libraries) - самый употребительный и удобный интерфейс, это по сути удобные обертки для корневого интерфейса; и, наконец, специальные функции дополнений (supplementary) - их использование возможно и, возможно, даже желательно, но об этом ниже.
Ниже будет рассмотрено как применять перечисленные интерфейсы, и есть ли в том или ином варианте смысл.
Необходимо сразу внести ясность в важный вопрос. Приложения фреймворка НЕ ОБЯЗАНЫ следовать правилам, примененным к коду ядра. Они могут использовать сторонние функции, библиотеки, заголовочные файлы как угодно разработчику. Разработчики фреймворка не несут никакой ответственности за разработку приложений, кроме приложений, опубликованных в SDK. Применение сторонних API никак не возбраняется на уровне приложений, но приложения, не соответствующие правилам (стиль кодирования, отсутствие проверок на ошибки, непрозрачная логика приложений, применение нестандартных библиотек и заголовков, неправильное управление привилегиями и тому подобное), не будут интегрированы на этот ресурс.
Корневой Интерфейс - Библиотека Приложений
Функции библиотеки приложений - это самый короткий путь к интерфейсу фреймворка, но и самый сложный. Функции объявлены в заголовочном файле argo-sdk/target/include/frm_app_if.h в SDK. Их не так много, но, как правило, они выполняют множество операций в зависимости от параметров. За исключением некоторых функций, требуется ПРАВИЛЬНОЕ заполнение структур данных для выполнения соответствующего запроса. Данный подход связан с тем, что каждая функция использует свое, индивидуальное событие, а их лимит ограничен (лимит большой, но запас карман не тянет :)). Заполнение таких структур, в общем-то, формальная задача, но это приводит к серьезному усложнению кода приложений, структуры многоуровневые. Разумеется, некоторые функции часто используются прямо, без оберток, но это скорее исключение. Необходимые обертки добавляются в библиотеках поддержки (support libraries)
Библиотеки Поддержки
Библиотеки поддержки (пока их три: общая библиотека, библиотека редактора текстов и библиотека установки приложений) обеспечивают более удобный программный интерфейс, чем корневой интерфейс - они как раз реализуют требуемые функции-обертки для вызова корневого интерфейса. Функции объявлены в следующих заголовочных файлах: argo-sdk/target/include/frm_libapi_if.h, argo-sdk/target/include/frm_libeditor_if.h и argo-sdk/target/include/frm_libinstall_if.h. Реализация функций-оберток открыта - исходный код расположен в папке support в SDK и в рабочем пространстве. Использование, реализация оберток - это ваша полная прерогатива (но доработки будут под вопросом при интеграции в репозиторий). Делайте с ними что хотите, но и претензий не предъявляйте :). Разработки других библиотек-оберток будет приветствоваться, да и найденные ошибки будут исправлятся.
Для приложений на языке Python необходима динамическая линкуемая библиотека (DLL), ее код расположен в папке support/libapi/dll/. По сути, функции библиотеки это тоже обертки для функций корневого интерфейса и библиотек поддержки, они не несут своей логики. Это только интерфейс взаимодействия с приложениями на Python. Без этой библиотеки взаимодействие приложений на Python с фреймворком невозможно. Это связано с механизмом вызова функций “Си” из Python, это можно сделать только используя DLL.
Функции Интеграционного Уровня
Использование функций интеграционного уровня в приложениях сугубо опционально. Их не так много, чтобы закрыть все потребности разработки. Функции объявлены в файле argo-sdk/target/include/frm_integration_if.h. Они позволяют взаимодействовать с операционной системой безопасно, поскольку адаптированы под ОС, но их набор явно недостаточен для всех запросов. Интеграционный уровень обслуживает фреймворк, но не обязан обслуживать приложения. При необходимости можно добавить дополнительные интеграционные библиотеки и заголовочные файлы, но менять существующий интерфейс нельзя! Также интеграционный уровень содержит некоторый набор библиотек, которые могут быть полезны, например, библиотека логирования. Все приложения в той или иной мере используют макросы для логирования, реализация логирования делается как раз в этой библиотеке (все макросы объявлены в файле argo-sdk/target/include/frm_comdef.h).
Дополнительные Библиотеки
Приложения фреймворка могут использовать некоторые дополнительные библиотеки, API которых доступен. В частности речь идет о библиотеке libfrmsuppl.so (supplementary library). Код этой библиотеки закрыт, поскольку она широко используется ядром и утилитами фреймворка. Библиотека реализует такие компоненты как списки, древовидные списки, очереди и набор вспомогательных функций для работы со строками. Соответствующие заголовочные файлы: frm_list_if.h, frm_treelist_if.h, frm_queue_if.h и frm_strhelp_if.h. Использование этих функций возможно, но надо понимать, что они в первую очередь написаны для нужд фреймворка и дорабатываться специально для приложений не будут.