--- title: "π ΠΠ°ΠΊ ΡΠΎΠ·Π΄Π°ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ Flipper Zero" date: 2023-03-27T21:42:08+03:00 draft: false tags: [tutorial, development, c, flipper zero] --- **ΠΡΠΎ ΡΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²ΠΎ ΠΏΠΎΠ»Π½Π°Ρ ΠΊΠΎΠΏΠΈΡ [ΡΡΠ°ΡΡΠΈ](https://amperka.ru/blogs/projects/flipper-zero-app-programming-tutorial) Ρ ΡΠ°ΠΉΡΠ° amperka.ru**. ΠΠ²ΡΠΎΡ: **ΠΠ°ΠΊΡΠΈΠΌ ΠΠ°Π½ΠΈΠ»ΠΈΠ½**. ΠΠ°ΠΏΠΈΡΠ°Π½ΠΎ: 25.01.2023 Π³ΠΎΠ΄Π°. # ΠΠ°ΠΊ ΡΠΎΠ·Π΄Π°ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ Flipper Zero ΠΡΠΈΠ²Π΅Ρ! Π ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅ ΠΌΡ ΡΠ°Π·Π±Π΅ΡΡΠΌΡΡ, ΠΊΠ°ΠΊ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ Flipper Zero! Π‘Π΅ΡΠ΄ΡΠ΅ΠΌ Π³Π°Π΄ΠΆΠ΅ΡΠ° Flipper Zero ΡΠ²Π»ΡΠ΅ΡΡΡ 32-Π±ΠΈΡΠ½ΡΠΉ ΠΌΠΈΠΊΡΠΎΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅Ρ STM32. ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΠ΅Π»ΡΡΠΈΠ½Π° ΡΠΈΠ»ΡΠ½ΠΎ ΠΎΡΠ»ΠΈΡΠ°Π΅ΡΡΡ ΠΎΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΡΠΈΠ²ΡΡΠ½ΡΡ Π½Π°ΠΌ Arduino. ΠΠΎΠΌΠΈΠΌΠΎ ΡΠ°ΠΌΠΎΠ³ΠΎ ΠΌΠΈΠΊΡΠΎΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ° Π²ΠΎ Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ΅ Π΅ΡΡΡ ΡΠ°Π΄ΠΈΠΎΠΌΠΎΠ΄ΡΠ»Ρ, NFC-ΠΌΠΎΠ΄ΡΠ»Ρ, ΠΊΠ°ΡΠ΄ΡΠΈΠ΄Π΅Ρ, ΠΌΠΎΠ΄ΡΠ»Ρ Bluetooth, Π΄ΠΈΡΠΏΠ»Π΅ΠΉ, ΠΌΠΈΠΊΡΠΎΡΡ Π΅ΠΌΠ° ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΊΠΎΠΉ ΠΈ ΡΠ°ΠΊ Π΄Π°Π»Π΅Π΅. ΠΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎ ΡΠΏΡΠ°Π²Π»ΡΡΡ Π²ΡΠ΅ΠΌΠΈ ΡΡΠΈΠΌΠΈ ΡΡΡΡΠΎΠΉΡΡΠ²Π°ΠΌΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΡΠΈΠΊΠ»Π΅ `loop`, ΠΊΠ°ΠΊ ΡΡΠΎ ΠΎΠ±ΡΡΠ½ΠΎ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ Π² ΡΡΠ΅Π΄Π΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ Arduino, ΡΠΆΠ΅ Π½Π΅Π»ΡΠ·Ρ. ΠΠ° ΠΏΠΎΠΌΠΎΡΡ ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΡ [ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ° ΡΠ΅Π°Π»ΡΠ½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ](https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_%D1%80%D0%B5%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%B8) ΠΈΠ»ΠΈ RTOS (real-time operating system). RTOS ΡΠ°Π·Π³ΡΠ°Π½ΠΈΡΠΈΠ²Π°Π΅Ρ Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ°ΡΡΠΈ Π²ΡΠ΅ΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π² ΡΠ°Π·Π½ΡΠ΅ ΠΏΠΎΡΠΎΠΊΠΈ ΠΈ ΡΠ°ΠΌΠ° ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅Ρ ΠΏΠ΅ΡΠ΅ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρ Π½ΠΈΠΌΠΈ, Π° ΡΠ°ΠΊΠΆΠ΅ Π²ΡΠ΄Π΅Π»ΡΠ΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² ΡΠ΅ΡΡΡΡΡ. Π’Π°ΠΊ ΠΊΠ°ΠΊ Π€Π»ΠΈΠΏΠΏΠ΅Ρ ΠΏΠΎΡΡΡΠΎΠ΅Π½ Π½Π° ΡΠΈΠΏΠ΅ STM32, Π² Π½ΡΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ, Π½Π°Π²Π΅ΡΠ½ΠΎΠ΅, ΡΠ°ΠΌΠ°Ρ ΠΏΠΎΠΏΡΠ»ΡΡΠ½Π°Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½ΠΊΠ° Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ ΡΠΈΠΏΠ° ΠΌΠΈΠΊΡΠΎΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠΎΠ² β [FreeRTOS](https://ru.wikipedia.org/wiki/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](https://docs.brew.sh/Homebrew-on-Linux). ΠΡ Π° Π΅ΡΠ»ΠΈ Π²Ρ ΡΠΎΠ±ΠΈΡΠ°Π΅ΡΠ΅ ΠΏΡΠΎΡΠΈΠ²ΠΊΡ Π½Π° Windows ΠΈ ΡΡΠΎΠ»ΠΊΠ½ΡΠ»ΠΈΡΡ Ρ ΡΡΡΠ΄Π½ΠΎΡΡΡΠΌΠΈ, ΠΏΠΎΠΏΡΠΎΠ±ΡΠΉΡΠ΅ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ [WSL](https://ubuntu.com/wsl). ΠΠΈΡΠ°ΡΡ ΠΊΠΎΠ΄ Π΄Π»Ρ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ Π½Π° ΡΠ·ΡΠΊΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ **C** Π½Π° Π½Π°ΡΡΠΎΠ»ΡΠ½ΠΎΠΌ ΠΊΠΎΠΌΠΏΡΡΡΠ΅ΡΠ΅ ΠΏΠΎΠ΄ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ Linux, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ Ubuntu 22.04.1 LTS (Jammy Jellyfish). ## Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΠ³ΠΎ ΡΠΎΡΡΠ° ΠΠ΅ΡΠ΅Π΄ ΡΠ΅ΠΌ ΠΊΠ°ΠΊ ΠΏΠΈΡΠ°ΡΡ Π½ΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π½Π°ΠΌ ΠΏΡΠΈΠ΄ΡΡΡΡ Π½Π°ΡΡΠΈΡΡΡΡ ΡΠΎΠ±ΠΈΡΠ°ΡΡ Π²ΡΡ ΠΏΡΠΎΡΠΈΠ²ΠΊΡ ΠΌΠΈΠΊΡΠΎΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ°. Π‘ΠΏΠ΅ΡΠ²Π° ΡΠΊΠ°ΡΠ°Π΅ΠΌ ΠΈ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΠΌ ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ [qFlipper](https://docs.flipperzero.one/basics/firmware-update#yK3zg) Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ Π€Π»ΠΈΠΏΠΏΠ΅ΡΠΎΠΌ ΡΠ΅ΡΠ΅Π· Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ. ΠΡ Π±ΡΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ qFlipper Π΄Π»Ρ ΡΠ΄ΠΎΠ±Π½ΠΎΠΉ Π·Π°Π³ΡΡΠ·ΠΊΠΈ Π½Π°ΡΠΈΡ Π³ΠΎΡΠΎΠ²ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π° SD-ΠΊΠ°ΡΡΡ Π²ΠΎ Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ΅. Π‘ΠΊΠ°ΡΠΈΠ²Π°Π΅ΠΌ Π²Π΅ΡΡΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π΄Π»Ρ OS Linux ΠΊΡΠ΄Π°-Π½ΠΈΠ±ΡΠ΄Ρ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ Π² Π΄ΠΎΠΌΠ°ΡΠ½ΡΡ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ. ΠΠ° ΠΌΠΎΠΌΠ΅Π½Ρ Π²ΡΡ ΠΎΠ΄Π° ΡΡΠ°ΡΡΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° qFlipper ΠΈΠΌΠ΅Π΅Ρ Π²Π΅ΡΡΠΈΡ 1.2.2, Π° ΡΠ°ΠΌ ΡΠ°ΠΉΠ» Π½Π°Π·ΡΠ²Π°Π΅ΡΡΡ `qFlipper-x86_64-1.2.2.AppImage`. Π’Π°ΠΊΠΆΠ΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΡ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ `libfuse2`, Π΅ΡΠ»ΠΈ Π΅Ρ Π½Π΅Ρ Π² Π²Π°ΡΠ΅ΠΉ ΡΠΈΡΡΠ΅ΠΌΠ΅. ```sh 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-ΠΏΠΎΡΡΡ Π΄Π»Ρ ΠΎΠ±ΡΡΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ. ΠΠ½Π°ΡΠ΅ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡ Π²Π΅ΡΡΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΡ ΠΎΡ Π»ΠΈΡΠ° ΡΡΠΏΠ΅ΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ, ΡΡΠΎ Π½Π΅Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ Π΄Π»Ρ Π²ΡΠ΅ΠΉ ΡΠΈΡΡΠ΅ΠΌΡ Π² ΡΠ»ΡΡΠ°Π΅ Π½Π΅ΠΎΡΡΠΎΡΠΎΠΆΠ½ΠΎΡΡΠΈ. ```sh sudo chmod +x qFlipper-x86_64-1.2.2.AppImage ./qFlipper-x86_64-1.2.2.AppImage rules install ``` ΠΠ°ΠΏΡΡΡΠΈΡΠ΅ qFlipper ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠΈΡΠ΅ Π²Π°Ρ Flipper Zero ΠΊ ΠΊΠΎΠΌΠΏΡΡΡΠ΅ΡΡ ΠΏΠΎ USB. ```sh ./qFlipper-x86_64-1.2.2.AppImage ``` Π£Π±Π΅Π΄ΠΈΡΠ΅ΡΡ, ΡΡΠΎ Π²Π°Ρ Π€Π»ΠΈΠΏΠΏΠ΅Ρ ΠΏΠΎΡΠ²ΠΈΠ»ΡΡ Π² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ qFlipper, Π²ΡΡ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΠΊΠ°ΠΊ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΎ ΠΈ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π° ΡΠ²Π΅ΠΆΠ°Ρ ΠΏΡΠΎΡΠΈΠ²ΠΊΠ°. ![](/content/images/2023/flipper-app/1.png) ΠΠ»Ρ Π±ΡΡΡΡΠΎΠΉ ΠΈ ΡΠ΄ΠΎΠ±Π½ΠΎΠΉ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΠ³ΠΎ ΡΠΎΡΡΠ° ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡ Π΄ΠΈΡΠΏΠ΅ΡΡΠ΅Ρ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ² [Homebrew](https://docs.brew.sh/Homebrew-on-Linux). Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ Homebrew: ```sh sudo apt install curl /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ``` ΠΠΎΡΠ»Π΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ Π΄ΠΎΠ±Π°Π²ΡΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ `PATH`, `MANPATH` Π΄Π»Ρ Homebrew. ΠΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ, Π΄ΠΎΠ±Π°Π²ΠΈΠ² ΡΠ»Π΅Π΄ΡΡΡΡΡ ΡΡΡΠΎΠΊΡ Π² ΡΠ°ΠΉΠ»Π΅ `.profile` Π΄Π»Ρ Π²Π°ΡΠ΅Π³ΠΎ ΡΠ·Π΅ΡΠ°: ```sh echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> /home/$USER/.profile ``` ΠΡΠΎΡΠΈΠ²ΠΊΠ° Π΄Π»Ρ Flipper Zero Ρ ΡΠ°Π½ΠΈΡΡΡ Π² ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΈ [flipperzero-firmware](https://github.com/flipperdevices/flipperzero-firmware) Π½Π° GitHub. Π‘ΠΊΠ»ΠΎΠ½ΠΈΡΡΠΉΡΠ΅ ΠΊ ΡΠ΅Π±Π΅ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ ΠΏΡΠΎΡΠΈΠ²ΠΊΠΈ Flipper Zero ΡΠΎ Π²ΡΠ΅ΠΌΠΈ ΠΌΠΎΠ΄ΡΠ»ΡΠΌΠΈ. Π Π΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ Π·Π°ΠΉΠΌΠ΅Ρ ΡΡΡΡ Π±ΠΎΠ»ΡΡΠ΅ 2 ΠΠ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π°. ```sh git clone --recursive https://github.com/flipperdevices/flipperzero-firmware.git ``` Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ ΠΏΠ΅ΡΠ΅ΡΠΈΡΠ»Π΅Π½Π½ΡΠΉ Π² ΠΎΠΏΠΈΡΠ°Π½ΠΈΠΈ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ ΡΠΎΡΡ: ```sh sudo apt update sudo apt install openocd clang-format-13 dfu-util protobuf-compiler ``` ΠΠ΅ΡΠ΅ΠΉΠ΄ΠΈΡΠ΅ Π² Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ ΠΈ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ Π²ΡΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ ΠΏΠ°ΠΊΠ΅ΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Homebrew: ```sh cd flipperzero-firmware brew bundle --verbose ``` ΠΠΎΡΠΎΠ²ΠΎ! ΠΡΠΎΡΠΈΠ²ΠΊΠ° Π΄Π»Ρ Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ°, ΠΊΠ°ΠΊ ΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, ΡΠΎΠ±ΠΈΡΠ°ΡΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΡΠΈΠ»ΠΈΡΡ `fbt` (Flipper Build Tool). ΠΠ»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π· ΡΠΎΠ±ΠΈΡΠ°ΡΡ Π²ΡΡ ΠΏΡΠΎΡΠΈΠ²ΠΊΡ ΡΠ΅Π»ΠΈΠΊΠΎΠΌ, ΠΎΠ΄Π½Π°ΠΊΠΎ ΠΏΡΠΈ ΠΏΠ΅ΡΠ²ΠΎΠΌ Π·Π°ΠΏΡΡΠΊΠ΅ ΡΡΠΈΠ»ΠΈΡΡ `fbt` Π±ΡΠ΄ΡΡ ΡΠΊΠ°ΡΠ°Π½Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ `gcc-arm` ΡΡΠ»ΡΠ΅ΠΉΠ½Ρ. Π‘ΠΎΠ±Π΅ΡΠΈΡΠ΅ ΠΏΡΠΎΡΠΈΠ²ΠΊΡ: ```sh ./fbt ``` ΠΡΠ΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ ΡΠ±ΠΎΡΠΊΠΈ ΠΈ Π±ΠΈΠ½Π°ΡΠ½ΡΠ΅ ΡΠ°ΠΉΠ»Ρ Π±ΡΠ΄ΡΡ ΠΏΠΎΠΌΠ΅ΡΠ΅Π½Ρ Π² Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ `./dist`. ## ΠΡΠΈΠΌΠ΅Ρ 1. ΠΡΠΎΡΡΠ΅ΠΉΡΠ΅Π΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΠΏΡΠΎΡΡΠ΅ΠΉΡΠ΅Π΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΡΠ΅ΠΌΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅. ΠΡ Π±ΡΠ΄Π΅ΠΌ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠΈΠΏΠ° FAP (Flipper Application Package). ΠΠΎΡΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΡΠΎΠ³ΠΎ ΡΠΈΠΏΠ° ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠΎΠ±ΠΎΠΉ ΡΠ°ΠΉΠ» ΡΠΎΡΠΌΠ°ΡΠ° `.fap`. ΠΠΎ ΡΡΡΠΈ, `.fap` ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ β ΡΡΠΎ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΡΠ°ΠΉΠ» `.elf` Ρ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΌΠΈ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΌΠΈ Π΄Π°Π½Π½ΡΠΌΠΈ. **ΠΡΡΠ°ΡΠΈ!** ΠΠ΅ΡΡ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΈΠ· ΡΡΠΎΠΉ ΡΡΠ°ΡΠΈ ΠΌΡ Π²ΡΠ»ΠΎΠΆΠΈΠ»ΠΈ Π½Π° GitHub Π² ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΈ [flipperzero-examples](https://github.com/amperka/flipperzero-examples). ΠΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΏΠΎΠΌΠ΅ΡΠ°ΡΡΡΡ Π² ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠ΅ ΠΏΠ°ΠΏΠΊΠΈ Π² ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΠΎ ΠΎΡΠ³Π°Π½ΠΈΠ·ΠΎΠ²Π°Π½Π½ΡΡ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ `applications_user`: ![](/content/images/2023/flipper-app/2.png) ΠΡΠΈΠ΄ΡΠΌΠ°ΠΉΡΠ΅ ΠΈΠΌΡ Π΄Π»Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΡ Π½Π°Π·Π²Π°Π»ΠΈ Π½Π°ΡΠ΅ ΠΏΠ΅ΡΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ `example_1`, ΡΡΠΈΠΌ ΠΆΠ΅ ΠΈΠΌΠ΅Π½Π΅ΠΌ Π½Π°Π·Π²Π°Π»ΠΈ ΠΈ ΠΏΠ°ΠΏΠΊΡ. Π Π½Π΅Ρ ΠΏΠΎΠΌΠ΅ΡΠ°ΡΡΡΡ Π²ΡΠ΅ ΡΠ°ΠΉΠ»Ρ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΎΡΠ½ΠΎΡΡΡΡΡ ΠΊ Π²Π°ΡΠ΅ΠΌΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ: ΠΈΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄, ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΈ ΠΏΡΠΎΡΠ΅Π΅. Π ΠΏΠ°ΠΏΠΊΠ΅ `example_1` ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ°ΠΉΠ» ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° Π½Π° ΡΠ·ΡΠΊΠ΅ Π‘ β `example_1_app.c`. ΠΠΎΡ ΠΊΠ°ΠΊ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΠΊΠΎΠ΄ ΠΏΡΠΎΡΡΠ΅ΠΉΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ```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** Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠΌΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΠΌΠΈ: ![](/content/images/2023/flipper-app/3.png) ΠΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠ΄Π½ΠΎ ΠΈΠ· ΡΠΆΠ΅ ΠΈΠΌΠ΅ΡΡΠΈΡ ΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ, Π½ΠΎ Π²ΡΠ΅Π³Π΄Π° Π»ΡΡΡΠ΅ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΡΡΠΎ-ΡΠΎ ΡΠ²ΠΎΡ. Π GIMP ΠΌΡ Π½Π°ΡΠΈΡΠΎΠ²Π°Π»ΠΈ Π²ΠΎΡ ΡΠ°ΠΊΠΎΠΉ ΡΠΌΠ°ΠΉΠ» Π² ΡΡΡΠ½ΡΡ ΠΎΡΠΊΠ°Ρ : ![](/content/images/2023/flipper-app/emoji_smile_icon_10x10px.png) ΠΠ°ΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠ²ΠΎΡ ΠΈΠΊΠΎΠ½ΠΊΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΈ Π² Paint. Π€Π°ΠΉΠ» ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΏΠΎΠΌΠ΅ΡΠ°Π΅ΠΌ Π² ΠΏΠ°ΠΏΠΊΡ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ `example_1`. ΠΠΎΠΌΠΈΠΌΠΎ ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° ΠΈ ΠΈΠΊΠΎΠ½ΠΊΠΈ Π½Π°ΠΌ Π½ΡΠΆΠ΅Π½ ΡΠ°ΠΉΠ» ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ β `application.fam`. ΠΡΠΎΡ ΡΠ°ΠΉΠ» ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΠΌ. ΠΠ°Ρ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈΠΌΠ΅Π΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ Π²ΠΈΠ΄: ```c 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** Π½Π° Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ΅. ΠΡΠ»ΠΈ Π²ΡΠ΅ ΡΠ°ΠΉΠ»Ρ Π½Π° ΠΌΠ΅ΡΡΠ΅, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°ΡΠΈΠ½Π°ΡΡ ΡΠ±ΠΎΡΠΊΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ![](/content/images/2023/flipper-app/4.png) Π ΡΠ΅ΡΠΌΠΈΠ½Π°Π»Π΅ ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄ΠΈΠΌ Π² ΠΊΠΎΡΠ½Π΅Π²ΡΡ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ ΠΏΡΠΎΡΠΈΠ²ΠΊΠΈ `flipperzero-firmware`. Π‘Π±ΠΎΡΠΊΠ° ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅ΡΡΡ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ `./fbt fap_{APPID}`, Π³Π΄Π΅ `{APPID}` β ΡΡΠΎ **ID**, ΡΠΊΠ°Π·Π°Π½Π½ΡΠΉ Π² `.fam`-ΡΠ°ΠΉΠ»Π΅ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ```sh ./fbt fap_example_1 ``` Π‘Π±ΠΈΠ»Π΄ΠΈΡΡ Π²ΡΠ΅ ΠΈΠΌΠ΅ΡΡΠΈΠ΅ΡΡ Π² ΠΏΡΠΎΡΠΈΠ²ΠΊΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ FAP ΠΌΠΎΠΆΠ½ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ `./fbt faps`. ΠΠΎΡΠΎΠ²ΠΎΠ΅ FAP-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ `build` Π² ΡΠΊΡΡΡΠΎΠΉ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ `.extapps`. ΠΠ°Ρ ΡΠ°ΠΉΠ» ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π½Π°Π·ΡΠ²Π°Π΅ΡΡΡ `example_1.fap`. ![](/content/images/2023/flipper-app/5.png) ΠΡΠΏΠΎΠ»ΡΠ·ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ qFlipper, ΠΏΠ΅ΡΠ΅Π½Π΅ΡΡΠΌ ΡΠ°ΠΉΠ» ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π½Π° SD-ΠΊΠ°ΡΡΡ Π² Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ `/apps/Misc`. Π€Π°ΠΉΠ» ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π½Π΅ΡΡΠΈ ΠΌΡΡΠΊΠΎΠΉ ΠΏΡΡΠΌΠΎ Π² ΠΎΠΊΠ½ΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ. ![](/content/images/2023/flipper-app/6.png) ΠΠΎΡΠ»Π΅ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π³ΠΎ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ Π²ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ FAP ΠΌΠΎΠΆΠ½ΠΎ ΡΠ±ΠΈΠ»Π΄ΠΈΡΡ ΠΈ ΠΏΠ΅ΡΠ΅Π½Π΅ΡΡΠΈ Π½Π° Π€Π»ΠΈΠΏΠΏΠ΅Ρ ΠΎΠ΄Π½ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ ΠΈΠ· ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ: ```sh ./fbt fap_deploy ``` ΠΠΎΡΠΎΠ²ΠΎ! Π’Π΅ΠΏΠ΅ΡΡ Π½Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΡΠ²ΠΈΠ»ΠΎΡΡ Π½Π° Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ΅ Π² ΡΠ°Π·Π΄Π΅Π»Π΅ `Misc`: ![](/content/images/2023/flipper-app/7.png) ΠΠ»Π°Π²Π½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ `example_1_app()` ΡΠ΅ΠΉΡΠ°Ρ ΠΏΡΡΡΠ°, ΠΏΠΎΡΡΠΎΠΌΡ ΠΏΡΠΈ Π·Π°ΠΏΡΡΠΊΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΠΏΡΠΎΡΡΠΎ Π·Π°Π²Π΅ΡΡΠΈΡ ΡΠ²ΠΎΡ ΡΠ°Π±ΠΎΡΡ ΠΈ ΠΌΡ Π½Π΅ ΡΠ²ΠΈΠ΄ΠΈΠΌ Π½ΠΈΠΊΠ°ΠΊΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π½Π° ΡΠΊΡΠ°Π½Π΅. Π‘ΠΌΠΎΡΡΠ΅ΡΡ Π²ΠΈΠ΄Π΅ΠΎ: https://youtu.be/qfpTYmIwJbA. ΠΠ°ΠΊ Π²ΠΈΠ΄Π½ΠΎ, Π²Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π²ΠΎΠ²ΡΠ΅ Π½Π΅ ΠΈΠΌΠ΅ΡΡ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° ΠΈ ΠΎΡΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΊΠ°ΠΊ Π±Ρ Β«Π·Π° ΠΊΡΠ»ΠΈΡΠ°ΠΌΠΈΒ». ΠΠΎ Ρ Π½Π°ΡΠ΅Π³ΠΎ Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ° Π΅ΡΡΡ ΡΠΊΡΠ°Π½ΡΠΈΠΊ, ΠΏΠΎΡΡΠΎΠΌΡ Π½Π΅Π»ΡΠ·Ρ Π½Π΅ ΡΠ΄Π΅Π»Π°ΡΡ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ. ## ΠΡΠΈΠΌΠ΅Ρ 2. ΠΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΠΠΎΠ±Π°Π²ΠΈΠΌ Π½Π°ΡΠ΅ΠΌΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ. Π§ΡΠΎΠ±Ρ Π½Π΅ ΠΏΡΡΠ°ΡΡΡΡ ΠΌΠ΅ΠΆΠ΄Ρ ΠΏΡΠ½ΠΊΡΠ°ΠΌΠΈ ΡΡΠ°ΡΡΠΈ, ΠΌΡ ΡΠ΄Π΅Π»Π°Π΅ΠΌ Π½ΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ `example_2`, Π½ΠΎ ΠΏΠΎ ΡΡΡΠΈ Π±ΡΠ΄Π΅ΠΌ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡΡ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅Π΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅. ΠΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠΌΠ΅ΡΡΠΈΠΌ Π² Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ `applications_user/example_2`. Π‘ΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ, ΡΠ°ΠΉΠ» Ρ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΌ ΠΊΠΎΠ΄ΠΎΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈΠΌΠ΅Π΅Ρ ΠΈΠΌΡ `example_2_app.c`. ΠΠ»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Π²Π°ΠΌ ΠΏΡΠΈΠ΄ΡΡΡΡ Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΠ°ΡΡΠΈΡΠΈΡΡ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π² Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» `example_2_app.h` Π΄Π»Ρ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ ΡΠΈΠΏΠΎΠ² Π΄Π°Π½Π½ΡΡ , ΡΡΡΡΠΊΡΡΡ ΠΈ ΠΏΡΠΎΡΠΎΡΠΈΠΏΠΎΠ² ΡΡΠ½ΠΊΡΠΈΠΉ. ΠΠΊΠ»ΡΡΠΈΠΌ ΡΠΆΠ΅ Π·Π½Π°ΠΊΠΎΠΌΡΠΉ Π½Π°ΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» ΡΠ΄ΡΠ° `furi.h`. ΠΠ»Ρ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ `gui/gui.h`. ```c #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` ΡΠ΅ΠΏΠ΅ΡΡ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ°ΠΊ: ```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; } ``` Π Π°Π·Π±Π΅ΡΡΠΌΡΡ, ΡΡΠΎ Π΅ΡΡΡ ΡΡΠΎ. ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎΠ΄ Π€Π»ΠΈΠΏΠΏΠ΅Ρ ΠΎΡΠ΅Π½Ρ ΡΡΠ΅Π±ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ ΠΊ ΡΠ΅ΡΡΡΡΠ°ΠΌ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΡ, ΠΈ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ Π·Π° ΡΡΠΈΠΌ ΡΠ»Π΅Π΄ΠΈΡΡ. ΠΡΠΎ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ, ΡΡΠΎΠ±Ρ Π½Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠ°Π±ΠΎΡΠ°Π»ΠΎ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎ ΠΈ Π½Π΅ Π²ΡΠ·ΡΠ²Π°Π»ΠΎ Π·Π°Π²ΠΈΡΠ°Π½ΠΈΠΉ ΠΈ Π³Π»ΡΠΊΠΎΠ². ΠΠΎΡΡΠΎΠΌΡ, Π΅ΡΠ»ΠΈ ΠΌΡ Ρ ΠΎΡΠΈΠΌ ΡΡΠΎ-ΡΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ, ΡΠΎ ΡΠ°ΠΌΠΎΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎ Π²ΡΠ΄Π΅Π»ΡΠ΅ΠΌ ΠΏΠΎΠ΄ ΡΡΠΎ ΠΏΠ°ΠΌΡΡΡ, Π° ΠΊΠΎΠ³Π΄Π° ΡΠ΄Π°Π»ΡΠ΅ΠΌ β ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅ΠΌ. ΠΠΏΠΈΡΡΠ²Π°Π΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ Π²ΡΠ΄Π΅Π»ΡΡΡ ΠΏΠ°ΠΌΡΡΡ ΠΏΠΎΠ΄ ΡΡΡΡΠΊΡΡΡΡ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ Π΅Π³ΠΎ: ```c Example2App* example_2_app_alloc() ``` Π ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅Ρ Π·Π°Π½ΡΡΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ ΠΏΠ°ΠΌΡΡΡ: ```c void example_2_app_free(Example2App* app) ``` Π ΡΡΠ½ΠΊΡΠΈΠΈ Π²ΡΠ΄Π΅Π»Π΅Π½ΠΈΡ ΠΏΠ°ΠΌΡΡΠΈ ΠΌΡ ΡΠ½Π°ΡΠ°Π»Π° Π²ΡΠ΄Π΅Π»ΡΠ΅ΠΌ ΠΏΠ°ΠΌΡΡΡ ΠΏΠΎΠ΄ ΡΡΡΡΠΊΡΡΡΡ `app` ΡΠΈΠΏΠ° `Example2App` Π΄Π»Ρ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΠ°ΡΠ΅ΠΌ Π²ΡΠ΄Π΅Π»ΡΠ΅ΠΌ ΠΏΠ°ΠΌΡΡΡ Π΄Π»Ρ `view_port`: ```c app->view_port = view_port_alloc(); ``` ΠΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΡΠ΅ΠΊΡΡΠΈΠΉ `Gui` Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ° β `gui`. ΠΠ΅ΡΠ΅Ρ Π²Π°ΡΡΠ²Π°Π΅ΠΌ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ `Gui` ΠΈ Π³ΠΎΠ²ΠΎΡΠΈΠΌ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΠ΅, ΡΡΠΎ Ρ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π΅ΡΡΡ Π½Π΅ΠΊΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ c ΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΎΠΉ ΡΠΊΡΠ°Π½Π° `view_port` ΠΈ ΠΌΡ Ρ ΠΎΡΠΈΠΌ Π΅Π³ΠΎ ΠΎΡΠΎΠ±ΡΠ°Π·ΠΈΡΡ. ```c app->gui = furi_record_open(RECORD_GUI); gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen); ``` Π ΡΡΠ½ΠΊΡΠΈΠΈ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½ΠΈΡ ΠΏΠ°ΠΌΡΡΠΈ ΠΌΡ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ, ΡΠ°Π±ΠΎΡΠ°Π΅ΠΌ Π² ΠΎΠ±ΡΠ°ΡΠ½ΠΎΠΌ Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠΈ. ΠΡΠΊΠ»ΡΡΠ°Π΅ΠΌ ΡΠ΅Π½Π΄Π΅Ρ Π½Π°ΡΠ΅Π³ΠΎ `view_port`: ```c view_port_enabled_set(app->view_port, false); ``` ΠΡΠΊΠ»ΡΡΠ°Π΅ΠΌ `view_port` ΠΎΡ `Gui` ΠΈ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅ΠΌ ΠΏΠ°ΠΌΡΡΡ, Π·Π°Π½ΡΡΡΡ `view_port`: ```c gui_remove_view_port(app->gui, app->view_port); view_port_free(app->view_port); ``` Π ΠΊΠΎΠ½ΡΠ΅ ΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΌ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΌ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠΌ ΠΎΡ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΠ΅: ```c furi_record_close(RECORD_GUI); ``` Π’Π°ΠΊ ΠΊΠ°ΠΊ ΠΌΡ ΠΏΠΈΡΠ΅ΠΌ Π½Π° Π‘ ΠΈ ΡΠ΅Π³ΡΠ»ΡΡΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ, Π² ΡΠ΄ΡΠ΅ FURI ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ ΠΊΡΠ°ΠΉΠ½Π΅ ΠΏΠΎΠ»Π΅Π·Π½Π°Ρ Π΄Π»Ρ Π½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ `furi_assert()`, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠΊΡΡΡΠ΅Π½Π½ΠΎ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΈΡ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈ Π²ΡΠ΄Π°ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅, Π΅ΡΠ»ΠΈ ΠΌΡ Π²Π΄ΡΡΠ³ ΠΏΠ΅ΡΠ΅Π΄Π°Π΄ΠΈΠΌ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΠΏΡΡΡΠΎΠΉ ΡΡΠ°ΡΡΠΎΠΊ ΠΏΠ°ΠΌΡΡΠΈ. Π’ΠΎΡΠΊΠΎΠΉ Π²Ρ ΠΎΠ΄Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π½Π° ΡΡΠΎΡ ΡΠ°Π· Π±ΡΠ΄Π΅Ρ ΡΡΠ½ΠΊΡΠΈΡ Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ `example_2_app`: ```c 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`. ```c 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", ) ``` Π‘ΠΎΠ±ΠΈΡΠ°Π΅ΠΌ Π½ΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅: ```sh ./fbt fap_example_2 ``` ΠΡΠΏΠΎΠ»ΡΠ·ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ qFlipper, ΠΏΠ΅ΡΠ΅Π½Π΅ΡΡΠΌ Π½ΠΎΠ²ΠΎΠ΅ FAP-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠ· ΠΏΠ°ΠΏΠΊΠΈ `build` Π½Π° SD-ΠΊΠ°ΡΡΡ Π² ΠΏΠ°ΠΏΠΊΡ `/apps/Misc`. ΠΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΠ΅ΡΠΌΠΈΠ½Π°Π» ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Ρ `./fbt fap_deploy`. ΠΠ°Ρ ΠΎΠ΄ΠΈΠΌ Π½ΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² ΡΠΏΠΈΡΠΊΠ΅ ΠΈ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌ Π΅Π³ΠΎ: ![](/content/images/2023/flipper-app/8.png) Π‘Π΅ΠΉΡΠ°Ρ Π΄Π»Ρ Π½Π°ΡΠ΅Π³ΠΎ `ViewPort` Π½Π΅ ΠΎΠΏΠΈΡΠ°Π½Ρ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΈ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ². ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΏΡΠΎΡΡΠΎ ΠΎΡΠΎΠ±ΡΠ°Π·ΠΈΡ ΠΏΡΡΡΠΎΠΉ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ 10 ΡΠ΅ΠΊΡΠ½Π΄ ΠΈ Π·Π°Π²Π΅ΡΡΠΈΡ ΡΠ°Π±ΠΎΡΡ. Π‘ΠΌΠΎΡΡΠ΅ΡΡ Π²ΠΈΠ΄Π΅ΠΎ: https://youtu.be/7LlnIKkdM8s. ## ΠΡΠΈΠΌΠ΅Ρ 3. Π’Π΅ΠΊΡΡ ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΠΎΠ±Π°Π²ΠΈΠΌ Π² ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΊΠ°ΠΊΠΈΠ΅-Π½ΠΈΠ±ΡΠ΄Ρ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΡ. ΠΠ΅ΠΊΠΎΡΠΎΡΡΠ΅ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΠΌΠΎΠ³ΡΡ ΠΈΠΌΠ΅ΡΡ Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ ΡΠ»ΠΎΠΆΠ½ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ: ΠΌΠ΅Π½Ρ, Π²ΡΠΏΠ°Π΄Π°ΡΡΠΈΠ΅ ΡΠΏΠΈΡΠΊΠΈ, ΡΠ°ΠΉΠ»ΠΎΠ²ΡΠ΅ Π±ΡΠ°ΡΠ·Π΅ΡΡ, ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ ΡΠΎΡΠΌΡ Π²Π²ΠΎΠ΄Π°. ΠΡ ΠΆΠ΅ Π½Π°ΡΠ½ΡΠΌ Ρ ΠΏΡΠΎΡΡΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ². Π‘Π½ΠΎΠ²Π° ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΠΊΠΎΠΏΠΈΡ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, Π½ΠΎ ΡΠ΅ΠΏΠ΅ΡΡ ΠΏΠΎΠ΄ ΠΈΠΌΠ΅Π½Π΅ΠΌ `example_3`. ΠΠ»Ρ ΡΠ΅Π½Π΄Π΅ΡΠ° Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π² ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠΌ ΡΠ°ΠΉΠ»Π΅ `example_3_app.c` `callback`-ΡΡΠ½ΠΊΡΠΈΡ ΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΈ `example_3_app_draw_callback`: ```c static void example_3_app_draw_callback(Canvas* canvas, void* ctx) { UNUSED(ctx); canvas_clear(canvas); } ``` Callback-ΡΡΠ½ΠΊΡΠΈΡ ΠΈΠΌΠ΅Π΅Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΡ ΡΠΈΠ³Π½Π°ΡΡΡΡ ΠΈ Π΄Π²Π° Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ° `canvas`, ΡΠΎ Π΅ΡΡΡ Β«Ρ ΠΎΠ»ΡΡΒ», Π½Π° ΠΊΠΎΡΠΎΡΠΎΠΌ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΡΠΈΡΠΎΠ²Π°ΡΡ, ΠΈ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ `ctx`. ΠΠΎΠ½ΡΠ΅ΠΊΡΡΠΎΠΌ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ Π΄ΡΡΠ³ΠΈΠ΅ Π΄Π°Π½Π½ΡΠ΅, Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΠΊΠΎΡΠΎΡΡΡ ΡΠ΅Π½Π΄Π΅ΡΠΈΡΡΡ `canvas`. ΠΠΎΠΊΠ° ΡΡΠΎ ΠΌΡ ΠΎΡΡΠ°Π²ΠΈΠΌ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ Π½Π΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Π½ΡΠΌ, ΡΠΎ Π΅ΡΡΡ `UNUSED`. ΠΠ΅ΡΠ²ΡΠΌ Π΄Π΅Π»ΠΎΠΌ ΠΏΠ΅ΡΠ΅Π΄ ΡΠ΅Π½Π΄Π΅ΡΠΎΠΌ ΠΎΡΠΈΡΡΠΈΠΌ Π½Π°Ρ ΡΠΊΡΠ°Π½: ```c canvas_clear(canvas); ``` ΠΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΡΠ°Π·ΠΌΠ΅ΡΠ°ΡΡΡΡ Π½Π° ΡΠΊΡΠ°Π½Π΅ ΡΠΎΠ³Π»Π°ΡΠ½ΠΎ ΡΠΈΡΡΠ΅ΠΌΠ΅ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°Ρ. ΠΠΊΡΠ°Π½ Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ° ΠΈΠΌΠ΅Π΅Ρ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ **128Γ64**, Π° Π½Π°ΡΠ°Π»ΠΎ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°Ρ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² Π»Π΅Π²ΠΎΠΌ Π²Π΅ΡΡ Π½Π΅ΠΌ ΡΠ³Π»Ρ: ![](/content/images/2023/flipper-app/9.png) ΠΠΎΠ±Π°Π²ΠΈΠΌ ΡΠ΅ΠΊΡΡ Π² ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΠΎΠ΄ΠΊΠ»ΡΡΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» Ρ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΌΠΈ ΡΠ΅ΠΊΡΡΠΎΠ²ΡΠΌΠΈ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°ΠΌΠΈ `gui/elements.h`. Π’Π΅ΠΊΡΡ ΠΎΡΡΠΈΡΠΎΠ²ΡΠ²Π°Π΅ΡΡΡ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ `canvas_draw_str()` Ρ ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΡ (`x` ΠΈ `y`) ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠΉ ΡΠΎΡΠΊΠΈ ΡΠ΅ΠΊΡΡΠ° ΠΈ, ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎ, ΡΠ°ΠΌΠΎΠΉ ΡΡΡΠΎΠΊΠΈ. ΠΠΎΠ·ΠΌΠΎΠΆΠ΅Π½ Π²ΡΠ±ΠΎΡ ΡΡΠΈΡΡΠ° Π΄Π»Ρ ΡΠ΅ΠΊΡΡΠ°. Π¨ΡΠΈΡΡ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ `canvas_set_font()`. Π¨ΡΠΈΡΡ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π³Π»Π°Π²Π½ΡΠΌ β `FontPrimary` (Π²ΡΡΠΎΡΠ° 8 ΠΏΠΈΠΊΡΠ΅Π»Π΅ΠΉ), Π²ΡΠΎΡΠΎΡΡΠ΅ΠΏΠ΅Π½Π½ΡΠΌ β `FontSecondary` (Π²ΡΡΠΎΡΠ° 7 ΠΏΠΈΠΊΡΠ΅Π»Π΅ΠΉ), `FontKeyboard` ΠΈΠ»ΠΈ `FontBigNumbers`. ΠΡΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ Π²Ρ ΡΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠΎΠ·Π΄Π°ΡΡ ΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠΉ ΡΡΠΈΡΡ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π½Π°ΠΏΠΈΡΠ΅ΠΌ Π³Π»Π°Π²Π½ΡΠΌ ΡΡΠΈΡΡΠΎΠΌ ΡΡΡΠΎΠΊΡ Β«**This is an example app!**Β» Π²Π²Π΅ΡΡ Ρ ΡΠΊΡΠ°Π½Π° ΠΈ ΠΏΡΠΈΠΌΠ΅ΡΠ½ΠΎ ΠΏΠΎ ΡΠ΅Π½ΡΡΡ, ΠΏΠΎ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΠ°ΠΌ (`4` ΠΈ `8`). ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ Π½Π°ΡΠ°Π»ΠΎ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°Ρ ΡΠ΅ΠΊΡΡΠ° Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² Π»Π΅Π²ΠΎΠΌ Π½ΠΈΠΆΠ½Π΅ΠΌ ΡΠ³Π»Ρ. ```c 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()`: ```c 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** ΠΏΠΈΠΊΡΠ΅Π»Π΅ΠΉ: ![](/content/images/2023/flipper-app/amperka_ru_logo_128x35px.png) Π ΠΏΠ°ΠΏΠΊΠ΅ Ρ Π²Π°ΡΠΈΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ ΡΠΎΠ·Π΄Π°ΠΉΡΠ΅ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΡΡ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ Π΄Π»Ρ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΌΡ Π½Π°Π·Π²Π°Π»ΠΈ ΡΠ²ΠΎΡ ΠΏΠ°ΠΏΠΊΡ `images`. Π Π΄Π°Π½Π½ΡΡ ΠΏΠ°ΠΏΠΊΡ ΠΏΠΎΠΌΠ΅ΡΡΠΈΡΠ΅ Π²ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΠ»Π°Π½ΠΈΡΡΠ΅ΡΠ΅ Π²ΡΠ²ΠΎΠ΄ΠΈΡΡ Π½Π° ΡΠΊΡΠ°Π½. ΠΡ Π½Π°Π·Π²Π°Π»ΠΈ Π½Π°ΡΡ ΠΊΠ°ΡΡΠΈΠ½ΠΊΡ `amperka_ru_logo_128x35px.png` ΠΈ ΠΏΠΎΠΌΠ΅ΡΡΠΈΠ»ΠΈ Π΅Ρ Π² ΡΠΎΠ·Π΄Π°Π½Π½ΡΡ ΠΏΠ°ΠΏΠΊΡ `images`: ![](/content/images/2023/flipper-app/10.png) Π ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ `application.fam` Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ Π½ΠΎΠ²ΡΠΉ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ `fap_icon_assets` Ρ ΠΏΡΡΡΠΌ Π΄ΠΎ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΠΌΠΈ: ```c 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`. ΠΠΎΠ±Π°Π²ΠΈΠΌ Π΄Π°Π½Π½ΡΠΉ ΡΠ°ΠΉΠ» Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ: ```c #include "example_3_icons.h" ``` Π’Π΅ΠΏΠ΅ΡΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΠΎΠ±Π»Π°ΡΡΡ ΠΏΠ°ΠΌΡΡΠΈ, Π³Π΄Π΅ Ρ ΡΠ°Π½ΠΈΡΡΡ Π½Π°ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π² Π²ΠΈΠ΄Π΅ ΠΌΠ°ΡΡΠΈΠ²Π° Π±Π°ΠΉΡΠΎΠ². ΠΠΌΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π±ΡΠ΄Π΅Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΎΠ²Π°ΡΡ ΠΈΠΌΠ΅Π½ΠΈ ΡΠ°ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, Π½ΠΎ Ρ ΠΏΡΠΈΡΡΠ°Π²ΠΊΠΎΠΉ `I_ΠΠΠ―_ΠΠΠ¨ΠΠΠ_Π€ΠΠΠΠ`. ΠΠ»Ρ Π½Π°ΡΠ΅ΠΉ ΠΊΠ°ΡΡΠΈΠ½ΠΊΠΈ Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ `amperka_ru_logo_128x35px.png` ΠΈΠΌΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π±ΡΠ΄Π΅Ρ `I_amperka_ru_logo_128x35px`. Π’Π΅ΠΏΠ΅ΡΡ, ΠΈΠΌΠ΅Ρ Π°Π΄ΡΠ΅Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΡΡΠ΅Π½Π΄Π΅ΡΠΈΡΡ Π΅Π³ΠΎ Π½Π° ΡΠΊΡΠ°Π½Π΅ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ `canvas_draw_icon()`. ΠΡΠ²Π΅Π΄Π΅ΠΌ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π²Π½ΠΈΠ·Ρ ΡΠΊΡΠ°Π½Π° ΠΏΠΎ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΠ°ΠΌ (`0` ΠΈ `29`): ```c canvas_draw_icon(canvas, 0, 29, &I_amperka_ru_logo_128x35px); ``` ΠΠΎΠΊΠ° ΡΡΠΎ Ρ Π²Π°ΡΠΈΡ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ². Π Π΅Π·ΡΠ»ΡΡΠ°Ρ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ: ![](/content/images/2023/flipper-app/11.png) ΠΠ°ΡΠ° `callback`-ΡΡΠ½ΠΊΡΠΈΡ ΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΈ Π³ΠΎΡΠΎΠ²Π°, ΠΈ Π΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡΠΈΠ²ΡΠ·Π°ΡΡ ΠΊ ΡΡΡΡΠΊΡΡΡΠ΅ `ViewPort` Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΡΠΎ Π½ΡΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ Π² ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΡΡΠ°Π·Ρ ΠΏΠΎΡΠ»Π΅ Π²ΡΠ΄Π΅Π»Π΅Π½ΠΈΡ ΠΏΠ°ΠΌΡΡΠΈ ΠΏΠΎΠ΄ `ViewPort`. Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° ΠΌΡ Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌ (`NULL`). ΠΠΎΡΠ»Π΅ ΠΏΡΠΈΠ²ΡΠ·ΠΊΠΈ ΠΏΠ΅ΡΠ²ΡΠΉ ΡΠ°Π· `callback`-ΡΡΠ½ΠΊΡΠΈΡ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½Π° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ. ```c view_port_draw_callback_set(app->view_port, example_3_app_draw_callback, NULL); ``` ΠΠ°Π³ΠΎΠ»ΠΎΠ²ΠΎΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» Π½Π°ΡΠ΅Π³ΠΎ ΡΡΠ΅ΡΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π½Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ»ΡΡ, Π·Π° ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ΠΌ ΠΈΠΌΠ΅Π½ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌΠΎΠ³ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΠΌΠΈ. ΠΠΎΠ΄ `example_3_app.h`: ```c #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.Ρ`: ```c #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 ΡΠ΅ΠΊΡΠ½Π΄ ΠΈ Π·Π°Π²Π΅ΡΡΠΈΡ ΡΠ²ΠΎΡ ΡΠ°Π±ΠΎΡΡ, Π½ΠΎ Π½Π° ΡΡΠΎΡ ΡΠ°Π· Ρ Π½Π°Ρ Π±ΡΠ΄Π΅Ρ Π³ΡΠ°ΡΠΈΠΊΠ°. Π‘ΠΎΠ±ΠΈΡΠ°Π΅ΠΌ Π½ΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅: ```sh ./fbt fap_example_3 ``` ΠΡΠΏΠΎΠ»ΡΠ·ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ qFlipper, ΠΏΠ΅ΡΠ΅Π½Π΅ΡΡΠΌ Π½ΠΎΠ²ΠΎΠ΅ FAP-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠ· ΠΏΠ°ΠΏΠΊΠΈ `build` Π½Π° SD-ΠΊΠ°ΡΡΡ Π² ΠΏΠ°ΠΏΠΊΡ `/apps/Misc`. ΠΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΠ΅ΡΠΌΠΈΠ½Π°Π» ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Ρ `./fbt fap_deploy`. ΠΠ°Ρ ΠΎΠ΄ΠΈΠΌ Π½ΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² ΡΠΏΠΈΡΠΊΠ΅ ΠΈ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌ Π΅Π³ΠΎ: ![](/content/images/2023/flipper-app/12.png) Π‘ΠΌΠΎΡΡΠ΅ΡΡ Π²ΠΈΠ΄Π΅ΠΎ: https://youtu.be/RNyTfBK4074. ## ΠΡΠΈΠΌΠ΅Ρ 4. ΠΠ½ΠΎΠΏΠΊΠΈ Π Π°Π·Π±Π΅ΡΡΠΌΡΡ, ΠΊΠ°ΠΊ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ Π½Π°ΠΆΠ°ΡΠΈΡ ΠΊΠ½ΠΎΠΏΠΎΠΊ Π½Π° Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ΅. ΠΡΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅ΠΌ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅Π΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠ΄ Π½ΠΎΠ²ΡΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ `example_4`. ΠΠ»Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΊΠ½ΠΎΠΏΠΎΠΊ Π½Π°ΠΌ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ (`MessageQueue`) ΠΈ Π΅ΡΡ ΠΎΠ΄Π½Π° `callback`-ΡΡΠ½ΠΊΡΠΈΡ Π΄Π»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΡΡΠΎΠΉ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ. **ΠΠ°ΡΠ΅ΠΌ Π½ΡΠΆΠ½Π° ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ?** ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π·Π° Π½Π°Ρ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ°, ΡΠΎ `callback`-ΡΡΠ½ΠΊΡΠΈΡ Π²Π²ΠΎΠ΄Π° Ρ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΊΠ°ΠΊ ΠΈ `callback`-ΡΡΠ½ΠΊΡΠΈΡ ΡΠ΅Π½Π΄Π΅ΡΠ° Π³ΡΠ°ΡΠΈΠΊΠΈ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π² ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅ Π΄ΡΡΠ³ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² ΠΠ‘ Flipper Zero, Π° Π½Π΅ Π² ΠΏΠΎΡΠΎΠΊΠ΅ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΠΎΡΠΎΠΊ, ΠΎΡΠ²Π΅ΡΠ°ΡΡΠΈΠΉ Π·Π° Π½Π°ΠΆΠ°ΡΠΈΠ΅ ΠΊΠ½ΠΎΠΏΠΎΠΊ, Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ Π²ΡΠ·Π²Π°ΡΡ ΠΊΠ°ΠΊΡΡ-Π»ΠΈΠ±ΠΎ ΡΡΠ½ΠΊΡΠΈΡ Π½Π°ΠΏΡΡΠΌΡΡ ΠΈΠ· Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΠΎ ΠΏΠΎΡΠΎΠΊΠΈ ΠΌΠΎΠ³ΡΡ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡ Π΄ΡΡΠ³ Π΄ΡΡΠ³Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π² Π»ΡΠ±ΠΎΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ, ΡΡΠΈΠΌ ΠΌΡ ΠΈ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ. ΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ Π² ΡΡΡΡΠΊΡΡΡΡ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ `Example4App` ΠΎΡΠ΅ΡΠ΅Π΄Ρ `event_queue` ΡΠΈΠΏΠ° `FuriMessageQueue`: ```c struct Example4App { Gui* gui; ViewPort* view_port; FuriMessageQueue* event_queue; }; ``` Π ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ `example_4_app_alloc()` Π²ΡΠ΄Π΅Π»ΡΠ΅ΠΌ ΠΏΠ°ΠΌΡΡΡ ΠΏΠΎΠ΄ Π½ΠΎΠ²ΡΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ. ```c app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); ``` ΠΠ°ΡΠ° ΠΎΡΠ΅ΡΠ΅Π΄Ρ Π±ΡΠ΄Π΅Ρ Π½Π° 8 ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΡΠΈΠΏΠ° `InputEvent`, ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΡΠ²Π΅ΡΠ°Π΅Ρ Π·Π° Π½Π°ΠΆΠ°ΡΠΈΠ΅ ΠΊΠ»Π°Π²ΠΈΡ. Π‘ΡΡΡΠΊΡΡΡΡ Π΄Π°Π½Π½ΡΡ ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ ΠΎΡ ΠΊΠ½ΠΎΠΏΠΎΠΊ Π½Π°Ρ ΠΎΠ΄ΡΡΡΡ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡΠ½ΠΎΠΌ ΡΠ°ΠΉΠ»Π΅ `input/input.h`. Π ΡΡΠ½ΠΊΡΠΈΠΈ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½ΠΈΡ ΠΏΠ°ΠΌΡΡΠΈ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ, ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅ΠΌ Π·Π°Π½ΡΡΡΡ ΠΎΡΠ΅ΡΠ΅Π΄ΡΡ ΠΏΠ°ΠΌΡΡΡ. ```c furi_message_queue_free(app->event_queue); ``` Π’Π΅ΠΏΠ΅ΡΡ ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ `callback`-ΡΡΠ½ΠΊΡΠΈΡ Π΄Π»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΡΡΠΎΠΉ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ. ```c 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`: ```c view_port_input_callback_set(app->view_port, example_4_app_input_callback, app->event_queue); ``` ΠΠΎΡΠΎΠ²ΠΎ! Π’Π΅ΠΏΠ΅ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² Π½Π°ΡΠ΅ΠΌ ΡΠ°ΡΠΏΠΎΡΡΠΆΠ΅Π½ΠΈΠΈ, ΠΈ Π΅Ρ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°ΡΡ. Π‘Π΅ΠΉΡΠ°Ρ Π½Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ 10 ΡΠ΅ΠΊΡΠ½Π΄, Π° Π·Π°ΡΠ΅ΠΌ Π·Π°Π²Π΅ΡΡΠ°Π΅Ρ ΡΠ°Π±ΠΎΡΡ. ΠΠ°Π²Π°ΠΉΡΠ΅ ΡΠ΄Π΅Π»Π°Π΅ΠΌ ΡΠ°ΠΊ, ΡΡΠΎΠ±Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π·Π°ΠΊΡΡΠ²Π°Π»ΠΎΡΡ Π½Π΅ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ, Π° ΠΏΡΠΈ Π½Π°ΠΆΠ°ΡΠΈΠΈ Π½Π° ΠΊΠ»Π°Π²ΠΈΡΡ Β«**ΠΠ°Π·Π°Π΄**Β» Π½Π° Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ΅. ΠΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΈΠ· ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ Π½Π°ΠΏΠΈΡΠ΅ΠΌ Π² Π³Π»Π°Π²Π½ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ (ΡΠΎΡΠΊΠ΅ Π²Ρ ΠΎΠ΄Π°) Π² Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΌ ΡΠΈΠΊΠ»Π΅: ```c 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`: ```c #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.Ρ`: ```c #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. ```sh ./fbt fap_example_4 ./fbt fap_deploy ``` ![](/content/images/2023/flipper-app/13.png) Π‘ΠΌΠΎΡΡΠ΅ΡΡ Π²ΠΈΠ΄Π΅ΠΎ: https://youtu.be/PlClOH5_yB0. ΠΠ·ΠΌΠ΅Π½ΠΈΠΌ Π½Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π΅ΡΡ ΠΏΠ°ΡΡ ΠΊΠ½ΠΎΠΏΠΎΠΊ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π±ΡΠ΄Π΅ΠΌ ΠΏΠΎ-ΡΠ°Π·Π½ΠΎΠΌΡ ΡΠ΅Π½Π΄Π΅ΡΠΈΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π½Π° ΡΠΊΡΠ°Π½Π΅ Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ Π½Π°ΠΆΠ°ΡΠΎΠΉ ΠΊΠ½ΠΎΠΏΠΊΠΈ. ΠΡΡΡΡ Ρ Π½Π°Ρ Π±ΡΠ΄Π΅Ρ ΡΡΠΈ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°: ΡΠ΅Π½Π΄Π΅ΡΠΈΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ΅ΠΊΡΡ, ΡΠ΅Π½Π΄Π΅ΡΠΈΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅, Π»ΠΈΠ±ΠΎ ΡΠ΅Π½Π΄Π΅ΡΠΈΡΡΡ ΠΈ ΡΠΎ, ΠΈ Π΄ΡΡΠ³ΠΎΠ΅. ΠΠ΅ΡΠ΅ΠΊΠ»ΡΡΠ°ΡΡΡΡ ΠΌΠ΅ΠΆΠ΄Ρ ΡΡΠΈΠΌΠΈ ΡΠ΅ΠΆΠΈΠΌΠ°ΠΌΠΈ Π±ΡΠ΄Π΅ΠΌ ΠΏΡΠΈ Π΄ΠΎΠ»Π³ΠΎΠΌ Π½Π°ΠΆΠ°ΡΠΈΠΈ Π½Π° ΠΊΠ½ΠΎΠΏΠΊΠΈ Β«ΠΠ»Π΅Π²ΠΎΒ» ΠΈΠ»ΠΈ Β«ΠΠΏΡΠ°Π²ΠΎΒ». ΠΠ²Π΅Π΄ΡΠΌ Π² ΡΡΡΡΠΊΡΡΡΡ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ ΠΎΡΠ²Π΅ΡΠ°ΡΡ Π·Π° ΡΠΎ, ΠΊΠ°ΠΊΠΎΠΉ ΡΠ΅ΠΆΠΈΠΌ ΡΠ΅Π½Π΄Π΅ΡΠΈΡΡΡ Π² Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ. ΠΠ°Π·ΠΎΠ²Π΅ΠΌ Π΅Ρ `draw_mode`. ```c 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` Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ°: ```c view_port_draw_callback_set(app->view_port, example_4_app_draw_callback, app); ``` Π’Π΅ΠΏΠ΅ΡΡ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠΌ ΡΠ°ΠΌΡ `callback`-ΡΡΠ½ΠΊΡΠΈΡ ΡΠ΅Π½Π΄Π΅ΡΠ°. ΠΡΡΡΡ ΡΠ°Π·Π½ΡΠ΅ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΡΠ΅Π½Π΄Π΅ΡΡΡΡΡ Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΡΠ΅ΠΊΡΡΠ΅Π³ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ `draw_mode`: ```c 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"); } } ``` Π Π·Π°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π΅ΠΌ Π½ΠΎΠ²ΡΠ΅ ΡΠΎΠ±ΡΡΠΈΡ ΠΊΠ½ΠΎΠΏΠΎΠΊ Π² Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΌ ΡΠΈΠΊΠ»Π΅ Π³Π»Π°Π²Π½ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ: ```c 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`. Π€ΡΠ½ΠΊΡΠΈΡ Π½Π΅ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½Π°Ρ, ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ° ΡΠ°ΠΌΠ° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ ΡΠ΅ΡΠ΅Π½Π΄Π΅Ρ ΡΠ°Π· Π² Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΌΠΈΠ»Π»ΠΈΡΠ΅ΠΊΡΠ½Π΄, Π½ΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΡΡΠΈΡΠΎΠ²Π°ΡΡ ΡΡΠΎ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ. Π‘ΠΎΠ±Π΅ΡΡΠΌ ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ½Π½ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π·Π°Π³ΡΡΠ·ΠΈΠΌ Π΅Π³ΠΎ Π½Π° Π€Π»ΠΈΠΏΠΏΠ΅Ρ, Π·Π°ΠΏΡΡΡΠΈΠΌ ΠΈ ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ: Π‘ΠΌΠΎΡΡΠ΅ΡΡ Π²ΠΈΠ΄Π΅ΠΎ: https://youtu.be/7EBGrZNekXM. ## ΠΡΠΈΠΌΠ΅Ρ 5. ΠΠΏΠΎΠ²Π΅ΡΠ΅Π½ΠΈΡ ΠΠΎΠΌΠΈΠΌΠΎ Π΄ΠΈΡΠΏΠ»Π΅Ρ Flipper Zero ΠΈΠΌΠ΅Π΅Ρ ΠΈ Π΄ΡΡΠ³ΠΎΠΉ ΡΠΏΠΎΡΠΎΠ± ΡΠΎΠΎΠ±ΡΠ°ΡΡ Π½Π°ΠΌ ΠΎ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΡΡΠΈΡ Π² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ ΡΠΎΠ±ΡΡΠΈΡΡ β ΠΎΠΏΠΎΠ²Π΅ΡΠ΅Π½ΠΈΡ (`Notifications`). ΠΠ°ΠΌ Π΄ΠΎΡΡΡΠΏΠ½ΠΎ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌΠΈ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΌΠΈ Π΄Π΅Π²Π°ΠΉΡΠ°ΠΌΠΈ: * RGB-cΠ²Π΅ΡΠΎΠ΄ΠΈΠΎΠ΄. * ΠΠΈΠ±ΡΠΎΠΌΠΎΡΠΎΡ. * ΠΡΠ΅Π·ΠΎΠΏΠΈΡΠ°Π»ΠΊΠ°. ΠΡΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅ΠΌ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅Π΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠ΄ Π½ΠΎΠ²ΡΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ `example_5`. ΠΠ° ΠΎΠΏΠΎΠ²Π΅ΡΠ΅Π½ΠΈΡ Π² ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΠ΅ Flipper Zero ΠΎΡΠ²Π΅ΡΠ°Π΅Ρ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΠΏΠΎΡΠΎΠΊ, ΠΈ ΠΌΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΡΠ·ΡΠ²Π°ΡΡ Π΅Π³ΠΎ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈΠ· Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π½Π°ΠΏΡΡΠΌΡΡ. ΠΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΡΡΡΠ»Π°ΡΡ Π² ΡΡΠΎΡ ΠΏΠΎΡΠΎΠΊ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ β `NotificationMessage`. ΠΠ· ΡΡΠΈΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΡΠΎΡΠΌΠΈΡΡΡΡΡΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ `NotificationSequence`, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠΆΠ΅ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΡΡ Π² ΠΏΠΎΡΠΎΠΊ. ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΡΡΡΡΠΊΡΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΈ ΠΈΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΠ΅ΠΉ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡΠ½ΠΎΠΌ ΡΠ°ΠΉΠ»Π΅ `notification/notification_messages.h`, Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ Π΅Π³ΠΎ Π² Π½Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅. Π Π³Π»Π°Π²Π½ΠΎΠΉ ΡΡΡΡΠΊΡΡΡΠ΅ ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ, ΡΡΠΎ Π½Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠΎΠ±ΠΈΡΠ°Π΅ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠΏΠΎΠ²Π΅ΡΠ΅Π½ΠΈΡ `NotificationApp`: ```c struct Example5App { Gui* gui; ViewPort* view_port; FuriMessageQueue* event_queue; NotificationApp* notifications; DrawMode draw_mode; }; ``` Π ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ `example_5_app_alloc()` ΠΏΠ΅ΡΠ΅Ρ Π²Π°ΡΡΠ²Π°Π΅ΠΌ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎΠΏΠΎΠ²Π΅ΡΠ΅Π½ΠΈΡΠΌΠΈ: ```c app->notifications = furi_record_open(RECORD_NOTIFICATION); ``` Π Π² ΡΡΠ½ΠΊΡΠΈΠΈ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½ΠΈΡ ΠΏΠ°ΠΌΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ `example_5_app_free` ΠΎΡΠ΄Π°ΡΠΌ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ: ```c furi_record_close(RECORD_NOTIFICATION); ``` ΠΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΈ Π³ΠΎΡΠΎΠ²ΡΠ΅ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ, Π° ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΠΈΡ ΡΠ°ΠΌΠΎΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎ, ΡΡΠΎ Π½Π΅ΡΠ»ΠΎΠΆΠ½ΠΎ. ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΠ·ΡΡΠΈΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» ΠΈ ΠΊΠ°ΠΊΠΈΠ΅ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΡΠ°ΠΌ Π΄ΠΎΡΡΡΠΏΠ½Ρ. Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π½Π°ΡΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ Π΄Π»Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ RGB-ΡΠ²Π΅ΡΠΎΠ΄ΠΈΠΎΠ΄ΠΎΠΌ. ΠΠ°Π·ΠΎΠ²Π΅ΠΌ Π΅Ρ `example_led_sequence` ΠΈ ΡΠ°Π·ΠΌΠ΅ΡΡΠΈΠΌ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΡΡΡΡ ΡΠ²Π΅ΡΠΎΠ΄ΠΈΠΎΠ΄ ΠΌΠΈΠ³Π½ΡΡ ΡΠΈΠΎΠ»Π΅ΡΠΎΠ²ΡΠΌ ΡΠ²Π΅ΡΠΎΠΌ **RGB(255, 0, 255)** ΡΡΠΈ ΡΠ°Π·Π° Ρ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π»ΠΎΠΌ **500 ΠΌΡ**, Π° Π·Π°ΡΠ΅ΠΌ ΠΏΠΎΠ³Π°ΡΠ½Π΅Ρ. Π‘ΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π±ΡΠ΄Π΅Ρ Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ: ```c 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 ΡΠ΅ΠΊΡΠ½Π΄Ρ, Π° Π·Π°ΡΠ΅ΠΌ Π²ΡΠΊΠ»ΡΡΠΈΡΡΡ. ΠΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ Π±ΡΠ΄Π΅Ρ Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ ΡΠ°ΠΊ: ```c 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**: ![](/content/images/2023/flipper-app/sound.png) ΠΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ Ρ Π΄Π°Π½Π½ΠΎΠΉ ΠΌΠ΅Π»ΠΎΠ΄ΠΈΠ΅ΠΉ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ°ΠΊ: ```c 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()`: ```c 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()` Ρ ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅ΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ. Π‘ΠΎΠ±ΠΈΡΠ°Π΅ΠΌ Π½ΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅: ```sh ./fbt fap_example_5 ``` ΠΡΠΏΠΎΠ»ΡΠ·ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ qFlipper, ΠΏΠ΅ΡΠ΅Π½ΠΎΡΠΈΠΌ Π½ΠΎΠ²ΡΠΉ FAP-ΡΠ°ΠΉΠ» ΠΈΠ· ΠΏΠ°ΠΏΠΊΠΈ `build` Π½Π° SD-ΠΊΠ°ΡΡΡ Π² ΠΏΠ°ΠΏΠΊΡ `/apps/Misc`. ΠΠ»ΠΈ Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ `./fbt fap_deploy`. ΠΠ°ΠΏΡΡΠΊΠ°Π΅ΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅: ![](/content/images/2023/flipper-app/14.png) Π‘ΠΌΠΎΡΡΠ΅ΡΡ Π²ΠΈΠ΄Π΅ΠΎ: https://youtu.be/238dmsw5DA4. ## ΠΡΠΈΠΌΠ΅Ρ 6. GPIO ΠΠ° Flipper Zero 18 ΠΊΠΎΠ½ΡΠ°ΠΊΡΠΎΠ² **GPIO**, ΡΡΠ΅Π΄ΠΈ ΠΊΠΎΡΠΎΡΡΡ Π΅ΡΡΡ ΠΊΠ°ΠΊ ΠΏΠΈΠ½Ρ ΠΏΠΈΡΠ°Π½ΠΈΡ, ΡΠ°ΠΊ ΠΈ ΠΏΠΈΠ½Ρ Π²Π²ΠΎΠ΄Π°-Π²ΡΠ²ΠΎΠ΄Π°. ΠΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΎΠ΅ Π½Π°ΠΏΡΡΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΈΡΠ°Π½ΠΈΡ β **3,3Π**, ΠΈ ΠΏΠΈΠ½Ρ Π½Π΅ΡΠΎΠ»Π΅ΡΠ°Π½ΡΠ½Ρ ΠΊ **5Π** (Π·Π° ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ΠΌ ΠΏΠΈΠ½Π° `iButton`). ΠΠΎ ΡΡΡΠΈ, ΠΏΠΈΠ½Ρ Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡ ΠΏΠΈΠ½Π°ΠΌ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π½ΠΎΠ³ΠΎ Π² Π½ΡΠΌ ΠΌΠΈΠΊΡΠΎΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ° `STM32WB55` ΠΈ ΠΎΠ±Π»Π°Π΄Π°ΡΡ ΡΠ΅ΠΌΠΈ ΠΆΠ΅ Π½Π°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌΡΠΌΠΈ Π°Π»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΡΠΌΠΈ ΡΡΠ½ΠΊΡΠΈΡΠΌΠΈ (`ADC`, `USART`, `SPI` ΠΈ Π΄Ρ.). Π Π°ΡΠΏΠΈΠ½ΠΎΠ²ΠΊΠ° Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ°: ![](/content/images/2023/flipper-app/pinout.png) ΠΠΎΠ΄ΡΠΎΠ±Π½ΠΎΠ΅ Π½Π°Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΈΠ½ΠΎΠ² ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡΡΠ΅ΡΡ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡΠ½ΠΎΠΌ ΡΠ°ΠΉΠ»Π΅ `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Π**. Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΠΌ ΡΠ²Π΅ΡΠΎΠ΄ΠΈΠΎΠ΄ ΠΈ ΠΊΠ½ΠΎΠΏΠΊΡ Π½Π° ΠΌΠ°ΠΊΠ΅ΡΠ½ΡΡ ΠΏΠ»Π°ΡΡ: ![](/content/images/2023/flipper-app/breadboard-1.jpg) ΠΠ°Π·ΠΎΠ²ΡΠΌ Π½ΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ `example_6` ΠΈ ΡΠ΄Π΅Π»Π°Π΅ΠΌ Π΅Π³ΠΎ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅Π³ΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠ° Π½ΠΎΠΌΠ΅Ρ 4. ΠΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΠ±Π΅ΡΡΠΌ ΠΈΠ· ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π²ΡΡ, ΡΡΠΎ ΠΊΠ°ΡΠ°Π΅ΡΡΡ ΠΎΠΏΠΎΠ²Π΅ΡΠ΅Π½ΠΈΠΉ, ΡΠ΅Π½Π΄Π΅ΡΠ° Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΡΡΠΎΠ±Ρ ΠΎΡΡΠ°Π»ΡΡ ΠΏΡΡΡΠΎΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ. ΠΠ»Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ GPIO Π½Π°ΠΌ Π½ΡΠΆΠ΅Π½ HAL Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ°. ΠΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ ΡΠ°ΠΉΠ» `furi_hal.h` Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. Π Π³Π»Π°Π²Π½ΠΎΠΉ ΡΡΡΡΠΊΡΡΡΠ΅ `Example6App` Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π΄Π²Π° ΠΏΠΈΠ½Π° Π΄Π»Ρ Π²Ρ ΠΎΠ΄Π° ΠΈ Π²ΡΡ ΠΎΠ΄Π°: `input_pin`, `output_pin` ΠΈ Π΄Π²Π΅ Π±ΡΠ»Π΅Π²Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ Π΄Π»Ρ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ ΡΠ΅ΠΊΡΡΠΈΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ Π½Π° ΡΡΠΈΡ ΠΏΠΈΠ½Π°Ρ : `input_value`, `output_value`. ΠΠ°Ρ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ Π²ΠΈΠ΄: ```c #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`: ```c 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()` (ΠΈ ΠΏΠΎ ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΡΠ΅Π»ΡΡΡΠ²Ρ Π² Π½Π°ΡΠ΅ΠΉ ΡΠΎΡΠΊΠ΅ Π²Ρ ΠΎΠ΄Π°) ΡΡΠΈΡΡΠ²Π°Π΅ΠΌ ΠΈ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π² Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΌ ΡΠΈΠΊΠ»Π΅: ```c furi_hal_gpio_write(app->output_pin, app->output_value); app->input_value = furi_hal_gpio_read(app->input_pin); ``` ΠΡΡΡΡ Π²ΡΡ ΠΎΠ΄Π½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π·Π°Π²ΠΈΡΠΈΡ ΠΎΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ ΠΊΠ½ΠΎΠΏΠΊΠΈ Β«ΠΠΊΒ» Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ°. ΠΠ½ΠΎΠΏΠΊΠ° Π½Π°ΠΆΠ°ΡΠ° β ΡΠΈΠ³Π½Π°Π» Π΅ΡΡΡ, ΠΎΡΠΆΠ°ΡΠ° β ΡΠΈΠ³Π½Π°Π»Π° Π½Π΅Ρ. ΠΠ°ΠΊ ΠΈ ΠΏΡΠ΅ΠΆΠ΄Π΅, ΠΊΠ»Π°Π²ΠΈΡΠ΅ΠΉ Β«ΠΠ°Π·Π°Π΄Β» Π·Π°Π²Π΅ΡΡΠ°Π΅ΠΌ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΠΎΠ±Π°Π²ΠΈΠΌ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ ΠΊΠ½ΠΎΠΏΠΊΠΈ Β«ΠΠΊΒ» Π² Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΡΠΉ ΡΠΈΠΊΠ» Π½Π°ΡΠ΅ΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ: ```c 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`. Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΌ Π² ΡΡΠ½ΠΊΡΠΈΡ ΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΈ Π³Π»Π°Π²Π½ΡΡ ΡΡΡΡΠΊΡΡΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ```c 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"); } ``` ΠΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π±ΡΠ΄Π΅Ρ Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ ΡΠ°ΠΊ: ![](/content/images/2023/flipper-app/15.png) Π‘ΠΎΠ±ΠΈΡΠ°Π΅ΠΌ Π½ΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌ Π΅Π³ΠΎ Π½Π° Π€Π»ΠΈΠΏΠΏΠ΅Ρ: ```sh ./fbt fap_example_6 ./fbt fap_deploy ``` Π‘ΠΌΠΎΡΡΠ΅ΡΡ Π²ΠΈΠ΄Π΅ΠΎ: https://youtu.be/6k5D1TGZm0Q. **PWM ΠΈ ADC** Π‘ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠ΅ΠΉ Π¨ΠΠ-ΡΠΈΠ³Π½Π°Π»ΠΎΠ² Π²ΡΡ ΠΎΠ±ΡΡΠΎΠΈΡ Π½Π°ΠΌΠ½ΠΎΠ³ΠΎ ΡΠ»ΠΎΠΆΠ½Π΅Π΅. ΠΠ΄Π΅ΡΡ ΡΠΆΠ΅ Π½Π΅ ΠΎΠ±ΠΎΠΉΡΠΈΡΡ ΠΎΠ΄Π½ΠΎΠΉ-Π΄Π²ΡΠΌΡ ΡΡΠ½ΠΊΡΠΈΡΠΌΠΈ ΠΈΠ· FURI HAL, Π° ΡΠ°ΠΌ ΠΊΠΎΠ΄ ΡΠΈΠ»ΡΠ½ΠΎ ΡΠ°Π·ΡΠ°ΡΡΠ°Π΅ΡΡΡ. Π ΠΏΡΠΎΡΠΈΠ²ΠΊΠ΅ Flipper Zero ΡΠΆΠ΅ Π΅ΡΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ **Signal Generator** Π΄Π»Ρ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ Π¨ΠΠ-ΡΠΈΠ³Π½Π°Π»Π° Π½Π° ΠΏΠΈΠ½Π°Ρ `PA7` ΠΈ `PA4`. ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠ°ΠΌΠΎΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎ ΠΈΠ·ΡΡΠΈΡΡ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ Π΄Π»Ρ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ Π¨ΠΠ Π² Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ [applications/plugins/signal_generator/](https://github.com/flipperdevices/flipperzero-firmware/tree/dev/applications/plugins/signal_generator) ΠΈ ΡΠ΅ΠΏΠ»ΠΈΡΠΈΡΠΎΠ²Π°ΡΡ Π΅Π³ΠΎ Π² Π²Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅. Π Π²ΠΎΡ ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠΉ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ Π½Π° ΡΡΠ΅Π½ΠΈΠ΅ Π°Π½Π°Π»ΠΎΠ³ΠΎΠ²ΡΡ ΡΠΈΠ³Π½Π°Π»ΠΎΠ² ΠΏΠΎΠΊΠ° Π½Π΅Ρ. ΠΡΠΎΠΌΠ΅ ΡΡΠΎΠ³ΠΎ Π°Π»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ Π°Π½Π°Π»ΠΎΠ³ΠΎ-ΡΠΈΡΡΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π½Π° ΠΏΠΈΠ½Π°Ρ Π΅ΡΡ Π½Π΅ ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½Ρ Π² FURI HAL. ΠΠ΄Π½Π°ΠΊΠΎ ΡΠ°ΠΌ ADC Π½Π° ΠΌΠΈΠΊΡΠΎΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ΅ STM32 ΠΈ Π΅Π³ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ Π½ΠΈΠΊΡΠ΄Π° ΠΎΡ Π½Π°Ρ Π½Π΅ Π΄Π΅Π»ΠΈΡΡ. ΠΠ° ΠΏΡΠΎΡΡΠΎΡΠ°Ρ ΠΈΠ½ΡΠ΅ΡΠ½Π΅ΡΠ° ΠΌΡ Π½Π°ΡΠ»ΠΈ ΠΏΡΠΈΠΌΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ **ADC**. ΠΡ ΡΠ°Π·ΠΌΠ΅ΡΡΠΈΠ»ΠΈ Π² ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΈ Ρ ΠΏΡΠΈΠΌΠ΅ΡΠ°ΠΌΠΈ [flipperzero-examples](https://github.com/amperka/flipperzero-examples) ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ [`adc_example`](https://github.com/amperka/flipperzero-examples/tree/main/applications/adc_example), ΠΊΠΎΡΠΎΡΠΎΠ΅ cΡΠΈΡΡΠ²Π°Π΅Ρ Π°Π½Π°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Ρ ΠΏΠΈΠ½Π° `PC3` ΠΈ Π²ΡΠ²ΠΎΠ΄ΠΈΡ Π΅Π³ΠΎ Π½Π° ΡΠΊΡΠ°Π½. ΠΠΎΠ΄ Π΅ΡΡ Π½ΡΠΆΠ΄Π°Π΅ΡΡΡ Π² Π΄ΠΎΡΠ°Π±ΠΎΡΠΊΠ΅, ΠΈ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΅Π³ΠΎ Π² ΡΠ²ΠΎΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΡ , ΠΎΠ΄Π½Π°ΠΊΠΎ ΠΌΡ ΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ Π΄ΠΎΠΆΠ΄Π°ΡΡΡΡ ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠΉ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ ΠΈ ΠΏΡΠΈΠΌΠ΅ΡΠΎΠ². ΠΠΏΠΎΡΠ½ΡΠΌ Π½Π°ΠΏΡΡΠΆΠ΅Π½ΠΈΠ΅ΠΌ ΡΠ²Π»ΡΠ΅ΡΡΡ Π²ΡΠ±ΠΎΡΠΎΡΠ½ΠΎ ΠΈΠ»ΠΈ **2.5Π** ΠΈΠ»ΠΈ **2.048Π**. ΠΠΎΠ΄ΠΊΠ»ΡΡΠΈΠ² ΠΊ ΡΠ»ΠΈΠΏΠΏΠ΅ΡΡ ΠΏΠΎΡΠ΅Π½ΡΠΈΠΎΠΌΠ΅ΡΡ ΠΈ Π²Π·ΡΠ² ΠΏΠΈΡΠ°Π½ΠΈΠ΅ Ρ ΠΏΠΈΠ½Π° **3.3Π** ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡ ΠΏΡΠΎΡΡΠΎΠΉ Π΄Π΅Π»ΠΈΡΠ΅Π»Ρ Π½Π°ΠΏΡΡΠΆΠ΅Π½ΠΈΡ Π² ΠΏΡΠ΅Π΄Π΅Π»Π°Ρ ΡΡΡΡΡΠΈ **ΠΠΌ**. Π Π°Π·ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΠ¦Π - **12 Π±ΠΈΡ**. Π§ΠΈΡΠ°Π΅ΠΌ Π½Π°ΠΏΡΡΠΆΠ΅Π½ΠΈΠ΅ ΠΎΡ **0** Π΄ΠΎ **2.5Π** Π½Π° ΠΏΠΈΠ½Π΅ `PC3` ΠΈ ΠΌΠ΅Π½ΡΠ΅ΠΌ Π΅Π³ΠΎ ΠΏΠΎΡΠ΅Π½ΡΠΈΠΎΠΌΠ΅ΡΡΠΎΠΌ: Π‘ΠΌΠΎΡΡΠ΅ΡΡ Π²ΠΈΠ΄Π΅ΠΎ: https://youtu.be/k2DK9xAi9QQ. ## ΠΠ°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΠ° ΡΡΠΎΠΌ ΠΌΡ Π·Π°ΠΊΠ°Π½ΡΠΈΠ²Π°Π΅ΠΌ Π±Π°Π·ΠΎΠ²ΠΎΠ΅ Π·Π½Π°ΠΊΠΎΠΌΡΡΠ²ΠΎ Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠΌΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΠΌΠΈ Π΄Π»Ρ Flipper Zero. ΠΠΎΠΊΠΎΠΏΠ°Π²ΡΠΈΡΡ Π² Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ, Π½Π°ΠΌ ΡΠ΄Π°Π»ΠΎΡΡ Π·Π°ΠΉΡΠΈ ΠΏΠΎΠ΄Π°Π»ΡΡΠ΅ Π±Π°Π½Π°Π»ΡΠ½ΠΎΠ³ΠΎ Β«Hello, world!Β» ΠΈ Π½Π°ΠΏΠΈΡΠ°ΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π΄Π»Ρ ΠΏΡΠΈΠΌΠ΅ΡΠ° ΡΠ°Π±ΠΎΡΡ Ρ GUI, ΠΊΠ½ΠΎΠΏΠΊΠ°ΠΌΠΈ ΠΈ Π²ΡΡΡΠΎΠ΅Π½Π½ΠΎΠΉ ΠΏΠ΅ΡΠΈΡΠ΅ΡΠΈΠ΅ΠΉ Π€Π»ΠΈΠΏΠΏΠ΅ΡΠ° β RGB-ΡΠ²Π΅ΡΠΎΠ΄ΠΈΠΎΠ΄ΠΎΠΌ, Π²ΠΈΠ±ΡΠΎΠΌΠΎΡΠΎΡΠΎΠΌ ΠΈ Π±Π°Π·Π·Π΅ΡΠΎΠΌ. ΠΠ΄ΡΠΌ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠΉ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ Π³Π°Π΄ΠΆΠ΅ΡΠ° ΠΈ Π½Π°Π΄Π΅Π΅ΠΌΡΡ, ΡΡΠΎ Π½Π°ΡΠΈ ΠΏΡΠΈΠΌΠ΅ΡΡ ΠΏΠΎΠΌΠΎΠ³ΡΡ Π²Π°ΠΌ Π² ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΡΠ²ΠΎΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π΄Π»Ρ Flipper Zero!