Урок - Создание/редактирование простого эльфа (подробно) : Эльфостроение : Форум


 vodoo999:
05.11.09, 00:42
 Для создания эльфов нам потребуются: IAR, includes, _cpp.C, _cpp2.cpp - где все это взять? смотрим здесь и здесь. Пример эльфа HelloWorld - смотрим во вложениях.

И так приступим:

1) Открываем файл HelloWorld.eww в папке (файл находится в папке C:\IAR\Embedded Workbench 4.0 Evaluation\ARM\HelloWorld\ - если вы все сделали правильно как в этой теме). Происходит запуск IAR и появляется такое вот окошко:



2) Кликаем два раза левой кнопкой мыши (ЛКМ) на main.c. У вас должно окно IAR выглядеть так:


3) Вся работа с кодом эльфа происходит в окошке main.c:


4) Давайте просмотрим код нашего эльфа HelloWorld и посмотрим какая строчка за что отвечает:

Код: 
#include "..\\include\Lib_Clara.h"
#include "..\\include\Dir.h"

u16 timer; // ID таймера
int lamp=0; // текущая яркость лампы
BOOK * HWBook;

int TerminateElf(void * ,BOOK* book)
{
  FreeBook(book);
  return(1);
}

typedef struct
{
  BOOK * book;
}MSG;

int ShowAuthorInfo(void *mess ,BOOK* book)
{
  MSG * msg = (MSG*)mess;
  MessageBox(0x6fFFFFFF,STR("Hello Wordl!\n\nExample elf.."),0, 1 ,5000,msg->book);
  return(1);
}

const PAGE_MSG HW_PageEvents[]@ "DYN_PAGE" ={
  ELF_TERMINATE_EVENT , TerminateElf,
  ELF_SHOW_INFO_EVENT  , ShowAuthorInfo,
  0,0
};

PAGE_DESC base_page ={"HW_BasePage",0,HW_PageEvents};


void elf_exit(void)

{
  kill_data(&ELF_BEGIN, (void(*)(void*))mfree_adr());
}

void onTimer (u16 unk , void * data)
{
  {
    // перезапускаем таймер
    Timer_ReSet(&timer,500,onTimer,0);
    // переключаем лампу
    SetLampLevel(lamp^=0x10);
  }
}

void onCloseHWBook(BOOK * book)
{
  if (book)
  {
    Timer_Kill(&timer);
    StatusIndication_ShowNotes(0x6FFFFFFF);
    SetLampLevel(0);
    SUBPROC(elf_exit);
  }
}

BOOK * CreateHWBook()
{
  HWBook= new BOOK;
  CreateBook(HWBook,onCloseHWBook,&base_page,"Example",-1,0);
  return(HWBook);
}

int main (void)
{
  CreateHWBook();
  // выводим текст в "заметки" на StandBy
  StatusIndication_ShowNotes(STR("Hello World!"));
  // запускаем таймер на 0.5 сек.
  timer=Timer_Set(500,onTimer,0);
  return(0);
}


5) Символами "//" мы можем комментировать строчки в самом коде эльфа.

6) Постараемся провести разбор каждой строчки:

#include "..\\include\Lib_Clara.h"
#include "..\\include\Dir.h"


- "инклуды" - файлы Lib_Clara.h и Dir.h из которых берутся функции для нашего эльфа. По умолчанию находятся здесь - C:\IAR\Embedded Workbench 4.0 Evaluation\ARM\Include\ (папка куда вы установили IAR).

Файлы Lib_Clara.h и Dir.h можно самостоятельно просмотреть, открыв их блокнотом.

Внимание! Важно следить за обновлением папки Include! Иначе, возможно, что у вас будет не полная библиотека функций Lib_Clara.h и вы не сможете написать эльф, т.к. необходимых функций в ней не будет. Обновляем папку Include, а также файлы _cpp.C, _cpp2.cpp с сайта http://perk11.info/svn/SE/ - папки include и C++ соответственно.

7) Строчки -

#include "..\\include\Lib_Clara.h"
#include "..\\include\Dir.h"


должны быть в каждом эльфе! Из них берутся функции, как к примеру эта:

StatusIndication_ShowNotes(STR("Hello World!"));


- функция показа на главном экране (ГЭ) заметки с выбранным тестом - в данном случае на вашем ГЭ (если вы скомпилируете на компьютере и запустите эльф на телефоне) появится заметка с сообщением с текстом "HelloWorld".

8) Строчки -

u16 timer; // ID таймера
int lamp=0; // текущая яркость лампы
BOOK * HWBook;


также должны быть в каждом эльфе. Функция запускает таймер на определенное время, по истечении которого будет выполнено необходимое действие (более подробно =timer&s[]=set]здесь).

9) Строчки -

int TerminateElf(void * ,BOOK* book)
{
FreeBook(book);
return(1);
}

typedef struct
{
BOOK * book;
}MSG;

int ShowAuthorInfo(void *mess ,BOOK* book)
{
MSG * msg = (MSG*)mess;
MessageBox(0x6fFFFFFF,STR("Hello Wordl!\n\nExample elf.."),0, 1 ,5000,msg->book);
return(1);
}

const PAGE_MSG HW_PageEvents[]@ "DYN_PAGE" ={
ELF_TERMINATE_EVENT , TerminateElf,
ELF_SHOW_INFO_EVENT , ShowAuthorInfo,
0,0
};

PAGE_DESC base_page ={"HW_BasePage",0,HW_PageEvents};


void elf_exit(void)

{
kill_data(&ELF_BEGIN, (void(*)(void*))mfree_adr());
}



void onTimer (u16 unk , void * data)
{
{
// перезапускаем таймер
Timer_ReSet(&timer,500,onTimer,0);
// переключаем лампу
SetLampLevel(lamp^=0x10);
}
}

void onCloseHWBook(BOOK * book)
{
if (book)
{
Timer_Kill(&timer);
StatusIndication_ShowNotes(0x6FFFFFFF);
SetLampLevel(0);
SUBPROC(elf_exit);
}
}

BOOK * CreateHWBook()
{
HWBook= new BOOK;
CreateBook(HWBook,onCloseHWBook,&base_page,"Example",-1,0);
return(HWBook);
}


отвечают за поддержку эльфа Букменеджером (BookManager). Если этих строк нее будет - вы не увидите свой эльф в Букменеджере и не сможете "убить" эльф Букменеджером. Остановимся поподробнее:

а) строка

MessageBox(0x6fFFFFFF,STR("Hello Wordl!\n\nExample elf.."),0, 1 ,5000,msg->book);


отвечает за информацию о названии и создателе эльфа ("About") в Букменеджере. Смотрим скриншот с экрана телефона:



Если мы хотим изменить информацию о создателе эльфа - правим строку Hello Wordl!\n\nExample elf.

\n\n - отвечает за перенос строчки

К примеру, напишем так: My Elf!\n\n© vodoo999

Строчка теперь выглядит так:

MessageBox(0x6fFFFFFF,STR("My Elf!\n\n(c) vodoo999"),0, 1 ,5000,msg->book);


После компиляции и запуске эльфа на телефоне мы получим в Букменеджере следующую надпись:



б) строки

void elf_exit(void)

{
kill_data(&ELF_BEGIN, (void(*)(void*))mfree_adr());
}


- отвечают за терминацию ("убийство") нашего эльфа Букменеджером. Должны быть всегда в коде эльфа! Иначе мы не сможем выгрузить наш эльф из памяти телефона (поможет только перезагрузка).

в) строка

CreateBook(HWBook,onCloseHWBook,&base_page,"Example",-1,0);


отвечает за создание "книги" (Book), а также и за поддержку Букменеджера:



Мы также можем править эту строчку, изменяя название нашего эльфа. К примеру так - мы хотим чтобы наш эльф назывался HelloWorld - пишем:

CreateBook(HWBook,onCloseHWBook,&base_page,"HelloWorld",-1,0);


Смотрим на скриншот:



10) Строчки -

int main (void)
{
CreateHWBook();
// выводим текст в "заметки" на StandBy
StatusIndication_ShowNotes(STR("Hello World!"));
// запускаем таймер на 0.5 сек.
timer=Timer_Set(500,onTimer,0);
return(0);
}


основные строчки.

Функция main (void) самая главная и в неё обычно вставляют обработчики клавиш и событий, функции которые необходимо запустить при старте эльфа и другие.
(с) arban
- лучше я бы не написал.

Т.к. у нас эльф простенький - в нем присутствует только одна функция -

StatusIndication_ShowNotes(STR("Hello World!"));

Как я уже писал - функция StatusIndication_ShowNotes(STR("Hello World!")); отвечает за создание и показ заметок на ГЭ с вашим текстом (в нашем примере - по умолчанию стоит текст Hello World!).

Вот что мы видим после запуска эльфа на нашем ГЭ:



Мы можем менять текст Hello World! на какой угодно:
к примеру на такой - Я написал эльф! Ура!

Получаем такой текст на ГЭ:



11) Теперь самое главное - мы после, всех проделанных операций, в программе IAR в окошке main.c должны получить следующий текст:

Код: 
#include "..\\include\Lib_Clara.h"
#include "..\\include\Dir.h"

u16 timer; // ID таймера
int lamp=0; // текущая яркость лампы
BOOK * HWBook;

int TerminateElf(void * ,BOOK* book)
{
  FreeBook(book);
  return(1);
}

