Flipper zero инструкция на русском

Не так давно, примерно год назад я наконец получил свою долгожданную посылку. Flipper Zero. Для тех кто не знает, Flipper Zero — это небольшое устройство, которое позволяет заниматься всякими весёлыми затеями в жизни. Веселье начинается с Sub-1 GHz антенны и продолжается микро-скриптами для ПК. Интересующихся, прошу под кат.

Ваше знакомство буду выполнять в хронологическом порядке разделов в меню самого флипера.

Приложения

Я бы не стал выбирать самым основным пунктом данный, так как задача флипера, на мой взгляд, работа с физическим миром вокруг нас, а не программные приколюхи внутри устройства. Как устройство по работе с приложениями — флипер не лучший вариант. Я бы рекомендовал использовать Raspberry Pi или на худой конец Arduino.

Тем не менее, внутри достаточно много приложений уже написанных прекрасными пользователями интернета. Скажу сразу, я установил себе кастомную прошивку DarkFlipper. Об этом позже.

Из предустановок — 8-битные игры типа DOOM, надстройки для распиновки GPIO, аудио-проигрыватель, калькуляторы и доп. приложения и доп. приложения для антенны в 1 ГГц.

Повторюсь, данный раздел совсем не самый интересный.

Sub-GHz

Тут всё просто. В диапазоне от 300 до 928 МГц в AM и FM модификациях можно сканировать все сырые и не сырые данные.

Для тех, кто не очень понимает зачем, могу привести простой пример — коды шлагбаумов. В данном диапазоне передаются данные в шлагбаумы. Как пример, я смог скопировать свой ключ от шлагбаума. Любых шлагбаумов и ворот.

Как это можно реализовать? Расскажу свою историю. Я живу в центре города, где есть такое поверие: «нет шлагбаума — нет парковки». Живя в уникальном, не побоюсь этого слова, доме, где в один небольшой двор размером с небольшой «плевочек» с детской площадкой и местом для парковки примерно на 30 машин установили аж 3 шлагбаума. Три, Карл!

Боль данного пункта заключается в том, что шлагбаумы были установлены трёх разных фирм, трёх разных диапазонов, да ещё и двух типов закрытия. Будучи законопослушным гражданином, я решил запросить данный пульт для парковки своего авто. Позвонив по номерам, которые были упорно замазаны на шлагбауме, я попал не много, не мало в город Реутов (сам нахожусь я в Москве). Там, мне сказали, что сделать можно, но без физического ключа — ничего не получится. На вопрос где его добыть, я получил неутешительный ответ: «Не знаю». Месяц поисков и чудом я выяснил у соседей, что данный ключ находится у «старшей по подъезду» (рубрика «Центр Москвы»). Старшая по подъезду переехала, а подъезд остался. Не ленясь, я дозвонился до данной хозяйки медного шлагбаума. Выяснилось, что данные три шлагбаума были установлены до закона о централизованной установке шлагбаумов и каждый подъезд поставил то что хочет и то как хочет данный аппарат. Каждый шлагбаум — совместная собственность, где все бумаги носит при себе старшая по подъезду. Цирк продолжился. Требования для получения заветного ключа были следующие:

  1. Заплатить 7 тысяч рублей за вызов бригады (оно и понятно, из Реутова-то ехать)

  2. Купить резидентную парковку для бесплатной парковки в районе дома, что стоило 3 тысячи рублей в год. Она у меня была, так как ставить машину у дома я не мог.

  3. Отдать «на сканирование в архив» старшей по подъезду, проживающей в другом доме все документы на машину и меня.

Если первые два пункта были хотя бы понятны и хоть на сколько-то разумны (хотя сейчас резидентной парковки сейчас у меня нет, так как ставя машину в дворовой территории, она не нужна), то последний пункт меня возмутил. И я бы не против был бы и купить за 10 тысяч «ключик от домика», даже был бы не против купить данную подписку у женщины, которая поставила данный шлагбаум, ведь благодаря ней, во дворе уменьшилось количество такси и сторонних машин. Но вот отдавать документы куда-то в другой дом незнакомому человеку, как-то не хотелось. Я любезно отказался от данного предложения.

Шаг в сторону парковки подарила мне компания Прайм Пульт. Вопрос решился просто.

Кто не понял — это ключ, который копирует сигнал. Нужно было просто понять в каком диапазоне работает ключ. Цена вопроса за 10 ключей была 3 тысячи рублей.

Зная фирму производителя (в моём случае Nice Flor-S), можно узнать герцовку данного производителя (в моём случае 433,92 МГц). Далее — всё просто.

Флиппер же помог мне сделать то же самое, но не в отдельном шлагбауме, а на всех трёх простым чтением сырых (RAW) данных. Также, в кастомной прошивке есть подбор ключей по диапазону (приложение находится в отдельной папке в меню Applications).

125 кГц RFID

Переводя с русского на русский, данный раздел нужен для чтения ключей и смарт карт доступа.

Ключики на 125 кГц

Ключики на 125 кГц

Данные ключи сейчас активно используются в новостройках для открытия балконов или (простите) комнат для мусора. В многих учреждениях, открывается турникеты для входа в помещения.

Я работаю в университете и у нас такие же ключи доступа. Как прочитать её — просто. Нажать кнопку «Read» и положить её под флипер. Примерно так:

NFC

Аналог ключей, но с большей защитой. Бывает два типа защиты — PSK. В нём — всё также как и в 125 кГц ключах.

Второй вариант — ASK.

Тут нужно сделать 2 пункта — записать ключ и считыватель. Мужчина на видео по ASK — создатель флипера Павел Жовнер @zhovner

Инфракрасный порт

Инфракрасный излучатель позволяет управлять всем с ИК-приёмником. Тут справится даже ребёнок. Выбираем универсальный пульт:

Затем, выбираем конкретный тип прибора:

Далее, переворачиваем флипер, так чтобы сверху оказался ИК-передатчик и после нажатия на кнопку — отправляются все типы ИК-сигналов.

GPIO

Жаба меня задушила купить Wi-Fi модуль для флипера. По нему не смогу ничего рассказать. Спасибо YouTube за контент.

Как дополнение, распиновка:

iButton

Под надписью iButton спрятался сканнер ключей. Работает всё просто. Сканируем ключ на + и — к разным выпирающим точкам:

Далее, эмулируем их же и подносим к домофону:

Bad USB

Мой любимый раздел. По умолчанию, доступно всего 2 демо для Mac и Windows. Так как сижу на винде, скриншот вывода:

Конечно, этим всё не заканчивается. Далеко не заканчивается. Из моих любимых уже готовых скриптов под винду на PowerShell — разработка от Jakoby. Там много различных вариаций использования от простой смены обоев, до Wi-Fi стиллера.

U2F

Двухфакторная аутентификация возможна и на флипере. Всё что нужно — подключить его без утилиты qFlipper.

К слову про qFlipper. Приложение можно скачать здесь. Смысл приложения прост — работа со сторонним устройством (ПК или же телефоном). Также есть работа через блютуз.

Десктопное приложение

Десктопное приложение

Мобильное приложение

Мобильное приложение

Часы и настройки

Тут что-то добавить сложно. Часы необходимы, если хотите узнать время, а в настройках можно доработать ваш флипер.

Прошивки

Из моих фаворитов кастомных прошивок — DarkFlippers.

На мой взгляд, данная прошивка самая стабильная из кастомных. Изменений довольно много. Все они описаны по ссылке на репозиторий гитхаба.

Второй крутой вариант — вариант от TalkingSasquach. Там также есть крутые обои такого типа:

Где, что и как купить?

Сейчас с поставками флипера сложности. Я свой флипер получил спустя почти год после его официального выхода, как пользователь поддерживающий проект на кикстарте. В комплекте: коробочка, USB type-C, стикер и инструкция по быстрому старту.

Сам флипер, как сказано в официальном телеграмм-канале Павла, купить можно через Joom. Всё остальное (чехол, Wi-Fi модуль, плату) можно купить в Амперке.

А кому оно надо?

Как итог моего использования, могу сказать следующее (учтите, это только моё мнение): устройство прикольное, но нужно «понимающим» пользователям или тем, у кого много ключ-карт и всякого рода пультов.

В реальной жизни я использовал флипер порой и веселее включая кондиционеры и проекторы в кабинетах, где оно всё терялось. Ну и конечно, убивалка времени — классная. Лично для меня — устройство очень удобно и главное — приятно. Однако, есть два момента. Первый — я гик и кайфую с этого. Второй — купил я устройство в хорошие годы за 8 000 — 10 000 тысяч рублей (в зависимости от курса банка за евробаксы). Особые весельчаки взламывают лючки теслы.

Потенциал у устройства есть. Об этом потенциале говорит Линус Себастьян (канал Linus Tech Tips). По мнению Себастьяна, Flipper Zero — это на самом деле это один из самых универсальных хакерских инструментов, которые когда-либо появлялись на рынке.

Как всегда, выбор остаётся за вами. Я же пойду дальше юзать свой флипер и играться с новыми и новыми прошивками.

А вы как относитесь к флиперу?

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Как вам Flipper Zero?


18.83%
Купил. Топ за свои деньги!
87


7.79%
Купил. Круто, но хотелось бы подешевле
36


1.95%
Купил. Не доволен.
9


51.08%
Не покупал. Коплю и/или жду цену в 200 рублей.
236


20.35%
Не покупал и не буду
94

Проголосовали 462 пользователя.

Воздержались 84 пользователя.

3 лайфхака Flipper Zero, чтобы удивить своих друзей (и как они работают)

21 октября 2022 г.

Flipper Zero, помимо встроенной Змеи по умолчанию и дружелюбного аватара дельфина, представляет собой

невероятно мощное маленькое устройство
. Точно описанный
как многофункциональный инструмент для гиков, он обеспечивает несколько диапазонов частот RFID, Bluetooth,
радиосвязь ниже 1 ГГц, контакты GPIO для отладки, USB для выполнения

BadUSB

атаки, инфракрасный порт и даже разъем для перехвата и имитации ключей iButton.

Это не совсем похоже на взлом Watch Dogs, но это самое близкое, что я нашел, и с небольшой подготовительной работой
и некоторыми очень простыми трюками вы можете легко убедить своих друзей, что это граничит с магией.

:::предупреждение
Предупреждение. Теоретически возможно использовать взломы и Flipper Zero в гнусных целях, включая
приемы, описанные в этой статье. Но знаешь… не делай этого. Приемы, которые я описываю в этой статье, предназначены
только для забавы и развлекательных целей и представляют собой базовые приемы для начинающих, призванные
проиллюстрировать лежащие в основе протоколы и их слабости.

:::

Взлом Flipper Zero:

  1. Угнать за 60 секунд
  2. Познакомьтесь с музыкой
  3. Запасной ключ

1. Угнать за 60 секунд

:::предупреждение
Предупреждение. Не угоняйте автомобили. Это незаконно и, как правило, плохая идея (хотя я
использовал это, когда ключ от машины был заперт, заставляя свою вторую половинку взять ключ от ее ключа на
расстоянии 50 миль, отправить его мне по электронной почте и воспроизвести его, чтобы войти).

:::

n Это
отличный старт (умный каламбур), чтобы убедить людей, что вы полностью погрузились в научно-фантастический хакер,
несмотря на то, что это очень просто. Проще говоря, вы научитесь открывать машину нажатием кнопки без ключа (не
работает на автомобилях без радиоключей и может не работать на всех радиоключах).

  1. Возьмите радиоключ достаточно далеко от машины, чтобы он не активировался (или возьмите себе мешок Фарадея).
  2. Возьмите Flipper Zero и выберите Sub-GHz > Прочитайте RAW, затем нажмите центральную кнопку, чтобы начать
    запись.
  3. Удерживайте кнопку разблокировки на радиоключе в течение нескольких секунд и убедитесь, что вы принимаете
    передаваемый код (см. Gif)

Вот и все. Если вы хотите использовать его немедленно, подойдите достаточно близко к машине и нажмите центральную
кнопку, чтобы отправить код и (надеюсь) разблокировать его удаленно, к шоку и трепету всех вокруг. Если вы
предпочитаете быть немного более тонким, вместо этого выберите Сохранить код, дайте ему удобное имя, и вы можете
вернуться в Sub-GHz > Сохраненный позже для передачи, он все еще должен работать, поскольку ключ не должен
повторно использовать один и тот же код.

Как это работает?

Это форма повторной атаки, когда для
разблокировки автомобиля используется действующий код. Хитрость заключается в том, что современные автомобили обычно
используют скользящие или скачкообразные коды, чтобы люди не могли сделать именно это, поэтому, когда вы записывали
код, вы хотели быть вне досягаемости автомобиля.

Обычно автомобиль принимает каждый код разблокировки только один раз, затем помечает его как использованный и
отказывается принимать в будущем. Поскольку случаются случайные нажатия клавиш или сигналы могут не сработать с
первого раза, для разблокировки можно использовать ряд кодов.

Что вы сделали, так это украли один из этих действительных кодов, не дав ему попасть в машину, чтобы пометить его
как недействительный. После того, как вы его использовали, вы обнаружите, что снова разблокировать машину не
получится, каждый из них одноразовый (хотя вы можете записать несколько кодов, чтобы получить несколько
дополнительных применений, и сделать то же самое с кодами блокировки). .

Вы также можете обнаружить, что если вы слишком долго ждете, чтобы использовать его, он больше не будет работать,
так как было использовано слишком много нажатий клавиш, и поэтому диапазон допустимых кодов расширился. n n Тот же
метод использовался в течение многих лет для кражи автомобилей с использованием глушителя для предотвращения
получения автомобиля кода при его захвате с помощью приемника. Конечно, по мере того, как автомобили становятся
«умнее», возникает __множество других
проблем__ чем просто украсть вашу.

2. Лицом к лицу с музыкой — взламывайте телевизоры с помощью Flipper
Zero

:::предупреждение
Предупреждение. В неправильном такте это может привести к тому, что вас ударят. Как и в случае со
всеми другими перечисленными, существуют риски, используйте ответственно.

:::

Вы когда-нибудь заходили в бар и обнаруживали, что телевизор слишком, слишком громкий? Или он застрял на канале,
который вы не хотите смотреть, а пульт загадочным образом пропал?

Именно здесь инфракрасный порт Flipper Zero может пригодиться для простого, старомодного взлома.

Если повезет, универсальных кодов будет достаточно. В противном случае вам может потребоваться узнать коды пульта
дистанционного управления с реального пульта или получить их в Интернете и загрузить на свой Flipper Zero.

Чтобы получить универсальные коды, просто перейдите в Инфракрасный > Универсальные пульты (Learn New Remote и
Saved Remotes говорят сами за себя), затем телевизоры (или кондиционер, если вам нужно им управлять), и он
предоставит вам приятный интерфейс для включения и выключения питания, изменения громкости или канала. . Даже если
канал и громкость не работают, универсальные коды питания работают в большинстве случаев.

Как это
работает?

Подавляющее большинство телевизоров по-прежнему используют инфракрасные коды от пультов< /strong> для управления ими
(старая уловка, чтобы проверить, работают ли батареи в пульте дистанционного управления, заключается в том, чтобы
направить его на камеру мобильного телефона и нажать кнопку — мобильные камеры чувствительны к инфракрасному
излучению, поэтому вы увидите, как мигает лампочка на пульте). скрин, если работает). Все, что вы делаете, это
используете стандартные коды или записываете коды для определенного телевизора и снова воспроизводите их через
инфракрасный порт. На самом деле, вы можете использовать это для чего угодно с помощью инфракрасного пульта
дистанционного управления, вам просто нужно захватить команду, сохранить ее и воспроизвести по желанию.

3.
Запасной ключ

:::предупреждение
Предупреждение: я не должен этого говорить, но на всякий случай не используйте это, чтобы
вламываться в гостиничные номера людей!

:::

Это не будет работать для всех электронных замков в отелях, но работает для многих. Это связано с тем, что
большинство отелей не утруждают себя вложениями в высоконадежные запорные механизмы, а только самые простые с
минимальным уровнем безопасности. Я объясню подробнее об этом позже, просто имейте в виду, что это не будет работать
везде.

Вас когда-нибудь раздражало, что вы получаете только один ключ в отеле или в дачном поселке? Ну, это больше не
проблема с этим простым взломом Flipper Zero. Считыватель RFID может считывать большинство бесконтактных
карт-ключей, используемых в отелях, офисах и других местах. Простой доступ через NFC > Считайте (или 125 кГц RFID
для низкочастотных карт), затем отсканируйте карту, сохраните ее и при необходимости эмулируйте.

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

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

Как это работает?

РЧИД-карты питаются от считывателя и активируются, когда они считываются. В старых картах не было возможности
шифрования, и даже в современных шифрование часто используется неэффективно.

Когда мы говорим о гостиничных номерах, номер комнаты закодирован в карточке. В зависимости от используемой системы
могут быть опции для кодирования всего этажа, набора комнат или мастер-ключа для разблокировки везде (как
используется службами по уборке).

Существует дюжина или около того различных схем, которые обычно используются, и в большинстве из них у каждого
устройства записи карт есть встроенный в него ключ, чтобы привязать его к определенному отелю и предотвратить
отпирание номера 101 по всему миру одним и тем же ключом.

Ключи также зашифрованы, как правило, со временем заезда и выезда, поэтому единственная причина сохранять ключи от
отеля — это если вы хотите получить больше данных, чтобы попытаться взломать шифрование, чтобы вы могли сделать свой
собственный мастер-ключ (не рекомендуется). по юридическим причинам, но забавно, если вы заинтересованы в этих
схемах), или, конечно, написать их как запасные ключи, а не размахивать своим Flipper Zero повсюду.


С помощью некоторых хаков Flipper Zero вы можете сделать гораздо больше, чтобы произвести впечатление на друзей
и повеселиться, и хотя есть и другие инструменты, я должен сказать, что это, безусловно, самый простой в
использовании и самый многофункциональный. я сталкивался.

Напишите в комментариях свои любимые лайфхаки Flipper Zero, чтобы произвести впечатление на ваших друзей, или
лайфхаки, которые вы бы хотели, чтобы я рассмотрел в будущих статьях.


Оригинал

2A2V6-FZ Мультитул Flipper Zero для хакера
Руководство пользователя

Быстрое начало

2A2V6 FZ Flipper Zero Мультитул для хакераПрочтите полное руководство здесь: https://docs.flipperzero.one

MicroSD карта

2A2V6 FZ Flipper Zero Мультитул для хакера - карта памяти microSD

Обязательно вставьте карту microSD, как показано на рисунке. Flipper Zero поддерживает карты объемом до 256 ГБ, но 16 ГБ должно быть достаточно.
Вы можете отформатировать карту microSD автоматически из меню Flipper или вручную с помощью компьютера. В последнем случае выберите exFAT или FAT32. fileсистемы.

2A2V6 FZ Flipper Zero Мультитул для хакера -iconFlipper Zero работает с картами microSD в «медленном режиме» SPI. Только подлинные карты microSD должным образом поддерживают этот режим. См. рекомендуемые карты microSD здесь: https://flipp.dev/sd-card

Включение

Сдерживаться 2A2V6 FZ Flipper Zero Multitool для хакера -icon 1в течение 3 секунд, чтобы включить.
Если Flipper Zero не запускается, попробуйте зарядить аккумулятор с помощью USB-кабеля, подключенного к источнику питания 5 В/1 А.

2A2V6 FZ Flipper Zero Мультитул для хакера - Включение питания

Обновление прошивки

2A2V6 FZ Flipper Zero Мультитул для хакера - Обновление прошивки

Чтобы обновить прошивку, подключите устройство к компьютеру через USB-кабель и перейдите по ссылке: https://update.flipperzero.one
Важно установить последнюю доступную прошивку, чтобы получить преимущество.tage всех улучшений и исправлений ошибок.

Rebooting

2A2V6 FZ Flipper Zero Мультитул для хакера -Перезагрузка

