84
правкиИзменения
Нет описания правки
Application - приложение для системы [[AFW]]. Приложение это именно то, что взаимодействует с пользователем (драйвера, в отличие от приложений, обычно не взаимодействуют с пользователем, они работают с железом и приложениями или [[OS|операционной системой]]).
Приложение для AFW разрабатывалось таким, чтобы работать из [[ROM]]'а, поэтому может вообще не иметь глобальных переменных, все данные должны храниться в структуре приложения, в которой первой должна быть структура [[APPLICATION_T]]. Указатель на экземпляр текущего приложения передаётся в каждом обработчике событий, из которых , по сути , и состоит приложение. В приложениях из эльфов немного иначе, как минимум таблица ивентов регистрации должна быть в [[RAM]]'е, т.к. база ивентов выделяется динамически. В прошивке коды ивентов назначаются автоматически в процессе компиляции.
== Таблица [[Event|ивентов]] регистрации ==
Массив кодов ивентов на которые стартует приложение, регистрируется функция старта. Для эльфов это обычно один единственный ивент , код которого записывается в глобальной структуре [[ldrElf]].
== Регистрация ==
Приложение должно быть зарегестрировано зарегистрировано в системе [[AFW]], делается это функцией [[APP_Register]].
Регистрируется приложение один раз и удалить регистрацию её потом будет невозможно, а эльф обычно должен выгружаться из памяти, поэтому нужно исключить совпадение ивентов для выгружаемого эльфа, для этого используется функция [[ldrRequestEventBase]], которая каждый раз возвращает уникальный свободный код ивента который можно использовать как "свои" ивенты. Даже более, следующие 63 кода тоже свободны и никогда не встретятся. При регистрации система запоминает не ивенты, а адресс таблицы, а т.к. память эльфа может быть освобождена данные могут быть изменениы и это может быть источником глюков, от этого никуда не деться. Также после получения базы ивентов нужно провести инициализацию таблиц обработчиков ивентов, т.к. там используются не реальные коды ивентов.
Пример:
UINT32 reserve;
UINT32 status;
int i;
reserve = ldrRequestEventBase();
elf.app = NULL;
elf.evbase = reserve ++;
status = APP_Register( &elf.evbase, // указатель на первый элемент таблицы ивентов регистрации
1, // количество элементов в этой таблице
Параметры:
* ev_st - указатель на [[Event_Stack|стэк событий]].
* reg_id - идентификатор регистрации приложения. Когда приложение регистрируется , оно получает уникальный идентификатор регистрации, по которому его можно найти. По reg_id можно определить , что приложение с таким идентификатором уже запущено (см. [[AFW_InquireRoutingStackByRegId]]).
* reg_hdr - структура с данными, которые получены при регистрации приложениями.
В начале можно проверить, - вдруг это приложение уже папущено:
<pre>
if( AFW_InquireRoutingStackByRegId( reg_id ) == RESULT_OK ) {
=== Инициализация ===
На этой стадии нужно выделить память под структуру и провести инициализацию приложения. Все это делает функция [[APP_InitAppData]]. Параметры:
* адресс функции функция обработчика ивентов приложения. Лучше воспользоваться уже готовыми в прошивке функциями из прошивки - [[APP_HandleEvent]] для приложений использующих [[UIS|графический интерфейс]] или [[APP_HandleEventPrepost]] для фоновых.
* размер структуры приложения.
* идентификатор регистрации приложения.
APP_Start( ev_st, // указатель на стэк событий
&papp->apt, // указатель на структуру приложения
APP_STATE_INIT, // индеск индекс первого стэйта, в котором стартует приложение
state_handling_table, // таблица, описывающая все состояния приложения
AppExit, // функция выхода из приложения
== Таблица состояний ({{lang-en|states}}) ==
В один момент времени приложение в целом может находиться в одном из состояний, за исключением зарезервированного ANY под индексом 0. От стэйта зависит поведение приложения. Когда на стандартный обработчик событий приложением (задается первым параметром в [[APP_InitAppData]] при старте приложения) поступает ивент , он ищет код этого ивента в таблице обработчиков ивентов, которая записана под ANY стэйтом, если там не находит, то ищет в таблице под текущим стэйтом и вызывает обработчик события. Если обработчик ивента вернул чтото отличное от RESULT_OK вызывается функция выхода из приложения.
Одно состояние должно иметь:
* идентификатор. Задается через enum в заголовочном файле, при этом ANY_STATE под индексом 0.
EVENT_HANDLER_T *hfunc; // функция, которая обрабатывает ивент с этим кодом
} EVENT_HANDLER_ENTRY_T;</pre>
В эльфах в этих таблицах не используются реальные коды событий, поэтому после получения базы ивентов нужно инициализировать таблицы:
<pre>
int i;
for ( i=0; i<APP_STATE_MAX; i++ )
reserve = ldrInitEventHandlersTbl((EVENT_HANDLER_ENTRY_T *)state_handling_table[i].htable, reserve);
</pre>
[[Категория:Эльфостроение]]