[FL-2627] Flipper applications: SDK, build and debug system (#1387)
* Added support for running applications from SD card (FAPs - Flipper Application Packages) * Added plugin_dist target for fbt to build FAPs * All apps of type FlipperAppType.EXTERNAL and FlipperAppType.PLUGIN are built as FAPs by default * Updated VSCode configuration for new fbt features - re-deploy stock configuration to use them * Added debugging support for FAPs with fbt debug & VSCode * Added public firmware API with automated versioning Co-authored-by: hedger <hedger@users.noreply.github.com> Co-authored-by: SG <who.just.the.doctor@gmail.com> Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
0f6f9ad52e
commit
b9a766d909
151
.clang-format
151
.clang-format
@ -1,86 +1,191 @@
|
||||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveMacros: None
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignConsecutiveBitFields: None
|
||||
AlignConsecutiveDeclarations: None
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: true
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: false
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: WithoutElse
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeConceptDeclarations: true
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: false
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 99
|
||||
ColumnLimit: 99
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
QualifierAlignment: Leave
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
PackConstructorInitializers: BinPack
|
||||
BasedOnStyle: ''
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
FixNamespaceComments: false
|
||||
|
||||
IncludeBlocks: Preserve
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseLabels: false
|
||||
IndentCaseBlocks: false
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentRequires: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: true
|
||||
InsertTrailingCommas: None
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
LambdaBodyIndentation: Signature
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
|
||||
# Taken from git's rules
|
||||
PenaltyBreakAssignment: 10
|
||||
PenaltyBreakBeforeFirstCallParameter: 30
|
||||
PenaltyBreakComment: 10
|
||||
PenaltyBreakFirstLessLess: 0
|
||||
PenaltyBreakOpenParenthesis: 0
|
||||
PenaltyBreakString: 10
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 100
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PointerAlignment: Left
|
||||
ReflowComments: false
|
||||
SortIncludes: false
|
||||
PPIndentWidth: -1
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: false
|
||||
RemoveBracesLLVM: false
|
||||
SeparateDefinitionBlocks: Leave
|
||||
ShortNamespaceLines: 1
|
||||
SortIncludes: Never
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: false
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: Never
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: false
|
||||
AfterForeachMacros: false
|
||||
AfterFunctionDefinitionName: false
|
||||
AfterFunctionDeclarationName: false
|
||||
AfterIfMacros: false
|
||||
AfterOverloadedOperator: false
|
||||
BeforeNonEmptyParentheses: false
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInAngles: Never
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp03
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
SpaceBeforeSquareBrackets: false
|
||||
BitFieldColonSpacing: Both
|
||||
Standard: c++03
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 4
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
WhitespaceSensitiveMacros:
|
||||
- STRINGIZE
|
||||
- PP_STRINGIZE
|
||||
- BOOST_PP_STRINGIZE
|
||||
- NS_SWIFT_NAME
|
||||
- CF_SWIFT_NAME
|
||||
...
|
||||
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -28,3 +28,6 @@
|
||||
[submodule "lib/mbedtls"]
|
||||
path = lib/mbedtls
|
||||
url = https://github.com/Mbed-TLS/mbedtls.git
|
||||
[submodule "lib/cxxheaderparser"]
|
||||
path = lib/cxxheaderparser
|
||||
url = https://github.com/robotpy/cxxheaderparser.git
|
||||
|
13
.vscode/example/launch.json
vendored
13
.vscode/example/launch.json
vendored
@ -31,7 +31,10 @@
|
||||
],
|
||||
"postAttachCommands": [
|
||||
// "attach 1",
|
||||
"compare-sections",
|
||||
// "compare-sections",
|
||||
"source debug/flipperapps.py",
|
||||
// "source debug/FreeRTOS/FreeRTOS.py",
|
||||
// "svd_load debug/STM32WB55_CM4.svd"
|
||||
]
|
||||
// "showDevDebugOutput": "raw",
|
||||
},
|
||||
@ -50,7 +53,8 @@
|
||||
"attach 1",
|
||||
"set confirm off",
|
||||
"set mem inaccessible-by-default off",
|
||||
"compare-sections",
|
||||
"source debug/flipperapps.py",
|
||||
// "compare-sections",
|
||||
]
|
||||
// "showDevDebugOutput": "raw",
|
||||
},
|
||||
@ -65,6 +69,9 @@
|
||||
"device": "STM32WB55RG",
|
||||
"svdFile": "./debug/STM32WB55_CM4.svd",
|
||||
"rtos": "FreeRTOS",
|
||||
"postAttachCommands": [
|
||||
"source debug/flipperapps.py",
|
||||
]
|
||||
// "showDevDebugOutput": "raw",
|
||||
},
|
||||
{
|
||||
@ -73,7 +80,7 @@
|
||||
"request": "launch",
|
||||
"program": "./lib/scons/scripts/scons.py",
|
||||
"args": [
|
||||
"sdk"
|
||||
"plugin_dist"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
3
.vscode/example/settings.json
vendored
3
.vscode/example/settings.json
vendored
@ -12,6 +12,9 @@
|
||||
"cortex-debug.openocdPath.windows": "${workspaceFolder}/toolchain/i686-windows/openocd/bin/openocd.exe",
|
||||
"cortex-debug.openocdPath.linux": "${workspaceFolder}/toolchain/x86_64-linux/openocd/bin/openocd",
|
||||
"cortex-debug.openocdPath.osx": "${workspaceFolder}/toolchain/x86_64-darwin/openocd/bin/openocd",
|
||||
"cortex-debug.gdbPath.windows": "${workspaceFolder}/toolchain/i686-windows/bin/arm-none-eabi-gdb-py.bat",
|
||||
"cortex-debug.gdbPath.linux": "${workspaceFolder}/toolchain/x86_64-linux/bin/arm-none-eabi-gdb-py",
|
||||
"cortex-debug.gdbPath.osx": "${workspaceFolder}/toolchain/x86_64-darwin/bin/arm-none-eabi-gdb",
|
||||
"editor.formatOnSave": true,
|
||||
"files.associations": {
|
||||
"*.scons": "python",
|
||||
|
30
.vscode/example/tasks.json
vendored
30
.vscode/example/tasks.json
vendored
@ -93,11 +93,41 @@
|
||||
"type": "shell",
|
||||
"command": "./fbt FIRMWARE_APP_SET=unit_tests FORCE=1 flash_usb"
|
||||
},
|
||||
{
|
||||
"label": "[Debug] Flash (USB, with resources)",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt FORCE=1 flash_usb_full"
|
||||
},
|
||||
{
|
||||
"label": "[Release] Flash (USB, with resources)",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt COMPACT=1 DEBUG=0 FORCE=1 flash_usb_full"
|
||||
},
|
||||
{
|
||||
"label": "[Debug] Build FAPs",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt plugin_dist"
|
||||
},
|
||||
{
|
||||
"label": "[Release] Build FAPs",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt COMPACT=1 DEBUG=0 plugin_dist"
|
||||
},
|
||||
{
|
||||
"label": "[Debug] Launch App on Flipper",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt launch_app APPSRC=${relativeFileDirname}"
|
||||
},
|
||||
{
|
||||
"label": "[Release] Launch App on Flipper",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt COMPACT=1 DEBUG=0 launch_app APPSRC=${relativeFileDirname}"
|
||||
}
|
||||
]
|
||||
}
|
@ -14,6 +14,10 @@ You should clone with
|
||||
$ git clone --recursive https://github.com/flipperdevices/flipperzero-firmware.git
|
||||
```
|
||||
|
||||
# Read the Docs
|
||||
|
||||
Check out details on [how to build firmware](documentation/fbt.md), [write applications](documentation/AppsOnSDCard.md), [un-brick your device](documentation/KeyCombo.md) and more in `documentation` folder.
|
||||
|
||||
# Update firmware
|
||||
|
||||
[Get Latest Firmware from Update Server](https://update.flipperzero.one/)
|
||||
|
28
SConstruct
28
SConstruct
@ -9,9 +9,10 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
DefaultEnvironment(tools=[])
|
||||
|
||||
EnsurePythonVersion(3, 8)
|
||||
|
||||
DefaultEnvironment(tools=[])
|
||||
# Progress(["OwO\r", "owo\r", "uwu\r", "owo\r"], interval=15)
|
||||
|
||||
|
||||
@ -58,6 +59,8 @@ distenv = coreenv.Clone(
|
||||
"-ex",
|
||||
"source debug/FreeRTOS/FreeRTOS.py",
|
||||
"-ex",
|
||||
"source debug/flipperapps.py",
|
||||
"-ex",
|
||||
"source debug/PyCortexMDebug/PyCortexMDebug.py",
|
||||
"-ex",
|
||||
"svd_load ${SVD_FILE}",
|
||||
@ -160,6 +163,28 @@ if GetOption("fullenv") or any(
|
||||
basic_dist = distenv.DistCommand("fw_dist", distenv["DIST_DEPENDS"])
|
||||
distenv.Default(basic_dist)
|
||||
|
||||
dist_dir = distenv.GetProjetDirName()
|
||||
plugin_dist = [
|
||||
distenv.Install(
|
||||
f"#/dist/{dist_dir}/apps/debug_elf",
|
||||
firmware_env["FW_EXTAPPS"]["debug"].values(),
|
||||
),
|
||||
*(
|
||||
distenv.Install(f"#/dist/{dist_dir}/apps/{dist_entry[0]}", dist_entry[1])
|
||||
for dist_entry in firmware_env["FW_EXTAPPS"]["dist"].values()
|
||||
),
|
||||
]
|
||||
Depends(plugin_dist, firmware_env["FW_EXTAPPS"]["validators"].values())
|
||||
Alias("plugin_dist", plugin_dist)
|
||||
# distenv.Default(plugin_dist)
|
||||
|
||||
plugin_resources_dist = list(
|
||||
distenv.Install(f"#/assets/resources/apps/{dist_entry[0]}", dist_entry[1])
|
||||
for dist_entry in firmware_env["FW_EXTAPPS"]["dist"].values()
|
||||
)
|
||||
distenv.Depends(firmware_env["FW_RESOURCES"], plugin_resources_dist)
|
||||
|
||||
|
||||
# Target for bundling core2 package for qFlipper
|
||||
copro_dist = distenv.CoproBuilder(
|
||||
distenv.Dir("assets/core2_firmware"),
|
||||
@ -240,7 +265,6 @@ firmware_env.Append(
|
||||
"site_scons",
|
||||
"scripts",
|
||||
# Extra files
|
||||
"applications/extapps.scons",
|
||||
"SConstruct",
|
||||
"firmware.scons",
|
||||
"fbt_options.py",
|
||||
|
@ -1,38 +1,90 @@
|
||||
# Structure
|
||||
|
||||
- `about` - Small About application that shows flipper info
|
||||
- `accessor` - Wiegand server
|
||||
- `application.h` - Firmware application list header
|
||||
|
||||
|
||||
## debug
|
||||
|
||||
Applications for factory testing the Flipper.
|
||||
|
||||
- `accessor` - Wiegand server
|
||||
- `battery_test_app` - Battery debug app
|
||||
- `blink_test` - LED blinker
|
||||
- `bt_debug_app` - BT test app. Requires full BT stack installed
|
||||
- `display_test` - Various display tests & tweaks
|
||||
- `file_browser_test` - Test UI for file picker
|
||||
- `keypad_test` - Keypad test
|
||||
- `lfrfid_debug` - LF RFID debug tool
|
||||
- `text_box_test` - UI tests
|
||||
- `uart_echo` - UART mode test
|
||||
- `unit_tests` - Unit tests
|
||||
- `usb_mouse` - USB HID test
|
||||
- `usb_test` - Other USB tests
|
||||
- `vibro_test` - Vibro test
|
||||
|
||||
|
||||
## main
|
||||
|
||||
Applications for main Flipper menu.
|
||||
|
||||
- `archive` - Archive and file manager
|
||||
- `bad_usb` - Bad USB application
|
||||
- `fap_loader` - External applications loader
|
||||
- `gpio` - GPIO application: includes USART bridge and GPIO control
|
||||
- `ibutton` - iButton application, onewire keys and more
|
||||
- `infrared` - Infrared application, controls your IR devices
|
||||
- `lfrfid` - LF RFID application
|
||||
- `nfc` - NFC application, HF rfid, EMV and etc
|
||||
- `subghz` - SubGhz application, 433 fobs and etc
|
||||
- `u2f` - U2F Application
|
||||
|
||||
|
||||
## plugins
|
||||
|
||||
Extra apps for Plugins & App Loader menus.
|
||||
|
||||
- `bt_hid_app` - BT Remote controller
|
||||
- `music_player` - Music player app (demo)
|
||||
- `picopass` - Picopass tool
|
||||
- `snake_game` - Snake game application
|
||||
|
||||
|
||||
## services
|
||||
|
||||
Background services providing system APIs to applications.
|
||||
|
||||
- `bt` - BLE service and application
|
||||
- `cli` - Console service and API
|
||||
- `crypto` - Crypto cli tools
|
||||
- `debug_tools` - Different tools that we use for debug
|
||||
- `desktop` - Desktop service
|
||||
- `dialogs` - Dialogs service: GUI Dialogs for your app
|
||||
- `dolphin` - Dolphin service and supplementary apps
|
||||
- `gpio` - GPIO application: includes USART bridge and GPIO control
|
||||
- `gui` - GUI service and API
|
||||
- `ibutton` - iButton application, onewire keys and more
|
||||
- `input` - Input service
|
||||
- `infrared` - Infrared application, controls your IR devices
|
||||
- `lfrfid` - LF RFID application
|
||||
- `lfrfid_debug` - LF RFID debug tool
|
||||
- `loader` - Application loader service
|
||||
- `music_player` - Music player app (demo)
|
||||
- `nfc` - NFC application, HF rfid, EMV and etc
|
||||
- `notification` - Notification service
|
||||
- `power` - Power service
|
||||
- `power_observer` - Power debug tool
|
||||
- `rpc` - RPC service and API
|
||||
- `scened_app_example` - C++ application example
|
||||
- `snake_game` - Snake game application
|
||||
- `storage` - Storage service, internal + sdcard
|
||||
- `storage_settings` - Storage settings app
|
||||
- `subghz` - SubGhz application, 433 fobs and etc
|
||||
- `system` - System settings, tools and API
|
||||
- `tests` - Unit tests and etc
|
||||
- `u2f` - U2F Application
|
||||
- `updater` - Update service & application
|
||||
|
||||
- `application.h` - Firmware application list header
|
||||
|
||||
## settings
|
||||
|
||||
Small applications providing configuration for basic firmware and its services.
|
||||
|
||||
- `about` - Small About application that shows flipper info
|
||||
- `bt_settings_app` - Bluetooth options
|
||||
- `desktop_settings` - Desktop configuration
|
||||
- `dolphin_passport` - Dolphin passport app
|
||||
- `notification_settings` - LCD brightness, sound volume, etc configuration
|
||||
- `power_settings_app` - Basic power options
|
||||
- `storage_settings` - Storage settings app
|
||||
- `system` - System settings
|
||||
|
||||
|
||||
## system
|
||||
|
||||
Utility apps not visible in other menus.
|
||||
|
||||
- `storage_move_to_sd` - Data migration tool for internal storage
|
||||
- `updater` - Update service & application
|
||||
|
@ -1,66 +0,0 @@
|
||||
App(
|
||||
appid="bt",
|
||||
name="BtSrv",
|
||||
apptype=FlipperAppType.SERVICE,
|
||||
entry_point="bt_srv",
|
||||
cdefines=["SRV_BT"],
|
||||
requires=[
|
||||
"cli",
|
||||
"dialogs",
|
||||
],
|
||||
provides=[
|
||||
"bt_start",
|
||||
"bt_settings",
|
||||
"bt_debug",
|
||||
],
|
||||
stack_size=1 * 1024,
|
||||
order=20,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="bt_start",
|
||||
apptype=FlipperAppType.STARTUP,
|
||||
entry_point="bt_on_system_start",
|
||||
order=70,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="bt_settings",
|
||||
name="Bluetooth",
|
||||
apptype=FlipperAppType.SETTINGS,
|
||||
entry_point="bt_settings_app",
|
||||
stack_size=1 * 1024,
|
||||
requires=[
|
||||
"bt",
|
||||
"gui",
|
||||
],
|
||||
order=10,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="bt_debug",
|
||||
name="Bluetooth Debug",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="bt_debug_app",
|
||||
stack_size=1 * 1024,
|
||||
requires=[
|
||||
"bt",
|
||||
"gui",
|
||||
"dialogs",
|
||||
],
|
||||
order=110,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="bt_hid",
|
||||
name="Bluetooth Remote",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="bt_hid_app",
|
||||
stack_size=1 * 1024,
|
||||
cdefines=["APP_BLE_HID"],
|
||||
requires=[
|
||||
"bt",
|
||||
"gui",
|
||||
],
|
||||
order=10,
|
||||
)
|
@ -7,4 +7,5 @@ App(
|
||||
requires=["gui"],
|
||||
stack_size=4 * 1024,
|
||||
order=40,
|
||||
fap_category="Debug",
|
||||
)
|
16
applications/debug/application.fam
Normal file
16
applications/debug/application.fam
Normal file
@ -0,0 +1,16 @@
|
||||
App(
|
||||
appid="debug_apps",
|
||||
name="Basic debug apps bundle",
|
||||
apptype=FlipperAppType.METAPACKAGE,
|
||||
provides=[
|
||||
"blink_test",
|
||||
"vibro_test",
|
||||
"keypad_test",
|
||||
"usb_test",
|
||||
"usb_mouse",
|
||||
"uart_echo",
|
||||
"display_test",
|
||||
"text_box_test",
|
||||
"file_browser_test",
|
||||
],
|
||||
)
|
14
applications/debug/battery_test_app/application.fam
Normal file
14
applications/debug/battery_test_app/application.fam
Normal file
@ -0,0 +1,14 @@
|
||||
App(
|
||||
appid="battery_test",
|
||||
name="Battery Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="battery_test_app",
|
||||
cdefines=["APP_BATTERY_TEST"],
|
||||
requires=[
|
||||
"gui",
|
||||
"power",
|
||||
],
|
||||
stack_size=1 * 1024,
|
||||
order=130,
|
||||
fap_category="Debug",
|
||||
)
|
@ -27,7 +27,7 @@ static void battery_test_battery_info_update_model(void* context) {
|
||||
.charge = app->info.charge,
|
||||
.health = app->info.health,
|
||||
};
|
||||
battery_info_set_data(app->batery_info, &battery_info_data);
|
||||
battery_info_set_data(app->battery_info, &battery_info_data);
|
||||
notification_message(app->notifications, &sequence_display_backlight_on);
|
||||
}
|
||||
|
||||
@ -48,13 +48,13 @@ BatteryTestApp* battery_test_alloc() {
|
||||
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
|
||||
|
||||
// Views
|
||||
app->batery_info = battery_info_alloc();
|
||||
app->battery_info = battery_info_alloc();
|
||||
view_set_previous_callback(
|
||||
battery_info_get_view(app->batery_info), battery_test_exit_confirm_view);
|
||||
battery_info_get_view(app->battery_info), battery_test_exit_confirm_view);
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher,
|
||||
BatteryTestAppViewBatteryInfo,
|
||||
battery_info_get_view(app->batery_info));
|
||||
battery_info_get_view(app->battery_info));
|
||||
|
||||
app->dialog = dialog_ex_alloc();
|
||||
dialog_ex_set_header(app->dialog, "Close Battery Test?", 64, 12, AlignCenter, AlignTop);
|
||||
@ -76,7 +76,7 @@ void battery_test_free(BatteryTestApp* app) {
|
||||
|
||||
// Views
|
||||
view_dispatcher_remove_view(app->view_dispatcher, BatteryTestAppViewBatteryInfo);
|
||||
battery_info_free(app->batery_info);
|
||||
battery_info_free(app->battery_info);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, BatteryTestAppViewExitDialog);
|
||||
dialog_ex_free(app->dialog);
|
||||
// View dispatcher
|
@ -6,14 +6,15 @@
|
||||
#include <notification/notification.h>
|
||||
|
||||
#include <gui/modules/dialog_ex.h>
|
||||
#include <power/power_settings_app/views/battery_info.h>
|
||||
// FIXME
|
||||
#include "../settings/power_settings_app/views/battery_info.h"
|
||||
|
||||
typedef struct {
|
||||
Power* power;
|
||||
Gui* gui;
|
||||
NotificationApp* notifications;
|
||||
ViewDispatcher* view_dispatcher;
|
||||
BatteryInfo* batery_info;
|
||||
BatteryInfo* battery_info;
|
||||
DialogEx* dialog;
|
||||
PowerInfo info;
|
||||
} BatteryTestApp;
|
11
applications/debug/blink_test/application.fam
Normal file
11
applications/debug/blink_test/application.fam
Normal file
@ -0,0 +1,11 @@
|
||||
App(
|
||||
appid="blink_test",
|
||||
name="Blink Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="blink_test_app",
|
||||
cdefines=["APP_BLINK"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=10,
|
||||
fap_category="Debug",
|
||||
)
|
18
applications/debug/bt_debug_app/application.fam
Normal file
18
applications/debug/bt_debug_app/application.fam
Normal file
@ -0,0 +1,18 @@
|
||||
App(
|
||||
appid="bt_debug",
|
||||
name="Bluetooth Debug",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="bt_debug_app",
|
||||
cdefines=["SRV_BT"],
|
||||
requires=[
|
||||
"bt",
|
||||
"gui",
|
||||
"dialogs",
|
||||
],
|
||||
provides=[
|
||||
"bt_debug",
|
||||
],
|
||||
stack_size=1 * 1024,
|
||||
order=110,
|
||||
fap_category="Debug",
|
||||
)
|
@ -9,7 +9,7 @@
|
||||
#include <gui/modules/submenu.h>
|
||||
#include "views/bt_carrier_test.h"
|
||||
#include "views/bt_packet_test.h"
|
||||
#include "../bt_settings.h"
|
||||
#include <bt/bt_settings.h>
|
||||
|
||||
typedef struct {
|
||||
BtSettings settings;
|
11
applications/debug/display_test/application.fam
Normal file
11
applications/debug/display_test/application.fam
Normal file
@ -0,0 +1,11 @@
|
||||
App(
|
||||
appid="display_test",
|
||||
name="Display Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="display_test_app",
|
||||
cdefines=["APP_DISPLAY_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=120,
|
||||
fap_category="Debug",
|
||||
)
|
11
applications/debug/file_browser_test/application.fam
Normal file
11
applications/debug/file_browser_test/application.fam
Normal file
@ -0,0 +1,11 @@
|
||||
App(
|
||||
appid="file_browser_test",
|
||||
name="File Browser Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="file_browser_app",
|
||||
cdefines=["APP_FILE_BROWSER_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=2 * 1024,
|
||||
order=150,
|
||||
fap_category="Debug",
|
||||
)
|
11
applications/debug/keypad_test/application.fam
Normal file
11
applications/debug/keypad_test/application.fam
Normal file
@ -0,0 +1,11 @@
|
||||
App(
|
||||
appid="keypad_test",
|
||||
name="Keypad Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="keypad_test_app",
|
||||
cdefines=["APP_KEYPAD_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=30,
|
||||
fap_category="Debug",
|
||||
)
|
@ -5,8 +5,11 @@ App(
|
||||
entry_point="lfrfid_debug_app",
|
||||
requires=[
|
||||
"gui",
|
||||
"lfrfid",
|
||||
],
|
||||
provides=[
|
||||
"lfrfid_debug",
|
||||
],
|
||||
stack_size=1 * 1024,
|
||||
order=100,
|
||||
fap_category="Debug",
|
||||
)
|
@ -9,9 +9,8 @@
|
||||
|
||||
#include <gui/modules/submenu.h>
|
||||
|
||||
#include <lfrfid_debug/views/lfrfid_debug_view_tune.h>
|
||||
|
||||
#include <lfrfid_debug/scenes/lfrfid_debug_scene.h>
|
||||
#include "views/lfrfid_debug_view_tune.h"
|
||||
#include "scenes/lfrfid_debug_scene.h"
|
||||
|
||||
typedef struct LfRfidDebug LfRfidDebug;
|
||||
|
11
applications/debug/text_box_test/application.fam
Normal file
11
applications/debug/text_box_test/application.fam
Normal file
@ -0,0 +1,11 @@
|
||||
App(
|
||||
appid="text_box_test",
|
||||
name="Text Box Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="text_box_test_app",
|
||||
cdefines=["APP_TEXT_BOX_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=140,
|
||||
fap_category="Debug",
|
||||
)
|
11
applications/debug/uart_echo/application.fam
Normal file
11
applications/debug/uart_echo/application.fam
Normal file
@ -0,0 +1,11 @@
|
||||
App(
|
||||
appid="uart_echo",
|
||||
name="UART Echo",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="uart_echo_app",
|
||||
cdefines=["APP_UART_ECHO"],
|
||||
requires=["gui"],
|
||||
stack_size=2 * 1024,
|
||||
order=70,
|
||||
fap_category="Debug",
|
||||
)
|
@ -10,7 +10,7 @@ App(
|
||||
App(
|
||||
appid="delay_test",
|
||||
name="Delay Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
apptype=FlipperAppType.SYSTEM,
|
||||
entry_point="delay_test_app",
|
||||
stack_size=1 * 1024,
|
||||
requires=["unit_tests"],
|
@ -1,6 +1,6 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <applications/storage/storage.h>
|
||||
#include <storage/storage.h>
|
||||
#include <lib/flipper_format/flipper_format.h>
|
||||
#include <lib/nfc/protocols/nfca.h>
|
||||
#include <lib/digital_signal/digital_signal.h>
|
11
applications/debug/usb_mouse/application.fam
Normal file
11
applications/debug/usb_mouse/application.fam
Normal file
@ -0,0 +1,11 @@
|
||||
App(
|
||||
appid="usb_mouse",
|
||||
name="USB Mouse Demo",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="usb_mouse_app",
|
||||
cdefines=["APP_USB_MOUSE"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=60,
|
||||
fap_category="Debug",
|
||||
)
|
11
applications/debug/usb_test/application.fam
Normal file
11
applications/debug/usb_test/application.fam
Normal file
@ -0,0 +1,11 @@
|
||||
App(
|
||||
appid="usb_test",
|
||||
name="USB Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="usb_test_app",
|
||||
cdefines=["APP_USB_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=50,
|
||||
fap_category="Debug",
|
||||
)
|
11
applications/debug/vibro_test/application.fam
Normal file
11
applications/debug/vibro_test/application.fam
Normal file
@ -0,0 +1,11 @@
|
||||
App(
|
||||
appid="vibro_test",
|
||||
name="Vibro Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="vibro_test_app",
|
||||
cdefines=["APP_VIBRO_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=20,
|
||||
fap_category="Debug",
|
||||
)
|
@ -1,115 +0,0 @@
|
||||
App(
|
||||
appid="debug_apps",
|
||||
name="Basic debug apps bundle",
|
||||
apptype=FlipperAppType.METAPACKAGE,
|
||||
provides=[
|
||||
"blink_test",
|
||||
"vibro_test",
|
||||
"keypad_test",
|
||||
"usb_test",
|
||||
"usb_mouse",
|
||||
"uart_echo",
|
||||
"display_test",
|
||||
"text_box_test",
|
||||
"file_browser_test",
|
||||
],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="blink_test",
|
||||
name="Blink Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="blink_test_app",
|
||||
cdefines=["APP_BLINK"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=10,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="vibro_test",
|
||||
name="Vibro Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="vibro_test_app",
|
||||
cdefines=["APP_VIBRO_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=20,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="keypad_test",
|
||||
name="Keypad Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="keypad_test_app",
|
||||
cdefines=["APP_KEYPAD_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=30,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="usb_test",
|
||||
name="USB Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="usb_test_app",
|
||||
cdefines=["APP_USB_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=50,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="usb_mouse",
|
||||
name="USB Mouse Demo",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="usb_mouse_app",
|
||||
cdefines=["APP_USB_MOUSE"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=60,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="uart_echo",
|
||||
name="UART Echo",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="uart_echo_app",
|
||||
cdefines=["APP_UART_ECHO"],
|
||||
requires=["gui"],
|
||||
stack_size=2 * 1024,
|
||||
order=70,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="display_test",
|
||||
name="Display Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="display_test_app",
|
||||
cdefines=["APP_DISPLAY_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=120,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="text_box_test",
|
||||
name="Text Box Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="text_box_test_app",
|
||||
cdefines=["APP_TEXT_BOX_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=140,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="file_browser_test",
|
||||
name="File Browser Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="file_browser_app",
|
||||
cdefines=["APP_FILE_BROWSER_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=2 * 1024,
|
||||
order=150,
|
||||
)
|
@ -1,58 +0,0 @@
|
||||
Import("ENV")
|
||||
|
||||
|
||||
from fbt.appmanifest import FlipperAppType
|
||||
|
||||
appenv = ENV.Clone(tools=["fbt_extapps"])
|
||||
|
||||
appenv.Replace(
|
||||
LINKER_SCRIPT="application-ext",
|
||||
STRIPFLAGS=[
|
||||
"--strip-debug",
|
||||
"--strip-unneeded",
|
||||
"-d",
|
||||
"-g",
|
||||
"-S",
|
||||
],
|
||||
)
|
||||
|
||||
appenv.AppendUnique(
|
||||
CCFLAGS=[
|
||||
"-Os",
|
||||
"-ggdb3",
|
||||
"-mword-relocations",
|
||||
"-mlong-calls",
|
||||
"-fno-common",
|
||||
"-nostdlib",
|
||||
"-fvisibility=hidden",
|
||||
],
|
||||
LINKFLAGS=[
|
||||
"-r",
|
||||
"-s",
|
||||
# "-Bsymbolic",
|
||||
"-nostartfiles",
|
||||
"-mlong-calls",
|
||||
"-fno-common",
|
||||
"-nostdlib",
|
||||
"-Wl,--gc-sections",
|
||||
"-Wl,--no-export-dynamic",
|
||||
"-fvisibility=hidden",
|
||||
"-Wl,-e${APP_ENTRY}",
|
||||
"-Xlinker",
|
||||
"-Map=${TARGET}.map",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
extapps = []
|
||||
for apptype in (FlipperAppType.PLUGIN, FlipperAppType.EXTERNAL):
|
||||
for app in appenv["APPBUILD"].get_apps_of_type(apptype):
|
||||
extapps.append(appenv.BuildAppElf(app))
|
||||
|
||||
# Ugly access to global option
|
||||
if extra_app_list := GetOption("extra_ext_apps"):
|
||||
for extra_app in extra_app_list.split(","):
|
||||
extapps.append(appenv.BuildAppElf(appenv["APPMGR"].get(extra_app)))
|
||||
|
||||
Alias(appenv["FIRMWARE_BUILD_CFG"] + "_extapps", extapps)
|
||||
Return("extapps")
|
@ -1,13 +0,0 @@
|
||||
App(
|
||||
appid="gui",
|
||||
name="GuiSrv",
|
||||
apptype=FlipperAppType.SERVICE,
|
||||
entry_point="gui_srv",
|
||||
cdefines=["SRV_GUI"],
|
||||
requires=[
|
||||
"input",
|
||||
"notification",
|
||||
],
|
||||
stack_size=2 * 1024,
|
||||
order=70,
|
||||
)
|
@ -1,131 +0,0 @@
|
||||
#include "dialog.h"
|
||||
#include <gui/elements.h>
|
||||
#include <furi.h>
|
||||
|
||||
struct Dialog {
|
||||
View* view;
|
||||
void* context;
|
||||
DialogResultCallback callback;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char* header_text;
|
||||
const char* text;
|
||||
const char* left_text;
|
||||
const char* right_text;
|
||||
} DialogModel;
|
||||
|
||||
static void dialog_view_draw_callback(Canvas* canvas, void* _model) {
|
||||
DialogModel* model = _model;
|
||||
uint8_t canvas_center = canvas_width(canvas) / 2;
|
||||
|
||||
// Prepare canvas
|
||||
canvas_clear(canvas);
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
|
||||
// Draw header
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, canvas_center, 17, AlignCenter, AlignBottom, model->header_text);
|
||||
|
||||
// Draw text
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
elements_multiline_text_aligned(
|
||||
canvas, canvas_center, 32, AlignCenter, AlignCenter, model->text);
|
||||
|
||||
// Draw buttons
|
||||
elements_button_left(canvas, model->left_text);
|
||||
elements_button_right(canvas, model->right_text);
|
||||
}
|
||||
|
||||
static bool dialog_view_input_callback(InputEvent* event, void* context) {
|
||||
Dialog* dialog = context;
|
||||
bool consumed = false;
|
||||
|
||||
// Process key presses only
|
||||
if(event->type == InputTypeShort && dialog->callback) {
|
||||
if(event->key == InputKeyLeft) {
|
||||
dialog->callback(DialogResultLeft, dialog->context);
|
||||
consumed = true;
|
||||
} else if(event->key == InputKeyRight) {
|
||||
dialog->callback(DialogResultRight, dialog->context);
|
||||
consumed = true;
|
||||
} else if(event->key == InputKeyBack) {
|
||||
dialog->callback(DialogResultBack, dialog->context);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
Dialog* dialog_alloc() {
|
||||
Dialog* dialog = malloc(sizeof(Dialog));
|
||||
dialog->view = view_alloc();
|
||||
view_set_context(dialog->view, dialog);
|
||||
view_allocate_model(dialog->view, ViewModelTypeLockFree, sizeof(DialogModel));
|
||||
view_set_draw_callback(dialog->view, dialog_view_draw_callback);
|
||||
view_set_input_callback(dialog->view, dialog_view_input_callback);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
void dialog_free(Dialog* dialog) {
|
||||
furi_assert(dialog);
|
||||
view_free(dialog->view);
|
||||
free(dialog);
|
||||
}
|
||||
|
||||
View* dialog_get_view(Dialog* dialog) {
|
||||
furi_assert(dialog);
|
||||
return dialog->view;
|
||||
}
|
||||
|
||||
void dialog_set_result_callback(Dialog* dialog, DialogResultCallback callback) {
|
||||
furi_assert(dialog);
|
||||
dialog->callback = callback;
|
||||
}
|
||||
|
||||
void dialog_set_context(Dialog* dialog, void* context) {
|
||||
furi_assert(dialog);
|
||||
dialog->context = context;
|
||||
}
|
||||
|
||||
void dialog_set_header_text(Dialog* dialog, const char* text) {
|
||||
furi_assert(dialog);
|
||||
furi_assert(text);
|
||||
with_view_model(
|
||||
dialog->view, (DialogModel * model) {
|
||||
model->header_text = text;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void dialog_set_text(Dialog* dialog, const char* text) {
|
||||
furi_assert(dialog);
|
||||
furi_assert(text);
|
||||
with_view_model(
|
||||
dialog->view, (DialogModel * model) {
|
||||
model->text = text;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void dialog_set_left_button_text(Dialog* dialog, const char* text) {
|
||||
furi_assert(dialog);
|
||||
furi_assert(text);
|
||||
with_view_model(
|
||||
dialog->view, (DialogModel * model) {
|
||||
model->left_text = text;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void dialog_set_right_button_text(Dialog* dialog, const char* text) {
|
||||
furi_assert(dialog);
|
||||
furi_assert(text);
|
||||
with_view_model(
|
||||
dialog->view, (DialogModel * model) {
|
||||
model->right_text = text;
|
||||
return true;
|
||||
});
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user