typedef struct
{
  BOOK * book;
}MSG;

int ShowAuthorInfo(void *mess ,BOOK* book)
{
  MSG * msg = (MSG*)mess;
  MessageBox(0x6fFFFFFF,STR("My Elf!\n\n(c) vodoo999"),0, 1 ,5000,msg->book);
  return(1);
}

const PAGE_MSG HW_PageEvents[]@ "DYN_PAGE" ={
  ELF_TERMINATE_EVENT , TerminateElf,
  ELF_SHOW_INFO_EVENT  , ShowAuthorInfo,
  0,0
};

PAGE_DESC base_page ={"HW_BasePage",0,HW_PageEvents};


void elf_exit(void)

{
  kill_data(&ELF_BEGIN, (void(*)(void*))mfree_adr());
}

void onTimer (u16 unk , void * data)
{
  {
    // перезапускаем таймер
    Timer_ReSet(&timer,500,onTimer,0);
    // переключаем лампу
    SetLampLevel(lamp^=0x10);
  }
}

void onCloseHWBook(BOOK * book)
{
  if (book)
  {
    Timer_Kill(&timer);
    StatusIndication_ShowNotes(0x6FFFFFFF);
    SetLampLevel(0);
    SUBPROC(elf_exit);
  }
}

BOOK * CreateHWBook()
{
  HWBook= new BOOK;
  CreateBook(HWBook,onCloseHWBook,&base_page,"HelloWorld",-1,0);
  return(HWBook);
}

int main (void)
{
  CreateHWBook();
  // выводим текст в "заметки" на StandBy
  StatusIndication_ShowNotes(STR("Я написал эльф! Ура!"));
  // запускаем таймер на 0.5 сек.
  timer=Timer_Set(500,onTimer,0);
  return(0);
}




12) Приступаем к компиляция (созданию эльфа). Для того чтобы программа IAR скомпилировала ваш эльф, из строчек которые вы написали в окошке main.c, необходимо нажать клавишу "F7" на вашей клавиатуре. Если вы все сделали правильно, то окно IAR должно выглядеть так (после нажатия "F7"):



Обращаем внимание на окошко Messages:
если вы все сделали правильно то кол-во ошибок и предупреждений будет "0" -



13) Наш созданный эльф будет лежать в папке Exe (C:\IAR\Embedded Workbench 4.0 Evaluation\ARM\HelloWorld4\Release\Exe\) и будет иметь название main.elf.

Для того, чтобы изменить название эльфа (не main.elf, а к примеру - Hello_World_main.elf) перед компиляцией (нажатием "F7") необходимо в IAR нажать сочетание клавиш "Alt+F7", в Category выбрать Linker, поставить галочку Override default и написать имя своего будущего эльфа:



Повторюсь, после нажатия "F7" (компиляции, создания эльфа) - ваш созданный эльф будет лежать в папке по умолчанию C:\IAR\Embedded Workbench 4.0 Evaluation\ARM\HelloWorld4\Release\Exe и иметь название Hello_World_main.elf

Спасибо arban - за инструкцию, UltraShot, arban, Alex_E - за помощь.

PS: В следующем уроке мы поговорим о том, как добавить в наш эльф код-защиту от многократного запуска (запуск нескольких копий) эльфа.

[ Редактировано vodoo999 в 5.11.09 00:01 ]

Прикрепленный к сообщению файл:

HelloWorld.zip HelloWorld.zip (48.68 kb; 53 hits) Скачать файл
Urok_1.zip Urok_1.zip (1799.61 kb; 31 hits) Скачать файл

 yr4ik:
05.11.09, 01:12
 vodoo999,
А суть этого фака научить юзеров менять копирайты в исходниках???)))
Для написание эльфов самый полезный мануал находится в wiki. А розжовывать новичкам хелов ворд - я думаю не стоит. Им все это нужно самим понять иначе толку не будет.

 vodoo999:
05.11.09, 01:16
 yr4ik писал:
vodoo999,
А суть этого фака научить юзеров менять копирайты в исходниках???)))
Для написание эльфов самый полезный мануал находится в wiki. А розжовывать новичкам хелов ворд - я думаю не стоит. Им все это нужно самим понять иначе толку не будет.

я постарался как можно подробнее описать))) копирайты я вроде не нарушал

yr4ik - завтра подправлю Урок, спасибо

[ Редактировано vodoo999 в 5.11.09 00:35 ]

 yr4ik:
05.11.09, 01:22
 И еще. Есть пару замечаний:
1)
Код: 
void onCloseHWBook(BOOK * book)
{
if (book)
{
Timer_Kill(&timer);
StatusIndication_ShowNotes(0x6FFFFFFF);
SetLampLevel(0);
SUBPROC(elf_exit);
}
}

Эти строки отвечают за терминацию ("убийство") нашего эльфа Букменеджером.

2)
Код: 
8) Строчки - 

u16 timer; // ID таймера
int lamp=0; // текущая яркость лампы
BOOK * HWBook;

также должны быть в каждом эльфе.

Я бы так не сказал что они должны быть в каждом эльфе. Это переменные. В каждом эльфе они задаются по своему. Например int lamp=0; - это глобальная переменная нужна лиж для установки а также проверки яркости лампы. BOOK * HWBook; - ожвучили HWBook как BOOK .



[ Редактировано yr4ik в 5.11.09 00:24 ]

 xaBaz:
05.11.09, 17:01
 Фига себе, это же как раз то что доктор прописал. Спасибо, vodoo999


Добавлено 5.11.09 17:22

С вашего разрешения влезу в эту тему с парой глупых вопросов.


1. Если эльфы пишутся на C, то что в проекте делают файлы с расширением *.cpp?

2. Что это за либы под main.c? Как они там оказались, ведь в коде мы инклудили только Lib_Clara.h и Dir.h?



3. Я в svn находил проекты в которых отсутствует main.c, и вообще файлы с этим расширением. Интересно будет почитать о том как устроены они.

4. Что это за полезный мануал, который находится в wiki? Я не встречал на него ссылки, поделитесь upd: нашел

ПС к эльмакерам которые против разжевывания hello world: к сожалению мемберы у которых возникает желание написать что нибудь полезное возможно видят Си впервые в жизни (как например я), и очень трудно самостоятельно разобраться во всех тонкостях, приходится открывать темы "по созданию эльфов" и наслаждаться пятидесятистраничным флеймом.
Например мне до сих пор невдомек, почему в эльфе Hello World рассматривается работа с фонариком :oops:

[ Редактировано xaBaz в 5.11.09 17:23 ]

[ Редактировано xaBaz в 5.11.09 17:23 ]

[ Редактировано xaBaz в 5.11.09 21:18 ]

 UltraShot:
05.11.09, 17:25
 
1. Если эльфы пишутся на C, то что в проекте делают файлы с расширением *.cpp?

Эльфы пишутся на C++. Хотя можно выбрать язык в настройках проекта

Что это за либы под main.c? Как они там оказались, ведь в коде мы инклудили только Lib_Clara.h и Dir.h?

Lib_Clara.h инклудит ещё множество файлов, они тут тоже показываются

3. Я в svn находил проекты в которых отсутствует main.c, и вообще файлы с этим расширением. Интересно будет почитать о том как устроены они.

main.c не особо и нужен. Функцию-энтрипоинт можно выбрать в настройках проекта.

Для новичков полезны шаблоны эльфов из темы "Создание эльфов". С их помощью можно автоматически всё настроить в проекте именно так, как надо. Остаётся только код писать.

 vodoo999:
05.11.09, 21:27
 UltraShot, yr4ik - стоит ли мне продолжать или уроки не совсем "правильные"? Скажем так, я пока что не достиг достаточного уровня в эльфостроении - постарался расписать элементарщину, но многие и такому рады (xaBaz). Ведь начинать надо с простого и потихонечку усложнять процесс. Еще один урок
PS: В следующем уроке мы поговорим о том, как добавить в наш эльф код-защиту от многократного запуска (запуск нескольких копий) эльфа.
- честно не так уж там много кода и до урока не дотягивает. Вопрос ребром - продолжать или нет? - продолжение следует =)

xaBaz писал:
Например мне до сих пор невдомек, почему в эльфе Hello World рассматривается работа с фонариком
- это какой например? если ты про урок от arban - то эльфа, типа HelloWorld - первые (самые простые на которых учат и объясняют) попытки в эльфостроении и программировании в целом. arban показал как можно создать простой эльф фонарик - потому и HelloWorld (я так понял - если не правильно - поправьте).


[ Редактировано vodoo999 в 7.11.09 21:46 ]

 Pavlus:
18.07.10, 21:17
 Ещё бы кто объяснил значение строк
Код:
int isMyElfBook(BOOK * book){
//return 0==strcmp(book->xbook->name,BookName);
  if(!strcmp(book->xbook->name,BookName)) return(1);
return(0);
}

и зачем нам нужна структура MSG:
Код:

 typedef struct
{
  BOOK * book;
}MSG;


первое я кажется понял, это типа назначение евентлистенеров, а второе это инициализация существующего поля для BOOK? Как его можно использовать? И почему можно вызывать функции с единым BOOK'ом в аргументах без аргументов?

URL этой темы:
https://mobilefree.justdanpo.ru/newbb_plus/viewtopic.php?topic_id=4446

© 2005-2018 supertrubka.org