Удерживайте левую 2A2V6 FZ Flipper Zero Multitool для хакера -icon 2+ Назад2A2V6 FZ Flipper Zero Multitool для хакера -icon 1 для перезагрузки.
Вы можете столкнуться с зависаниями, особенно когда прошивка находится в стадии бета-тестирования или при использовании версии для разработчиков. Если Flipper Zero перестает отвечать на запросы, перезагрузите устройство.
Руководство по порту GPIO см. на странице docs.flipperzero.one

Ссылки

2A2V6 FZ Flipper Zero Мультитул для хакера - код qr

  • Прочтите документацию: docs.flipperzero.one
  • Поговорите с нами в Discord: flipp.dev/дискорд
  • Обсудите возможности на нашем форуме: forum.flipperzero.one
  • Ознакомьтесь с исходным кодом: github.com/flipperdevices
  • Сообщать об ошибках: flipp.dev/ошибка

2A2V6 FZ Flipper Zero Multitool для хакера -icon 6Твиттер: @flipper_zero
2A2V6 FZ Flipper Zero Multitool для хакера -icon 4Фейсбук: @flipperzero
2A2V6 FZ Flipper Zero Multitool для хакера -icon 3Instagбаран: @flipper_zero

ФЛИППЕР
Флиппер Девиз Инк.
Все права защищены
Безопасность Flipper Zero и руководство пользователя

Разработано и распространено
Флиппер Девиз Инк
Люкс Б #551
2803 Филадельфия Пайк
Клеймонт, Делавэр, 19703, США
www.flipperdevices.com
support@flipperdevices.com

2A2V6 FZ Flipper Zero Мультитул для хакера - осторожноВНИМАНИЕ: ЗАПРЕЩАЕТСЯ ЧИСТИТЬ ЭКРАН СПИРТОМ ИЛИ СПИРТОСОДЕРЖАЩИМИ СРЕДСТВАМИ, ТКАЦАМИ, САЛФЕТКАМИ ИЛИ ДЕЗИНФИЦИРУЮЩИМИ СРЕДСТВАМИ. ЭТО МОЖЕТ ПОВРЕДИТЬ ЭКРАН И АННУЛИРОВАТЬ ВАШУ ГАРАНТИЮ.

ПРЕДУПРЕЖДЕНИЕ

  • Не подвергайте изделие воздействию воды, влаги или тепла. Он рассчитан на надежную работу при нормальных комнатных температурах и влажности.
  • Любое периферийное устройство или оборудование, используемое с Flipper Zero, должно соответствовать применимым стандартам страны использования и иметь соответствующую маркировку для обеспечения соблюдения требований безопасности и производительности.
  • Любой внешний источник питания, используемый с продуктом, должен соответствовать соответствующим нормам и стандартам, применимым в стране предполагаемого использования. Источник питания должен обеспечивать 5 В постоянного тока и минимальный номинальный ток 0.5 А.
  • Любые изменения или модификации продукта, которые явно не одобрены Flipper Devices Inc., могут привести к аннулированию права пользователя на эксплуатацию оборудования и вашей гарантии.

Все сертификаты соответствия см. www.flipp.dev/compliance.

СОБЛЮДЕНИЕ

СООТВЕТСТВИЕ FCC

Это устройство соответствует части 15 правил FCC. Эксплуатация осуществляется при соблюдении следующих двух условий: (1) это устройство не должно создавать вредных помех, и (2) это устройство должно принимать любые получаемые помехи, включая помехи, которые могут вызвать нежелательную работу. Это оборудование было протестировано и признано соответствующим ограничениям для цифровых устройств класса B в соответствии с частью 15 правил FCC. Эти ограничения предназначены для обеспечения разумной защиты от вредных помех при установке в жилых помещениях. Это оборудование генерирует, использует и может излучать радиочастотную энергию и, если оно не установлено и не используется в соответствии с инструкциями, может создавать вредные помехи для радиосвязи. Однако нет гарантии, что помехи не возникнут в конкретной установке. Если это оборудование создает вредные помехи для радио- или телевизионного приема, что можно определить, выключив и включив оборудование, пользователю рекомендуется попытаться устранить помехи одним или несколькими из следующих способов: (1) Переориентировать или переместить приемная антенна; (2) увеличить расстояние между оборудованием и приемником; (3) Подключить оборудование к розетке в цепи, отличной от той, к которой подключен приемник; (4) Обратитесь за помощью к дилеру или опытному специалисту по радио/телевидению. Предупреждение: Изменения или модификации данного устройства, не одобренные явным образом стороной, ответственной за соответствие требованиям, могут привести к аннулированию права пользователя на эксплуатацию оборудования. Предупреждение о радиочастотном воздействии: устройство было проверено на соответствие общим требованиям к радиочастотному излучению. Прибор можно использовать в условиях портативного облучения без ограничений.

СООТВЕТСТВИЕ ИС

Это устройство соответствует стандарту(ам) RSS, не требующему лицензии Министерства промышленности Канады. Эксплуатация осуществляется при соблюдении следующих двух условий: (1) Это устройство не должно создавать помех, и (2) Это устройство должно принимать любые помехи, включая помехи, которые могут вызвать нежелательную работу устройства. В соответствии с правилами Министерства промышленности Канады, этот радиопередатчик может работать только с антенной, тип и максимальный (или меньший) коэффициент усиления которой утверждены для передатчика Министерством промышленности Канады. Чтобы уменьшить потенциальные радиопомехи другим пользователям, тип антенны и ее коэффициент усиления следует выбирать таким образом, чтобы эквивалентная изотопно-излучаемая мощность (э.и.и.м.) не превышала той, которая необходима для успешной связи. Предупреждение о радиочастотном воздействии: устройство было проверено на соответствие общим требованиям к радиочастотному излучению. Прибор можно использовать в условиях портативного облучения без ограничений.

СООТВЕТСТВИЕ СЕ

Максимальная мощность радиочастот, передаваемая в диапазонах частот, в которых работает радиооборудование: Максимальная мощность для всех диапазонов меньше максимального предельного значения, указанного в соответствующем Гармонизированном стандарте. Диапазоны частот и номинальные пределы мощности передачи (излучаемой и/или кондуктивной), применимые к этому радиооборудованию, следующие:

  • Диапазон рабочих частот Bluetooth: 2402-2480 МГц и максимальная мощность EIRP: 2.58 дБм
  • Диапазон рабочих частот SRD: 433.075–434.775 МГц, 868.15–868.55 МГц и максимальная мощность EIRP: -15.39 дБм
  • Диапазон рабочих частот NFC: 13.56 МГц и максимальная мощность EIRP: 17.26 дБА/м
  1. Диапазон рабочих температур ИО: от 0°C до 35°C.
  2. Номинальное питание 5 В постоянного тока, 1 А.
  3. Декларация соответствия.

Flipper devises Inc настоящим заявляет, что этот Flipper Zero соответствует основным требованиям и другим соответствующим положениям Директивы 2014/53/ЕС. Этот продукт разрешен к использованию во всех странах-членах ЕС.
Flipper devises Inc настоящим заявляет, что этот Flipper Zero соответствует стандартам Постановлений Великобритании 2016 г. (SI 2016/1091), Постановлений 2016 г. (SI 2016/1101) и Постановлений 2017 г. (SI 2017/1206).
Чтобы ознакомиться с декларацией соответствия, посетите www.flipp.dev/compliance.

СОБЛЮДЕНИЕ РОХС И WEEE

значок утилизацииВНИМАНИЕ!: ОПАСНОСТЬ ВЗРЫВА ПРИ ЗАМЕНЕ АККУМУЛЯТОРА НА НЕПРАВИЛЬНЫЙ ТИП. УТИЛИЗИРУЙТЕ ИСПОЛЬЗУЕМЫЕ БАТАРЕИ В СООТВЕТСТВИИ С ИНСТРУКЦИЯМИ.
RoHS: Flipper Zero соответствует соответствующим положениям директивы RoHS для Европейского Союза.
Директива WEEE: эта маркировка указывает на то, что данное изделие нельзя утилизировать вместе с другими бытовыми отходами на всей территории ЕС. Чтобы предотвратить возможный вред окружающей среде или здоровью человека от неконтролируемой утилизации отходов, ответственно относитесь к их переработке, чтобы способствовать устойчивому повторному использованию материальных ресурсов. Чтобы вернуть бывшее в употреблении устройство, воспользуйтесь системами возврата и сбора или обратитесь к продавцу, у которого было приобретено изделие. Они могут сдать этот продукт на экологически безопасную переработку.
Примечание: Полную онлайн-копию настоящей Декларации можно найти по адресу www.flipp.dev/compliance.

2A2V6 FZ Flipper Zero Мультитул для хакера -icon ce

Продукт: Flipper Zero Модель: FZ.1
Идентификатор FCC: 2A2V6-FZ IC: 27624-FZ

Flipper, Flipper Zero и логотип Dolphin являются зарегистрированными товарными знаками Flipper Devices Inc в США и/или других странах.

Документы / Ресурсы

Привет!

В этой статье мы разберёмся, как написать собственную программу-приложение для Flipper Zero!

Сердцем гаджета Flipper Zero является 32-битный микроконтроллер STM32. Программирование Дельфина сильно отличается от программирования привычных нам Arduino. Помимо самого микроконтроллера во Флиппере есть радиомодуль, NFC-модуль, кардридер, модуль Bluetooth, дисплей, микросхема управления подсветкой и так далее. Эффективно управлять всеми этими устройствами в одном цикле loop, как это обычно выглядит в среде разработки Arduino, уже нельзя.

На помощь приходит операционная система реального времени или RTOS (real-time operating system). RTOS разграничивает логические части всей программы в разные потоки и сама осуществляет переключение между ними, а также выделяет необходимые для работы потоков ресурсы.

Так как Флиппер построен на чипе STM32, в нём используется, наверное, самая популярная операционка для этого типа микроконтроллеров — FreeRTOS.

Мы не будем подробно разбирать, как реализована операционная система на Flipper Zero, а лучше сосредоточимся на написании приложений.

Это важно! Проект Flipper Zero активно развивается, и на момент выхода данной статьи официальной документации по созданию собственных приложений нет, а сам API полностью не описан. Однако принцип построения приложений вполне понятен в процессе изучения исходного кода встроенных в Флиппер приложений. Вполне возможно, что со временем API изменится, и код из этой статьи станет неактуальным. Разработчики Flipper Zero обещают, что документация появится, когда стабилизируется API. Статья актуальна для прошивки Флиппера 0.75.0.

Прошивку можно собрать на следующих платформах:

  • Windows 10+ с PowerShell и Git (архитектура x86_64).
  • macOS 12+ с Command Line tools (архитектура x86_64 и arm64).
  • Ubuntu 20.04+ с build-essential и Git (архитектура x86_64).

У пользователей macOS не должно быть проблем со сборкой прошивки благодаря Homebrew. Ну а если вы собираете прошивку на Windows и столкнулись с трудностями, попробуйте воспользоваться WSL.

Писать код для собственных приложений мы будем на языке программирования C на настольном компьютере под управлением Linux, а именно Ubuntu 22.04.1 LTS (Jammy Jellyfish).

Установка необходимого софта

Перед тем как писать новое приложение, нам придётся научиться собирать всю прошивку микроконтроллера.

Сперва скачаем и установим официальную программу qFlipper для работы с Флиппером через графический интерфейс. Мы будем использовать qFlipper для удобной загрузки наших готовых приложений на SD-карту во Флиппере.

Скачиваем версию программы для OS Linux куда-нибудь, например в домашнюю директорию. На момент выхода статьи программа qFlipper имеет версию 1.2.2, а сам файл называется qFlipper-x86_64-1.2.2.AppImage. Также установите необходимую для работы программы библиотеку libfuse2, если её нет в вашей системе.

wget https://update.flipperzero.one/builds/qFlipper/1.2.2/qFlipper-x86_64-1.2.2.AppImage
sudo apt install libfuse2

Установите разрешение на запуск qFlipper и добавьте в систему udev правила доступа к USB Serial-порту для обычного пользователя. Иначе понадобится вести разработку от лица суперпользователя, что небезопасно для всей системы в случае неосторожности.

sudo chmod +x qFlipper-x86_64-1.2.2.AppImage
./qFlipper-x86_64-1.2.2.AppImage rules install

Запустите qFlipper и подключите ваш Flipper Zero к компьютеру по USB.

./qFlipper-x86_64-1.2.2.AppImage

Убедитесь, что ваш Флиппер появился в программе qFlipper, всё работает как положено и установлена свежая прошивка.

qflipper_1

Для быстрой и удобной установки необходимого софта понадобится диспетчер пакетов Homebrew.

Установите Homebrew:

sudo apt install curl
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

После установки добавьте переменные окружения PATH, MANPATH для Homebrew. Это можно сделать, добавив следующую строку в .profile-файл для вашего юзера:

echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> /home/тут_ваш_username/.profile

Прошивка для Flipper Zero хранится в репозитории flipperzero-firmware на GitHub.

Склонируйте к себе репозиторий прошивки Flipper Zero со всеми модулями. Репозиторий займет чуть больше 2 ГБ пространства.

git clone --recursive https://github.com/flipperdevices/flipperzero-firmware.git

Установите перечисленный в описании репозитория софт:

sudo apt update
sudo apt install openocd clang-format-13 dfu-util protobuf-compiler

Перейдите в директорию репозитория и установите все необходимые пакеты с помощью Homebrew:

cd flipperzero-firmware
brew bundle --verbose

Готово! Прошивка для Флиппера, как и пользовательские приложения, собираются с помощью утилиты fbt (Flipper Build Tool). Для создания собственных приложений нет необходимости каждый раз собирать всю прошивку целиком, однако при первом запуске утилиты fbt будут скачаны необходимые gcc-arm тулчейны.

Соберите прошивку:

./fbt

Все результаты сборки и бинарные файлы будут помещены в директорию /dist.

Пример 1. Простейшее приложение

Создадим простейшее компилируемое приложение.

Мы будем создавать приложение типа FAP (Flipper Application Package). Готовое приложение этого типа представляет собой файл формата .fap. По сути, .fap-приложение — это исполняемый файл .elf с дополнительными встроенными данными.

Кстати! Весь исходный код приложений из этой стати мы выложили на GitHub в репозитории flipperzero-examples.

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

ws_code_1

Придумайте имя для приложения. Мы назвали наше первое приложение example_1, этим же именем назвали и папку. В неё помещаются все файлы, которые относятся к вашему приложению: исходный код, изображения и прочее.

В папке example_1 создадим файл исходного кода на языке С — example_1_app.c. Вот как выглядит код простейшего приложения.

#include <furi.h>

int32_t example_1_app(void* p) {
    UNUSED(p);
    return 0;
}

Конвенционально в приложении точкой входа является функция, которая имеет имя приложения и суффикс app. Точка входа в наше приложение — функция example_1_app. Главная функция традиционно возвращает код ошибки числом типа int32_t. Возвращаемый ноль сообщает об отсутствии ошибок.

При компиляции кода для Флиппера любой warning воспринимается как ошибка. Да, ваш код должен быть чистеньким. Неиспользованные в функции аргументы вызывают warning, поэтому для обозначения неиспользуемого указателя p мы используем макрос UNUSED. Реализация данного макроса описана в заголовке furi.h. FURI расшифровывается как «Flipper Universal Registry Implementation». Этим заголовочным файлом мы, по сути, подключаем вce core API Флиппера.

Нашему приложению понадобится иконка. Для пользовательских приложений, которые находятся на самом Флиппере в разделе Applications, в качестве иконок используются изображения PNG с глубиной цвета 1 бит (чёрно-белые) и размером 10×10 пикселей.

Раздел Apllications с пользовательскими приложениями:

flipper_1

Можно использовать одно из уже имеющихся изображений, но всегда лучше добавить что-то своё. В GIMP мы нарисовали вот такой смайл в чёрных очках:

emoji_smile_icon_10x10px

Нарисовать свою иконку можно и в Paint. Файл изображения помещаем в папку нашего приложения example_1.

Помимо исходного кода и иконки нам нужен файл манифеста приложения — application.fam. Этот файл является обязательным. Наш манифест приложения имеет следующий вид:

App(
    appid="example_1",
    name="Example 1 application",
    apptype=FlipperAppType.EXTERNAL,
    entry_point="example_1_app",
    cdefines=["APP_EXAMPLE_1"],
    stack_size=1 * 1024,
    order=90,
    fap_icon="emoji_smile_icon_10x10px.png",
    fap_category="Misc",
)

Разберёмся, за что отвечают данные параметры. Параметры для всех видов приложений:

  • appid — строка, которая используется как ID приложения при конфигурации сборки fbt, а также для разрешения зависимостей и конфликтов. Есть смысл использовать здесь непосредственно имя вашего приложения.
  • name — читабельное имя приложения, которое будет отображаться в меню приложений на Флиппере.
  • apptype — тип приложения. Существуют разные типы для тестовых, системных, сервисных, архивных приложений и для приложений, которые должны быть в главном меню Флиппера. В конце сборки наше приложение будет типа FAP. Для приложений подобного рода используется тип EXTERNAL (FlipperAppType.EXTERNAL).
  • entry_point — точка входа приложения. Имя главной функции, с выполнения которой начнётся работа вашего приложения. Если в качестве точки входа вы хотите использовать функцию C++, то она должна быть обёрнута в extern "C".
  • cdefines — препроцессорное глобальное объявление для других приложений, когда текущее приложение включено в активную конфигурацию сборки.
  • stack_size — размер стека в байтах, выделяемый для приложения при его запуске. Обратите внимание, что выделение слишком маленького стека приведёт к сбою системы из-за переполнения стека, а выделение слишком большого уменьшит полезный объём heap-памяти для обработки данных приложениями.
  • order — порядок приложения внутри своей группы при сортировке записей. Чем ниже значение, тем выше по списку окажется ваше приложение.

Параметры для внешних приложений типа EXTERNAL:

  • fap_icon — путь и имя PNG-изображения размером 10×10 пикселей, которое используется как иконка. Здесь пишем путь и имя нашей PNG-иконки.
  • fap_category — подкатегория приложения. Определяет путь .fap-файла в папке приложений в файловой системе. Может быть пустым. Мы поместили наше приложение в категорию Misc на Флиппере.

Если все файлы на месте, мы можем начинать сборку приложения.

ws_code_2

В терминале переходим в корневую директорию прошивки flipperzero-firmware. Сборка осуществляется командой ./fbt fap_{APPID}, где {APPID} — это ID, указанный в .fam-файле манифеста приложения.

./fbt fap_example_1

Сбилдить все имеющиеся в прошивке приложения FAP можно командой ./fbt faps.

Готовое FAP-приложение находится в директории build в скрытой директории .extapps. Наш файл приложения называется example_1.fap.

ws_code_3

Используя программу qFlipper, перенесём файл приложения на SD-карту в директорию /apps/Misc. Файл можно перенести мышкой прямо в окно программы.

qflipper_2

После последнего обновления все приложения FAP можно сбилдить и перенести на Флиппер одной командой из консоли:

./fbt fap_deploy

Готово! Теперь наше приложение появилось на Флиппере в разделе Misc:

flipper_2

Главная функция example_1_app() сейчас пуста, поэтому при запуске приложения программа просто завершит свою работу и мы не увидим никаких изменений на экране.

Как видно, ваше приложение может вовсе не иметь графического интерфейса и отработать как бы «за кулисами». Но у нашего Флиппера есть экранчик, поэтому нельзя не сделать графический интерфейс.

Пример 2. Графический интерфейс

Добавим нашему приложению графический интерфейс.

Чтобы не путаться между пунктами статьи, мы сделаем новое приложение с именем example_2, но по сути будем продолжать предыдущее приложение.

Новое приложение поместим в директорию applications_user/example_2. Соответственно, файл с исходным кодом приложения имеет имя example_2_app.c.

Для создания графического интерфейса вам придётся значительно расширить исходный код приложения. Создадим в директории приложения заголовочный файл example_2_app.h для описания типов данных, структур и прототипов функций.

Включим уже знакомый нам заголовочный файл ядра furi.h. Для графического интерфейса понадобится заголовок gui/gui.h.

#pragma once

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

struct Example2App {
    Gui* gui;
    ViewPort* view_port;
};

typedef struct Example2App Example2App;

В заголовочном файле мы создали структуру Example2App, которая будет хранить указатели на все важные компоненты нашего приложения, и ввели новый тип для этой структуры. В структуре нашего приложения есть указатели на графический интерфейс Gui и на ViewPort. ViewPort — это структура, которая используется для отрисовки единичного полного экрана. К ней привязываются указатели на callback-функции отрисовки графических объектов на экране и функции обработки различных событий (Events), например нажатие клавиш.

Исходный код приложения в файле example_2_app.c теперь выглядит так:

#include "example_2_app.h"

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

Example2App* example_2_app_alloc() {
    Example2App* app = malloc(sizeof(Example2App));

    app->view_port = view_port_alloc();

    app->gui = furi_record_open(RECORD_GUI);
    gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen);

    return app;
}

void example_2_app_free(Example2App* app) {
    furi_assert(app);

    view_port_enabled_set(app->view_port, false);
    gui_remove_view_port(app->gui, app->view_port);
    view_port_free(app->view_port);

    furi_record_close(RECORD_GUI);
}

int32_t example_2_app(void *p) {
    UNUSED(p);
    Example2App* app = example_2_app_alloc();

    furi_delay_ms(10000);

    example_2_app_free(app);
    return 0;
}

Разберёмся, что есть что. Программирование под Флиппер очень требовательно к ресурсам операционной системы, и нам нужно за этим следить. Это необходимо, чтобы наше приложение работало правильно и не вызывало зависаний и глюков. Поэтому, если мы хотим что-то добавить в приложение или интерфейс, то самостоятельно выделяем под это память, а когда удаляем — освобождаем.

Описываем функцию, которая будет выделять память под структуру нашего приложения и инициализировать его:

Example2App* example_2_app_alloc()

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

void example_2_app_free(Example2App* app)

В функции выделения памяти мы сначала выделяем память под структуру app типа Example2App для нашего приложения. Затем выделяем память для view_port:

app->view_port = view_port_alloc();

Получаем указатель на текущий Gui Флиппера — gui. Перехватываем управление Gui и говорим операционной системе, что у нашего приложения есть некий интерфейс c отрисовкой экрана view_port и мы хотим его отобразить.

app->gui = furi_record_open(RECORD_GUI);
gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen);

В функции освобождения памяти мы, соответственно, работаем в обратном направлении. Выключаем рендер нашего view_port:

view_port_enabled_set(app->view_port, false);

Отключаем view_port от Gui и освобождаем память, занятую view_port:

gui_remove_view_port(app->gui, app->view_port);
view_port_free(app->view_port);

В конце мы передаём управление графическим интерфейсом от нашего приложения обратно операционной системе:

furi_record_close(RECORD_GUI);

Так как мы пишем на С и регулярно используем указатели, в ядре FURI существует крайне полезная для нас функция furi_assert(), которая экстренно остановит работу приложения и выдаст сообщение, если мы вдруг передадим указатель на пустой участок памяти.

Точкой входа приложения на этот раз будет функция с именем example_2_app:

int32_t example_2_app(void *p) {
    UNUSED(p);
    Example2App* app = example_2_app_alloc();

    furi_delay_ms(10000);

    example_2_app_free(app);
    return 0;
}

При запуске приложения мы аллоцируем память для структуры приложения, перехватываем управление Gui и рендерим наш ViewPort. После этого мы простаиваем 10 секунд функцией furi_delay_ms(), освобождаем все занятые ресурсы, передаём управление Gui операционной системе и завершаем работу приложения.

Кроме того, у нас получился хороший шаблон с выделением/освобождением памяти для будущих приложений.

Иконку для приложения оставляем прежней.

Вносим правки в файл манифеста приложения application.fam. Здесь всё остаётся прежним, за исключением нового параметра requires. В этом параметре мы указываем, что для работы нашему приложению нужен сервис, отвечающий за графические интерфейсы gui.

App(
    appid="example_2",
    name="Example 2 application",
    apptype=FlipperAppType.EXTERNAL,
    entry_point="example_2_app",
    cdefines=["APP_EXAMPLE_2"],
    requires=[
        "gui",
    ],
    stack_size=1 * 1024,
    order=90,
    fap_icon="emoji_smile_icon_10x10px.png",
    fap_category="Misc",
)

Собираем новое приложение:

./fbt fap_example_2

Используя программу qFlipper, перенесём новое FAP-приложение из папки build на SD-карту в папку /apps/Misc. Или используем терминал и команду ./fbt fap_deploy.

Находим новое приложение в списке и запускаем его:

flipper_3

Сейчас для нашего ViewPort не описаны конкретные функции отрисовки графических объектов. Программа приложения просто отобразит пустой графический интерфейс в течение 10 секунд и завершит работу.

Пример 3. Текст и изображения

Добавим в интерфейс нашего приложения какие-нибудь графические объекты. Некоторые графические объекты могут иметь довольно сложную реализацию, например: меню, выпадающие списки, файловые браузеры, различные формы ввода. Мы же начнём с простых объектов.

Снова создадим копию предыдущего приложения, но теперь под именем example_3.

Для рендера графических объектов создадим в исходном файле example_3_app.c callback-функцию отрисовки example_3_app_draw_callback:

static void example_3_app_draw_callback(Canvas* canvas, void* ctx) {
    UNUSED(ctx);
    canvas_clear(canvas);
}

Callback-функция имеет определённую сигнатуру и два аргумента canvas, то есть «холст», на котором мы будем рисовать, и контекст ctx. Контекстом могут быть другие данные, в зависимости от которых рендерится canvas. Пока что мы оставим контекст неиспользованным, то есть UNUSED.

Первым делом перед рендером очистим наш экран:

canvas_clear(canvas);

Графические объекты размещаются на экране согласно системе координат. Экран Флиппера имеет разрешение 128×64, а начало координат находится в левом верхнем углу:

canvas

Добавим текст в интерфейс нашего приложения.

Подключим заголовочный файл с графическими текстовыми элементами gui/elements.h. Текст отрисовывается функцией canvas_draw_str() с указанием координаты (x; y) исходной точки текста и, собственно, самой строки. Возможен выбор шрифта для текста. Шрифт устанавливается функцией canvas_set_font(). Шрифт может быть главным — FontPrimary (высота 8 пикселей), второстепенным — FontSecondary (высота 7 пикселей), FontKeyboard или FontBigNumbers. При желании вы сможете создать и собственный шрифт.

Например, напишем главным шрифтом строку «This is an example app!» вверху экрана и примерно по центру, по координатам (4; 8). По умолчанию начало координат текста находится в левом нижнем углу.

canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, 4, 8, "This is an example app!");

В заголовочном файле gui/elements.h можно найти различные имплементации для отрисовки простых элементов, скроллбаров, кнопок или выравнивания текста.

Например, снизу от нашей первой надписи разместим длинный двухстрочный текст «Some long long long long aligned multiline text», написанный второстепенным шрифтом и автоматически выровненный по верхней и правой границам. Для этого воспользуемся функцией elements_multiline_text_aligned():

canvas_set_font(canvas, FontSecondary);
elements_multiline_text_aligned(canvas, 127, 15, AlignRight, AlignTop, "Some long long long long n aligned multiline text");

Теперь разберёмся, как вывести на экран картинку.

Для эксперимента мы нарисовали чёрно-белый логотип Амперки в PNG разрешением в 128×35 пикселей:

amperka_ru_logo_128x35px

В папке с вашим приложением создайте специальную директорию для хранения изображений. Например, мы назвали свою папку images. В данную папку поместите все изображения, которые планируете выводить на экран. Мы назвали нашу картинку amperka_ru_logo_128x35px.png и поместили её в созданную папку images:

ws_code_4

В манифесте приложения application.fam добавляем новый параметр fap_icon_assets с путём до директории с изображениями:

App(
    appid="example_3",
    name="Example 3 application",
    apptype=FlipperAppType.EXTERNAL,
    entry_point="example_3_app",
    cdefines=["APP_EXAMPLE_3"],
    requires=[
        "gui",
    ],
    stack_size=1 * 1024,
    order=90,
    fap_icon="emoji_smile_icon_10x10px.png",
    fap_category="Misc",
    fap_icon_assets="images",
)

Теперь при сборке приложения все изображения из папки images будут переведены в код, а сам код будет сгенерирован в специальном заголовочном файле с именем {APPID}_icons.h, где {APPID} — это ID, указанный в .fam-файле манифеста приложения.

Наше приложение имеет ID example_3, значит заголовочный файл получит имя example_3_icons.h. Добавим данный файл в заголовок приложения:

#include "example_3_icons.h"

Теперь мы можем получить указатель на область памяти, где хранится наше изображение в виде массива байтов. Имя указателя будет соответствовать имени самого файла изображения, но с приставкой I_ИМЯ_ВАШЕГО_ФАЙЛА. Для нашей картинки с именем amperka_ru_logo_128x35px.png имя указателя будет I_amperka_ru_logo_128x35px.

Теперь, имея адрес изображения, мы можем отрендерить его на экране функцией canvas_draw_icon(). Выведем изображение внизу экрана по координатам (0; 29):

canvas_draw_icon(canvas, 0, 29, &I_amperka_ru_logo_128x35px);

Пока что хватит графических элементов. Результат должен выглядеть следующим образом:

flipper_4

Наша callback-функция отрисовки готова, и её необходимо привязать к структуре ViewPort нашего приложения. Это нужно сделать в функции инициализации нашего приложения сразу после выделения памяти под ViewPort. В качестве контекста мы ничего не отправляем (NULL). После привязки первый раз callback-функция будет выполнена автоматически.

view_port_draw_callback_set(app->view_port, example_3_app_draw_callback, NULL);

Заголовочный файл нашего третьего приложения не изменился, за исключением имени приложения и подключаемого заголовка с изображениями.

Код example_3_app.h:

#pragma once

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

#include "example_3_icons.h"

struct Example3App {
    Gui* gui;
    ViewPort* view_port;
};

typedef struct Example3App Example3App;

Код example_3_app.с:

#include "example_3_app.h"

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

#include <gui/elements.h>

static void example_3_app_draw_callback(Canvas* canvas, void* ctx) {
    UNUSED(ctx);

    canvas_clear(canvas);

    canvas_draw_icon(canvas, 0, 29, &I_amperka_ru_logo_128x35px);

    canvas_set_font(canvas, FontPrimary);
    canvas_draw_str(canvas, 4, 8, "This is an example app!");

    canvas_set_font(canvas, FontSecondary);
    elements_multiline_text_aligned(canvas, 127, 15, AlignRight, AlignTop, "Some long long long long n aligned multiline text");
}

Example3App* example_3_app_alloc() {
    Example3App* app = malloc(sizeof(Example3App));

    app->view_port = view_port_alloc();

    view_port_draw_callback_set(app->view_port, example_3_app_draw_callback, NULL);

    app->gui = furi_record_open(RECORD_GUI);
    gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen);

    return app;
}

void example_3_app_free(Example3App* app) {
    furi_assert(app);

    view_port_enabled_set(app->view_port, false);
    gui_remove_view_port(app->gui, app->view_port);
    view_port_free(app->view_port);

    furi_record_close(RECORD_GUI);
}

int32_t example_3_app(void *p) {
    UNUSED(p);
    Example3App* app = example_3_app_alloc();

    furi_delay_ms(10000);

    example_3_app_free(app);
    return 0;
}

Главную функцию приложения example_3_app оставляем как есть. Приложение снова отработает 10 секунд и завершит свою работу, но на этот раз у нас будет графика.

Собираем новое приложение:

./fbt fap_example_3

Используя программу qFlipper, перенесём новое FAP-приложение из папки build на SD-карту в папку /apps/Misc. Или используем терминал и команду ./fbt fap_deploy.

Находим новое приложение в списке и запускаем его:

flipper_5

Взглянем на результат:

Пример 4. Кнопки

Разберёмся, как обрабатывать нажатия кнопок на Флиппере.

Продолжаем предыдущее приложение под новым именем example_4.

Для использования кнопок нам понадобится очередь сообщений (MessageQueue) и ещё одна callback-функция для обработки этой очереди.

Зачем нужна очередь сообщений? Поскольку за нас работает операционная система, то callback-функция ввода с кнопок, как и callback-функция рендера графики выполняется в контексте других потоков ОС Flipper Zero, а не в потоке нашего приложения. Поток, отвечающий за нажатие кнопок, не может вызвать какую-либо функцию напрямую из нашего приложения. Но потоки могут отправлять друг другу сообщения в любой момент выполнения, этим мы и воспользуемся.

Добавляем в структуру нашего приложения Example4App очередь event_queue типа FuriMessageQueue:

struct Example4App {
    Gui* gui;
    ViewPort* view_port;
    FuriMessageQueue* event_queue;
};

В функции инициализации приложения example_4_app_alloc() выделяем память под новую очередь.

app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));

Наша очередь будет на 8 сообщений типа InputEvent, который отвечает за нажатие клавиш. Структуры данных и функции для работы с сообщениями от кнопок находятся в заголовочном файле input/input.h.

В функции освобождения памяти нашего приложения, соответственно, освобождаем занятую очередью память.

furi_message_queue_free(app->event_queue);

Теперь создадим callback-функцию для обработки этой очереди.

static void example_4_app_input_callback(InputEvent* input_event, void* ctx) {
    furi_assert(ctx);

    FuriMessageQueue* event_queue = ctx;
    furi_message_queue_put(event_queue, input_event, FuriWaitForever);
}

Как и в случае с callback-функцией отрисовки, эта имеет два аргумента: input_event и контекст ctx. Событие input_event сигнализирует о каком-либо взаимодействии с кнопками. В отличие от функции отрисовки, в этот раз контекст не пустой. Мы положили в контекст очередь сообщений нашего приложения. Таким образом актуальные события ввода с кнопок окажутся в потоке нашего приложения.

Привязываем новую callback-функцию к графическому интерфейсу ViewPort нашего приложения. В качестве контекста указываем очередь сообщений приложения event_queue:

view_port_input_callback_set(app->view_port, example_4_app_input_callback, app->event_queue);

Готово! Теперь информация о состоянии кнопок находится в нашем распоряжении, и её можно обработать.

Сейчас наше приложение работает 10 секунд, а затем завершает работу. Давайте сделаем так, чтобы приложение закрывалось не автоматически, а при нажатии на клавишу «Назад» на Флиппере.

Обработчик сообщений из очереди напишем в главной функции нашего приложения (точке входа) в бесконечном цикле:

while (1) {
    if (furi_message_queue_get(app->event_queue, &event, 100) == FuriStatusOk) {
        if (event.type == InputTypePress) {
            if (event.key == InputKeyBack)
                break;
        }
    }
}

Пока очередь пуста, крутимся в бесконечном цикле. Если в нашей очереди есть событие (FuriStatusOk), нажалась кнопка (InputTypePress), и это была кнопка «Назад» (InputKeyBack), то выходим из цикла и, как следствие, движемся к завершению работы приложения.

Код example_4_app.h:

#pragma once

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

#include "example_4_icons.h"

struct Example4App {
    Gui* gui;
    ViewPort* view_port;
    FuriMessageQueue* event_queue;
};

typedef struct Example4App Example4App;

Код example_4_app.с:

#include "example_4_app.h"

#include <furi.h>
#include <gui/gui.h>
#include <gui/elements.h>

#include <input/input.h>

static void example_4_app_draw_callback(Canvas* canvas, void* ctx) {
    UNUSED(ctx);

    canvas_clear(canvas);

    canvas_draw_icon(canvas, 0, 29, &I_amperka_ru_logo_128x35px);

    canvas_set_font(canvas, FontPrimary);
    canvas_draw_str(canvas, 4, 8, "This is an example app!");

    canvas_set_font(canvas, FontSecondary);
    elements_multiline_text_aligned(canvas, 127, 15, AlignRight, AlignTop, "Some long long long long n aligned multiline text");
}

static void example_4_app_input_callback(InputEvent* input_event, void* ctx) {
    furi_assert(ctx);

    FuriMessageQueue* event_queue = ctx;
    furi_message_queue_put(event_queue, input_event, FuriWaitForever);
}

Example4App* example_4_app_alloc() {
    Example4App* app = malloc(sizeof(Example4App));

    app->view_port = view_port_alloc();
    app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));

    view_port_draw_callback_set(app->view_port, example_4_app_draw_callback, NULL);
    view_port_input_callback_set(app->view_port, example_4_app_input_callback, app->event_queue);

    app->gui = furi_record_open(RECORD_GUI);
    gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen);

    return app;
}

void example_4_app_free(Example4App* app) {
    furi_assert(app);

    view_port_enabled_set(app->view_port, false);
    gui_remove_view_port(app->gui, app->view_port);
    view_port_free(app->view_port);

    furi_message_queue_free(app->event_queue);

    furi_record_close(RECORD_GUI);
}

int32_t example_4_app(void *p) {
    UNUSED(p);
    Example4App* app = example_4_app_alloc();

    InputEvent event;

    while (1) {
        if (furi_message_queue_get(app->event_queue, &event, 100) == FuriStatusOk) {
            if (event.type == InputTypePress) {
                if (event.key == InputKeyBack)
                    break;
            }
        }
    }

    example_4_app_free(app);
    return 0;
}

Собираем новое приложение и переносим его на Flipper Zero.

./fbt fap_example_4
./fbt fap_deploy

flipper_6

Взглянем на результат:

Изменим наше приложение и добавим ещё пару кнопок.

Например, будем по-разному рендерить изображение на экране в зависимости от нажатой кнопки.

Пусть у нас будет три состояния интерфейса: рендерится только текст, рендерится только изображение, либо рендерится и то, и другое. Переключаться между этими режимами будем при долгом нажатии на кнопки «Влево» или «Вправо».

Введём в структуру нашего приложения переменную, которая будет отвечать за то, какой режим рендерится в данный момент. Назовем её draw_mode.

typedef enum {
    DRAW_ALL,
    DRAW_ONLY_TEXT,
    DRAW_ONLY_PICTURES,
    TOTAL_DRAW_MODES = 3,
} DrawMode;

struct Example4App {
    Gui* gui;
    ViewPort* view_port;
    FuriMessageQueue* event_queue;

    DrawMode draw_mode;
};

Чтобы draw_mode был доступен для нашей callback-функции рендера экрана, передадим в неё указатель на всю структуру приложения app в качестве контекста:

view_port_draw_callback_set(app->view_port, example_4_app_draw_callback, app);

Теперь изменим саму callback-функцию рендера. Пусть разные графические объекты рендерятся в зависимости от текущего значения draw_mode:

static void example_4_app_draw_callback(Canvas* canvas, void* ctx) {
    furi_assert(ctx);
    Example4App* app = ctx;

    canvas_clear(canvas);

    DrawMode mode = app->draw_mode;
    if (mode == DRAW_ONLY_PICTURES || mode == DRAW_ALL)
        canvas_draw_icon(canvas, 0, 29, &I_amperka_ru_logo_128x35px);
    if (mode == DRAW_ONLY_TEXT|| mode == DRAW_ALL) {
        canvas_set_font(canvas, FontPrimary);
        canvas_draw_str(canvas, 4, 8, "This is an example app!");
        canvas_set_font(canvas, FontSecondary);
        elements_multiline_text_aligned(canvas, 127, 15, AlignRight, AlignTop, "Some long long long long n aligned multiline text");
    }
}

В заключении обработаем новые события кнопок в бесконечном цикле главной функции приложения:

