diff --git a/.vscode/example/tasks.json b/.vscode/example/tasks.json index c16c3ab4..beedf886 100644 --- a/.vscode/example/tasks.json +++ b/.vscode/example/tasks.json @@ -138,6 +138,18 @@ "Serial Console" ] }, + { + "label": "[Debug] Build and upload all FAPs to Flipper over USB", + "group": "build", + "type": "shell", + "command": "./fbt fap_deploy" + }, + { + "label": "[Release] Build and upload all FAPs to Flipper over USB", + "group": "build", + "type": "shell", + "command": "./fbt COMPACT=1 DEBUG=0 fap_deploy" + }, { // Press Ctrl+] to quit "label": "Serial Console", @@ -145,7 +157,7 @@ "command": "./fbt cli", "group": "none", "isBackground": true, - "options": { + "options": { "env": { "FBT_NO_SYNC": "0" } @@ -162,4 +174,4 @@ } } ] -} +} \ No newline at end of file diff --git a/SConstruct b/SConstruct index 138b52d9..b8c65044 100644 --- a/SConstruct +++ b/SConstruct @@ -165,6 +165,14 @@ Alias("fap_dist", fap_dist) distenv.Depends(firmware_env["FW_RESOURCES"], firmware_env["FW_EXTAPPS"].resources_dist) +# Copy all faps to device + +fap_deploy = distenv.PhonyTarget( + "fap_deploy", + "${PYTHON3} ${ROOT_DIR}/scripts/storage.py send ${SOURCE} /ext/apps", + source=Dir("#/assets/resources/apps"), +) + # Target for bundling core2 package for qFlipper copro_dist = distenv.CoproBuilder( diff --git a/scripts/fbt_tools/fbt_help.py b/scripts/fbt_tools/fbt_help.py index 0475f51b..8cce9335 100644 --- a/scripts/fbt_tools/fbt_help.py +++ b/scripts/fbt_tools/fbt_help.py @@ -11,6 +11,8 @@ Building: Build all FAP apps fap_{APPID}, launch_app APPSRC={APPID}: Build FAP app with appid={APPID}; upload & start it over USB + fap_deploy: + Build and upload all FAP apps over USB Flashing & debugging: flash, flash_blackmagic, jflash: diff --git a/scripts/runfap.py b/scripts/runfap.py index c2c0f78d..410b3e7d 100644 --- a/scripts/runfap.py +++ b/scripts/runfap.py @@ -15,6 +15,13 @@ import serial.tools.list_ports as list_ports class Main(App): def init(self): self.parser.add_argument("-p", "--port", help="CDC Port", default="auto") + self.parser.add_argument( + "-n", + "--no-launch", + dest="launch_app", + action="store_false", + help="Don't launch app", + ) self.parser.add_argument("fap_src_path", help="App file to upload") self.parser.add_argument( @@ -84,11 +91,14 @@ class Main(App): self.logger.error(f"Error: upload failed: {storage.last_error}") return -3 - storage.send_and_wait_eol(f'loader open "Applications" {fap_dst_path}\r') - result = storage.read.until(storage.CLI_EOL) - if len(result): - self.logger.error(f"Unexpected response: {result.decode('ascii')}") - return -4 + if self.args.launch_app: + storage.send_and_wait_eol( + f'loader open "Applications" {fap_dst_path}\r' + ) + result = storage.read.until(storage.CLI_EOL) + if len(result): + self.logger.error(f"Unexpected response: {result.decode('ascii')}") + return -4 return 0 finally: