разработка простого приложения под Flipper Zero

разработка простого приложения под Flipper Zero

с1t1zen

Разработка простого приложения под flipper zero


Привет! В этой статье я хочу начать цикл статей относительно разработки приложений под flipper zero . Я решил разобрать тему разработки поскольку флиппер есть у большинства людей из технической тусовки и он приколен воможностью пилить свои проекты на его основе.

Но сперва давайте покопаемся в истории и внутреностях)))

выделены основные компоненты флиппера

синий цвет контроллер

красный цвет rfid

зеленый и черый nfc

самый первый прототип
дев кит

Одним из плюсов флиппера является то что он мощнеее других МК и на нем имеется встроенная система FREE RTOS и 2 ARM ядра. Особенностью встроенной системы является многопоточность.Которая позволит увеличить повысить функционал проета Начнем с разработки самого приложения, оно будет написано на языке С и будет выводить hello world. (конечная прошивка лежит здесь

https://gitlab.com/noobcoder-oct/flipper_test_app )

long helloworld_app(void* p) {

return 0;

}

extern int32_t helloworld_app(void* p);

{.app = helloworld_app, .name = "hello world", .stack_size = 1024, .icon = &A_Pluggins_14}

Гуд давайте разбиратья как все это работает. Верхние 3 строчки создают само приложение, их надо закинуть в файл .с и закинуть в flipperzero-firmware/applications

следующая строка объявляние имени главной функции. И последняя строка название пункта меню app — это имя функции-точки входа в приложение, .name — имя в меню, .stack_size — размер стека для приложения .icon — иконка для меню. В главном меню иконки обязательны, поэтому NULL-ом обойтись не получится, и я взял иконку у соседнего приложения а именно pluggins/

#include <furi.h>
#include <furi-hal.h>
#include <gui/gui.h>

int32_t helloworld_app(void* p) {
    ViewPort* view_port = view_port_alloc();
    Gui* gui = furi_record_open("gui");
    gui_add_view_port(gui, view_port, GuiLayerFullscreen);

    delay(2000);

    gui_remove_view_port(gui, view_port);
    furi_record_close("gui");
    view_port_free(view_port);
    return 0;
} 
То, что в нем делается, довольно просто: сначала создаем ViewPort — это такая структура, в которую записываются указатели на коллбеки отрисовки экрана и получения эвентов от пользователя, потом вызываем furi_record_open, получая структуру Gui — говорим операционной системе, что у нас тут есть есть некоторый интерфейс и мы его хотим показывать, потом добавляем в полученный Gui созданный ViewPort, ждем две секунды, освобождаем все ресурсы и выходим.
typedef struct {
    Gui* gui;
    ViewPort* view_port;
} helloworldApp;
Как я уже говорил, для вывода чего-то на экран служит функция коллбека, которую вызывает тред Gui. Функция выглядит вот так:
void helloworld_draw_callback(Canvas* canvas, void* ctx) {
    canvas_set_font(canvas, FontPrimary);
    canvas_draw_str(canvas, 2, 15, "hello world");
} 

Она вызывается с двумя аргументами — первый это canvas, на котором мы собственно, и что-то рисуем/пишем, второй служит для передачи туда каких-нибудь дополнительных данных, т.к. как эта функция, хоть и лежит в приложении, де-факто будет выполняться внутри треда Gui, который ее вызвал, и не будет иметь доступа к данным приложения. Поэтому вторым аргументом туда передается контекст приложения — например, та самая структура CounterApp или какая-нибудь другая с данными, которые должны быть отрисованы.

Что делаем дальше — понятно по названиям функций. Устанавливаем шрифт и по координатам 2:15 выводим этим шрифтом надпись. Осталось указать эту функцию в качестве коллбека для отрисовки. Для этого где-нибудь в конце counter_app_alloc вызываем функцию view_port_draw_callback_set вот так:

view_port_draw_callback_set(app->view_port, helloworld_draw_callback, app);
Первый аргумент — это обьект вьюпорта, второй — непосредственно коллбек, а третий — тот самый контекст, который появляется во втором аргументе коллбека. Я туда уже положил app, хоть он в коллбеке никак еще не используется. Еще для каждой отрисовки надо вызывать функцию view_port_update, которая сообщает треду о том, что надо запросить коллбек, когда у треда интерфейса будет время, но в данном случае ее вызывать не обязательно — после регистрации коллбека он будет в первый раз вызван автоматически. 
Итог: 
Я еще буду заниматься данной прошивкой и думаю в дальнейшем выйдет еще часть про мою еблю с флиппером, так как у меня нет достаточного опыта в програмировании под free RTOS, и я че то вычрал лишь благодаря локументации и ствтьям других ребят, которые умнее меня и пилили уже свои приложения. 
Что пнравилось лично мне : во первых я понял примерный алгоритм написания приложения под флиппер 
во вторых я улучшил свои навыки владения RTOS, я не собираюсь опускать руки и в дальнейшем думаю смогу чо нить высрать ищо. 
P.S это была самая первая моя заметка)) позже я узнал, про то что можно было бы просто напечатать хелло ворлд через printf(). 
C1t1zen 
s4n6c7u4ry_labs


Report Page