while (1) {
    if (furi_message_queue_get(app->event_queue, &event, 100) == FuriStatusOk) {
        if (event.type == InputTypePress) {
            if (event.key == InputKeyBack)
                break;
        } else if (event.type == InputTypeLong) {
            DrawMode mode = app->draw_mode;
            if (event.key == InputKeyLeft)
                app->draw_mode = (mode - 1 + TOTAL_DRAW_MODES) % TOTAL_DRAW_MODES;
            else if (event.key == InputKeyRight)
                app->draw_mode = (mode + 1) % TOTAL_DRAW_MODES;

            view_port_update(app->view_port);
        }
    }
}

Теперь если будет зарегистрировано событие длительного нажатия (InputTypeLong) кнопки «Влево» (InputKeyLeft) или «Вправо» (InputKeyRight), наш режим отрисовки app->draw_mode будет меняться от 0 до TOTAL_DRAW_MODES.

Функция view_port_update() запускает ререндер нашего интерфейса view_port. Функция не обязательная, операционная система сама производит ререндер раз в несколько миллисекунд, но мы можем форсировать это функцией.

Соберём обновлённое приложение, загрузим его на Флиппер, запустим и посмотрим результат:

Пример 5. Оповещения

Помимо дисплея Flipper Zero имеет и другой способ сообщать нам о происходящих в программе событиях — оповещения (Notifications). Нам доступно управление следующими встроенными девайсами:

  • RGB-cветодиод.
  • Вибромотор.
  • Пьезопищалка.

Продолжаем предыдущее приложение под новым именем example_5.

За оповещения в операционной системе Flipper Zero отвечает отдельный поток, и мы не можем вызывать его функции из нашего приложения напрямую. Но мы можем отсылать в этот поток сообщения — NotificationMessage. Из этих сообщений формируются последовательности NotificationSequence, которые уже непосредственно отправляются в поток.

Описание структур сообщений и их последовательностей находится в заголовочном файле notification/notification_messages.h, добавляем его в наше приложение.

В главной структуре указываем, что наше приложение собирается использовать оповещения NotificationApp:

struct Example5App {
    Gui* gui;
    ViewPort* view_port;
    FuriMessageQueue* event_queue;
    NotificationApp* notifications;

    DrawMode draw_mode;
};

В функции инициализации приложения example_5_app_alloc() перехватываем управление оповещениями:

app->notifications = furi_record_open(RECORD_NOTIFICATION);

А в функции освобождения памяти приложения example_5_app_free отдаём управление обратно:

furi_record_close(RECORD_NOTIFICATION);

Можно использовать и готовые последовательности сообщений, а можно сделать их самостоятельно, это несложно. Вы можете изучить соответствующий заголовочный файл и какие последовательности там доступны.

Создадим нашу последовательность сообщений для управления RGB-светодиодом. Назовем её example_led_sequence и разместим в заголовке нашего приложения.

Пусть светодиод мигнёт фиолетовым цветом RGB(255, 0, 255) три раза с интервалом 500 мс, а затем погаснет. Сообщение будет выглядеть следующим образом:

const NotificationSequence example_led_sequence = {
    &message_red_255,
    &message_blue_255,
    &message_delay_500,
    &message_red_0,
    &message_blue_0,
    &message_delay_500,
    &message_red_255,
    &message_blue_255,
    &message_delay_500,
    &message_red_0,
    &message_blue_0,
    &message_delay_500,
    &message_red_255,
    &message_blue_255,
    &message_delay_500,
    &message_red_0,
    &message_blue_0,
    NULL,
};

Последовательности сообщений для управления вибромотором составляются схожим образом. Создадим последовательность для вибромотора с именем example_vibro_sequence и разместим её в заголовке.

Пусть по сигналу наш вибромотор включится на 3 секунды, а затем выключится. Последовательность сообщений будет выглядеть так:

const NotificationSequence example_vibro_sequence = {
    &message_vibro_on,
    &message_do_not_reset,
    &message_delay_1000,
    &message_delay_1000,
    &message_delay_1000,
    &message_vibro_off,
    NULL,
};

По умолчанию максимально долгая описанная задержка составляет 1 секунду, поэтому мы три раза использовали сообщение message_delay_1000.

Теперь создадим последовательность сообщений для пьезодинамика. Назовем её example_sound_sequence.

Здесь нам уже доступна полная MIDI-клавиатура прямо из коробки! Описание всех нот и их частот можно посмотреть в заголовочном файле notification_messages_notes.h.

Добавим в наш Флиппер классическую мелодию звонка телефонов Nokia:

sound

Последовательность сообщений с данной мелодией выглядит так:

const NotificationSequence example_sound_sequence = {
    &message_note_e5,
    &message_delay_100,
    &message_note_d5,
    &message_delay_100,
    &message_note_fs4,
    &message_delay_250,
    &message_note_gs4,
    &message_delay_250,
    &message_note_cs5,
    &message_delay_100,
    &message_note_b4,
    &message_delay_100,
    &message_note_d4,
    &message_delay_250,
    &message_note_e4,
    &message_delay_250,
    &message_note_b4,
    &message_delay_100,
    &message_note_a4,
    &message_delay_100,
    &message_note_cs4,
    &message_delay_250,
    &message_note_e4,
    &message_delay_250,
    &message_note_a4,
    &message_delay_500,
    NULL,
};

Отлично! Теперь нужно решить, когда запускать данные оповещения. Пусть при нажатии на кнопку «Вверх» (InputKeyUp) включится светодиод, при нажатии на кнопку «Вниз» (InputKeyDown) включится вибромотор, а при нажатии на кнопку «Ок» (InputKeyOk) заиграет мелодия.

Добавляем обработку для новых кнопок в бесконечный цикл в главной функции нашего приложения example_5_app():

while (1) {
    if (furi_message_queue_get(app->event_queue, &event, 100) == FuriStatusOk) {
        if (event.type == InputTypePress) {
            if (event.key == InputKeyBack)
                break;
            else if (event.key == InputKeyUp)
                notification_message(app->notifications, &example_led_sequence);
            else if (event.key == InputKeyDown)
                notification_message(app->notifications, &example_vibro_sequence);
            else if (event.key == InputKeyOk)
                notification_message(app->notifications, &example_sound_sequence);

        } else if (event.type == InputTypeLong) {
            DrawMode mode = app->draw_mode;
            if (event.key == InputKeyLeft)
                app->draw_mode = (mode - 1 + TOTAL_DRAW_MODES) % TOTAL_DRAW_MODES;
            else if (event.key == InputKeyRight)
                app->draw_mode = (mode + 1) % TOTAL_DRAW_MODES;

            view_port_update(app->view_port);
        }
    }
}

Отправка сообщений осуществляется функцией notification_message() с указанием соответствующей последовательности.

Собираем новое приложение:

./fbt fap_example_5

Используя программу qFlipper, переносим новый FAP-файл из папки build на SD-карту в папку /apps/Misc. Или загружаем приложение командой ./fbt fap_deploy.

Запускаем приложение:

flipper_7

Смотрим на результат:

Пример 6. GPIO

На Flipper Zero 18 контактов GPIO, среди которых есть как пины питания, так и пины ввода-вывода. Логическое напряжение питания — 3,3 В, и пины нетолерантны к 5 В (за исключением пина iButton). По сути, пины Флиппера соответствуют пинам установленного в нём микроконтроллера STM32WB55 и обладают теми же настраиваемыми альтернативными функциями (ADC, USART, SPI и др.).

Распиновка Флиппера:

pinout

Подробное назначение пинов можно посмотреть в заголовочном файле furi_hal_resources.h. FURI HAL — специальный HAL Flipper Zero, который призван упростить для нас взаимодействие с железом.

В FURI HAL GPIO-структура имеет имя GpioPin. Без разборки Флиппера на куски нам доступны:

  • const GpioPin gpio_ext_pc0 — порт GPIOC, пин 0 (номер 16 на Флиппере).
  • const GpioPin gpio_ext_pc1 — порт GPIOC, пин 1 (номер 15 на Флиппере).
  • const GpioPin gpio_ext_pc3 — порт GPIOC, пин 3 (номер 7 на Флиппере).
  • const GpioPin gpio_ext_pb2 — порт GPIOB, пин 2 (номер 6 на Флиппере).
  • const GpioPin gpio_ext_pb3 — порт GPIOB, пин 3 (номер 5 на Флиппере).
  • const GpioPin gpio_ext_pa4 — порт GPIOA, пин 4 (номер 4 на Флиппере).
  • const GpioPin gpio_ext_pa6 — порт GPIOA, пин 6 (номер 3 на Флиппере).
  • const GpioPin gpio_ext_pa7 — порт GPIOA, пин 7 (номер 2 на Флиппере).
  • const GpioPin ibutton_gpio — порт GPIOB, пин 14 (номер 17 на Флиппере).

Также доступны пины с функцией USART по умолчанию:

  • const GpioPin gpio_usart_tx — порт GPIOB, пин 6 (номер 13 на Флиппере).
  • const GpioPin gpio_usart_rx — порт GPIOB, пин 7 (номер 14 на Флиппере).

Ещё есть пины интерфейса SWD (Serial Wire Debug) для отладки, маркированные на корпусе как SIO, SWC. Все остальные пины микроконтроллера используются для управления начинкой Flipper Zero: дисплеем, кнопками, USB, NFC, I²C, SPI и т. д.

Сделаем приложение, через которое мы сможем управлять GPIO. Сперва сделаем простой DigitalWrite, DigitalRead. Читать значение будем с пина А6, а писать значение в пин А7.

Подключим к Флипперу простую кнопку к пину А6 и светодиод к пину А7. Максимальный ток на пине — 20 мА, для светодиода хватит. Питание берём с шины 3,3 В. Установим светодиод и кнопку на макетную плату:

breadboard_1

Назовём новое приложение example_6 и сделаем его на основе нашего предыдущего примера номер 4. Предварительно уберём из приложения всё, что касается оповещений, рендера графических элементов и обработки кнопок, чтобы остался пустой интерфейс.

Для управления GPIO нам нужен HAL Флиппера. Подключаем файл furi_hal.h в заголовок нашего приложения.

В главной структуре Example6App нашего приложения создадим два пина для входа и выхода: input_pin, output_pin и две булевы переменные для хранения текущих значений на этих пинах: input_value, output_value.

Наш заголовочный файл принимает следующий вид:

#pragma once

#include <furi.h>
#include <furi_hal.h>
#include <gui/gui.h>

struct Example6App {
    Gui* gui;
    ViewPort* view_port;
    FuriMessageQueue* event_queue;

    const GpioPin* input_pin;
    const GpioPin* output_pin;

    bool input_value;
    bool output_value;
};

typedef struct Example6App Example6App;

В функции инициализации приложения example_6_app_alloc() задаём номера пинов. Функцией furi_hal_gpio_init() инициалзируем пины. Для ввода устанавливаем режим GpioModeInput и включаем подтяжку GpioPullUp, а для вывода режим GpioModeOutputPushPull и отключаем подтяжку GpioPullNo. Оба пина опрашиваются на максимальной скорости GpioSpeedVeryHigh:

app->input_pin = &gpio_ext_pa6;
app->output_pin = &gpio_ext_pa7;

furi_hal_gpio_init(app->input_pin, GpioModeInput, GpioPullUp, GpioSpeedVeryHigh);
furi_hal_gpio_init(app->output_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);

В главной функции приложения example_6_app() (и по совместительству в нашей точке входа) считываем и отправляем соответствующие значения в бесконечном цикле:

furi_hal_gpio_write(app->output_pin, app->output_value);
app->input_value = furi_hal_gpio_read(app->input_pin);

Пусть выходное значение зависит от состояния кнопки «Ок» Флиппера. Кнопка нажата — сигнал есть, отжата — сигнала нет. Как и прежде, клавишей «Назад» завершаем работу приложения. Добавим соответствующую обработку кнопки «Ок» в бесконечный цикл нашей программы:

if (furi_message_queue_get(app->event_queue, &event, 100) == FuriStatusOk) {
    if (event.key == InputKeyBack) {
        if (event.type == InputTypePress)
            break;

    } else if (event.key == InputKeyOk) {
        if (event.type == InputTypePress)
            app->output_value = true;
        else if (event.type == InputTypeRelease)
            app->output_value = false;
    }

Наконец, добавим немного графики в callback-функцию отрисовки интерфейса. Просто выведем текстом текущее входное и выходное значение. Для отрисовки больших цифр можно использовать шрифт FontBigNumbers. В качестве контекста передаём в функцию отрисовки главную структуру приложения.

static void example_6_app_draw_callback(Canvas* canvas, void* ctx) {
    furi_assert(ctx);
    Example6App* app = ctx;

    canvas_clear(canvas);
    canvas_set_font(canvas, FontSecondary);
    elements_multiline_text_aligned(canvas, 32, 17, AlignCenter, AlignTop, "Output PA7:");
    elements_multiline_text_aligned(canvas, 96, 17, AlignCenter, AlignTop, "Input PA6:");

    canvas_set_font(canvas, FontBigNumbers);
    elements_multiline_text_aligned(canvas, 32, 32, AlignCenter, AlignTop, app->output_value ? "1" : "0");
    elements_multiline_text_aligned(canvas, 96, 32, AlignCenter, AlignTop, app->input_value ? "1" : "0");
}

Интерфейс будет выглядеть так:

flipper_8

Собираем новое приложение и загружаем его на Флиппер:

./fbt fap_example_6
./fbt fap_deploy

Протестируем приложение на Флиппере:

PWM и ADC

С генерацией ШИМ-сигналов всё обстоит намного сложнее. Здесь уже не обойтись одной-двумя функциями из FURI HAL, а сам код сильно разрастается.

В прошивке Flipper Zero уже есть приложение Signal Generator для генерации ШИМ-сигнала на пинах PA7 и PA4. Вы можете самостоятельно изучить исходный код для генерации ШИМ в директории applications/plugins/signal_generator/ и реплицировать его в ваше приложение.

А вот официальной документации на чтение аналоговых сигналов пока нет. Кроме этого альтернативные функции аналого-цифрового преобразователя на пинах ещё не имплементированы в FURI HAL. Однако сам ADC на микроконтроллере STM32 и его возможности никуда от нас не делись.

На просторах интернета мы нашли пример использования ADC. Мы разместили в репозитории с примерами flipperzero-examples приложение adc_example, которое cчитывает аналоговое значение с пина PC3 и выводит его на экран. Код ещё нуждается в доработке, и вы можете использовать его в своих приложениях, однако мы советуем дождаться официальной документации и примеров.

Опорным напряжением является выборочно или 2.5 В или 2.048 В. Подключив к флипперу потенциометр и взяв питание с пина 3.3 В понадобится простой делитель напряжения в пределах тысячи Ом. Разрешение АЦП — 12 бит.

Читаем напряжение от 0 до 2.5В на пине PC3 и меняем его потенциометром:

Заключение

На этом мы заканчиваем базовое знакомство с пользовательскими приложениями для Flipper Zero.

Покопавшись в документации, нам удалось зайти подальше банального «Hello, world!» и написать несколько приложений для примера работы с GUI, кнопками и встроенной периферией Флиппера — RGB-светодиодом, вибромотором и баззером.

Ждём обновления официальной документации гаджета и надеемся, что наши примеры помогут вам в создании своих приложений для Flipper Zero!

Полезные ссылки

  • Гаджет Flipper Zero в каталоге Амперки
  • Посмотреть все проекты

Привет всем! Одним из моих хобби является реверс инжиниринг электронных устройств. После небольшой задержки мой Flipper Zero наконец-то прибыл по почте. Давненько я хотел затестить его, а, заодно, рассказать вам, что с его помощью можно сделать.

Вот так выглядит упаковка после вскрытия. Он содержит устройство, USB-кабель, руководство по быстрому запуску (в основном указывающее на веб-сайт Flipper Zero) и наклейку Flipper «Взломай планету».

Флиппер Зеро - Пакет

Несмотря на то, что над программным обеспечением все еще работают, оно уже кажется довольно отточенным и интуитивно понятным.

Имейте в виду, что вам нужна карта microSD для обновления до последней версии прошивки и хранения ваших данных.

Флиппер Зеро - Пакет

Некоторая информация в этом посте быстро устареет из-за текущей скорости обсуждений и создаваемых хаков.

qFlipper — настольное приложение-компаньон

Flipper Zero поставляется с сопутствующим приложением для установки прошивки.

Flipper Zero - файловый менеджер

Обновление прошивки прошло очень гладко. Совсем скоро появятся приложения для Android и iOS.

Также доступны бета-версии, которые включают будущие обновления функций, такие как файловый менеджер для копирования файлов.

Flipper Zero - файловый менеджер

Скорее всего, когда вы это читаете, последняя версия qFlipper уже включает файловый менеджер.

NFC

Первой особенностью, которую я исследовал, были возможности NFC, протестировав следующие устройства:

  1. Физическая карта — вау, я вижу номера своих кредитных карт!
  2. Apple Watch — вау, я вижу номера карт!
  3. Airtags — удалось прочитать идентификатор устройства
  4. Ски-пассы и другие случайные вещи — захватывает NFC UID без проблем

Все они работали. Существует также режим эмуляции, который позволяет вам эмулировать сохраненное устройство — будьте осторожны и осознайте риски, связанные с этим (также, очевидно, не делайте ничего незаконного).

Для дебетовых/кредитных карт и Apple Watch (после открытия для сканирования карты в кошельке) можно было прочитать номер карты с устройств!

Чтение NFC

На приведенном выше снимке экрана показан пример старой карты предоплаты. Несмотря на то, что очевидно, что это возможно, довольно страшно осознавать, насколько это просто на самом деле.

Это действительно заставляет задуматься о том, чтобы инвестировать в рукава, которые защищают карты, чтобы предотвратить считывание номеров ваших кредитных карт произвольными устройствами.

RFID

Flipper Zero без проблем считывает брелоки и карты. Он также может эмулировать ранее отсканированный брелок, что очень удобно. Существует также функция записи, которая позволяет, например, записывать информацию о сканированном RFID-чипе с одного брелока на другой.

Одна вещь, которую я узнал, это то, что на самом деле есть люди, у которых под кожей есть RFID-имплантаты! Я не шучу!

Инфракрасный

Инфракрасная функция очень проста в использовании. Например, легко захватывать и записывать команды с вашего собственного пульта дистанционного управления. После этого вы можете переиграть их.

Плохой USB

Bad-USB — это функция, которая превращает Flipper Zero в USB-устройство, такое как клавиатура, и можно отправлять заранее определенную последовательность команд.

Пример сценария по умолчанию, поставляемый с устройством, просто открывает блокнот и записывает следующий текст:

Пример плохого USB

Если вы знакомы с BashBunny или Rubber Ducky, это будет выглядеть довольно знакомо, и вы также можете использовать сценарии из первого для запуска на Flipper Zero.

Радио

Эта функция поставляется с частотным анализатором, который я нахожу очень удобным. Я попытался клонировать свой брелок для ключей от машины и смог проанализировать и записать последовательность, но мне еще не удалось воспроизвести ее, чтобы действительно открыть двери. Это, вероятно, означает, что у моего брелока есть средства защиты (например, подвижный ключ) — это полезно знать.

Кроме того, будьте осторожны, делая такие вещи, потому что современные брелки имеют вращающиеся ключи, и вы можете заблокировать свой собственный брелок, рассинхронизировав его! В конце концов, помните, что Flipper Zero — это образовательное устройство, поэтому не используйте его для плохих дел или чего-то важного, на что вы действительно полагаетесь.

Есть видеоролики, в которых люди открывают крышку зарядки своего Tesla, потому что все Tesla используют один и тот же ключ для ее открытия.

Разное и пользовательский код

Flipper Zero имеет несколько других функций и уловок! Например, вы можете сыграть в Snake или использовать устройства как устройство U2F+множество других вещей.

Вывод

В целом, продукт очень хорош и уже отполирован, и будущие обновления программного обеспечения и прошивки должны улучшить его.

Понравилась статья? Поделить с друзьями:
  • Finger pulse oximeter инструкция на русском
  • Finetest инструкция по на русском
  • Finetest auto coding premium инструкция
  • Finepix f660exr инструкция на русском
  • Finecut 9 инструкция на русском