Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FL-3954, FL-3955] New CLI architecture #4111

Open
wants to merge 85 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
bf7fefc
feat: FuriThread stdin
portasynthinca3 Oct 31, 2024
a9d3264
Merge branch 'dev' into portasynthinca3/3927-thread-stdin
portasynthinca3 Oct 31, 2024
4c59243
ci: fix f18
portasynthinca3 Oct 31, 2024
9f2e934
Merge branch 'dev' into portasynthinca3/3927-thread-stdin
portasynthinca3 Nov 5, 2024
f1eb60b
feat: stdio callback context
portasynthinca3 Nov 7, 2024
da187fe
Merge branch 'dev' into portasynthinca3/3927-thread-stdin
portasynthinca3 Nov 7, 2024
a4a7a41
feat: FuriPipe
portasynthinca3 Nov 7, 2024
004e3a6
POTENTIALLY EXPLOSIVE pipe welding
portasynthinca3 Nov 8, 2024
920a3e9
fix: non-explosive welding
portasynthinca3 Nov 11, 2024
f792fde
Revert welding
portasynthinca3 Nov 12, 2024
1c9dbb3
docs: furi_pipe
portasynthinca3 Nov 12, 2024
bd28387
feat: pipe event loop integration
portasynthinca3 Nov 12, 2024
acf307d
update f18 sdk
portasynthinca3 Nov 12, 2024
2bcc3c4
f18
portasynthinca3 Nov 12, 2024
af7ff81
docs: make doxygen happy
portasynthinca3 Nov 12, 2024
857ad33
fix: event loop not triggering when pipe attached to stdio
portasynthinca3 Nov 13, 2024
bc9223a
fix: partial stdout in pipe
portasynthinca3 Nov 13, 2024
dac9c00
allow simultaneous in and out subscription in event loop
portasynthinca3 Nov 13, 2024
8837c8b
feat: vcp i/o
portasynthinca3 Nov 13, 2024
20ce18f
feat: cli ansi stuffs and history
portasynthinca3 Nov 14, 2024
1b31e70
feat: more line editing
portasynthinca3 Nov 15, 2024
82169a7
working but slow cli rewrite
portasynthinca3 Nov 28, 2024
fa1919c
restore previous speed after 4 days of debugging 🥲
portasynthinca3 Nov 28, 2024
bd82671
fix: cli_app_should_stop
portasynthinca3 Nov 28, 2024
34c6566
fix: cli and event_loop memory leaks
portasynthinca3 Nov 28, 2024
a346d8c
style: remove commented out code
portasynthinca3 Nov 29, 2024
c3f7825
ci: fix pvs warnings
portasynthinca3 Nov 29, 2024
b0b73c0
fix: unit tests, event_loop crash
portasynthinca3 Dec 2, 2024
8e05df6
ci: fix build
portasynthinca3 Dec 3, 2024
789e337
ci: silence pvs warning
portasynthinca3 Dec 3, 2024
2e1d236
feat: cli gpio
portasynthinca3 Dec 3, 2024
1280a8e
ci: fix formatting
portasynthinca3 Dec 3, 2024
9d34069
Fix memory leak during event loop unsubscription
gsurkov Dec 4, 2024
7a69000
Event better memory leak fix
gsurkov Dec 4, 2024
da047a3
feat: cli completions
portasynthinca3 Dec 7, 2024
824b644
Merge remote-tracking branch 'origin/dev' into portasynthinca3/3928-c…
portasynthinca3 Dec 24, 2024
c8e0a55
Merge branch 'dev' into portasynthinca3/3928-cli-threads
portasynthinca3 Dec 24, 2024
daf8ad7
merge fixups
portasynthinca3 Dec 24, 2024
58bd664
temporarily exclude speaker_debug app
portasynthinca3 Dec 24, 2024
0916aeb
pvs and unit tests fixups
portasynthinca3 Dec 24, 2024
82c1e71
feat: commands in fals
portasynthinca3 Dec 25, 2024
c88891e
move commands out of flash, code cleanup
portasynthinca3 Jan 9, 2025
1a54a00
ci: fix errors
portasynthinca3 Jan 9, 2025
c316a9f
fix: run commands in buffer when stopping session
portasynthinca3 Jan 9, 2025
c7c397b
Merge branch 'dev' into portasynthinca3/3928-cli-threads
skotopes Jan 16, 2025
a1d5239
speedup cli file transfer
portasynthinca3 Feb 4, 2025
1dce569
fix f18
portasynthinca3 Feb 4, 2025
3722940
separate cli_shell into modules
portasynthinca3 Feb 10, 2025
f88d8a5
Merge remote-tracking branch 'origin/dev' into portasynthinca3/3928-c…
portasynthinca3 Feb 10, 2025
e4a82f3
fix pvs warning
portasynthinca3 Feb 10, 2025
2e4fed6
Merge remote-tracking branch 'origin/dev' into portasynthinca3/3928-c…
skotopes Feb 12, 2025
321078c
Merge remote-tracking branch 'origin/dev' into portasynthinca3/3928-c…
portasynthinca3 Feb 12, 2025
687bbe7
fix qflipper refusing to connect
portasynthinca3 Feb 12, 2025
c150a42
remove temp debug logs
portasynthinca3 Feb 12, 2025
18b55cf
remove erroneous conclusion
portasynthinca3 Feb 13, 2025
97910fb
Fix memory leak during event loop unsubscription
gsurkov Dec 4, 2024
12bd902
Event better memory leak fix
gsurkov Dec 4, 2024
e442375
unit test for the fix
portasynthinca3 Feb 13, 2025
1cd3bbd
improve thread stdio callback signatures
portasynthinca3 Dec 2, 2024
c79bdbd
pipe stdout timeout
portasynthinca3 Feb 12, 2025
9065348
update api symbols
portasynthinca3 Feb 13, 2025
0c481f9
Merge branch 'portasynthinca3/3958-stdio-api-improvements' into porta…
portasynthinca3 Feb 13, 2025
0247801
Merge new architecture from 'portasynthinca3/3928-cli-threads', refac…
portasynthinca3 Feb 13, 2025
a2d43ac
fix f18, formatting
portasynthinca3 Feb 13, 2025
f957e8c
fix pvs warnings
portasynthinca3 Feb 13, 2025
f16d054
increase stack size, hope to fix unit tests
portasynthinca3 Feb 13, 2025
6f4505a
Merge remote-tracking branch 'origin/dev' into portasynthinca3/3954-3…
skotopes Feb 21, 2025
0ed3a84
cli: revert flag changes
portasynthinca3 Feb 22, 2025
30a363f
cli: fix formatting
portasynthinca3 Feb 22, 2025
433a2c0
cli, fbt: loopback perf benchmark
portasynthinca3 Feb 24, 2025
11b0e6a
thread, event_loop: subscribing to thread flags
portasynthinca3 Feb 24, 2025
327e327
cli: signal internal events using thread flags, improve performance
portasynthinca3 Feb 24, 2025
a14c47a
fix f18, formatting
portasynthinca3 Feb 24, 2025
9aec0cc
Merge branch 'dev' into portasynthinca3/3954-3955-new-cli-architecture
skotopes Feb 24, 2025
a66d105
event_loop: fix crash
portasynthinca3 Feb 24, 2025
6044e42
Merge branch 'portasynthinca3/3954-3955-new-cli-architecture' of http…
portasynthinca3 Feb 24, 2025
7574d67
storage_cli: increase write_chunk buffer size again
portasynthinca3 Feb 25, 2025
dd8f1d0
cli: explanation for order=0
portasynthinca3 Feb 25, 2025
e5baac5
thread, event_loop: thread flags callback refactor
portasynthinca3 Feb 25, 2025
d291005
cli: increase stack size
portasynthinca3 Feb 25, 2025
bce7307
cli: rename cli_app_should_stop -> cli_is_pipe_broken_or_is_etx_next_…
portasynthinca3 Feb 25, 2025
1ebca10
cli: use plain array instead of mlib for history
portasynthinca3 Feb 25, 2025
fd36ca1
cli: prepend file name to static fns
portasynthinca3 Feb 25, 2025
3f57a00
cli: fix formatting
portasynthinca3 Feb 25, 2025
168df2d
cli_shell: increase stack size
portasynthinca3 Feb 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,21 @@ distenv.PhonyTarget(
],
)


# Measure CLI loopback performance
distenv.PhonyTarget(
"cli_perf",
[
[
"${PYTHON3}",
"${FBT_SCRIPT_DIR}/serial_cli_perf.py",
"-p",
"${FLIP_PORT}",
"${ARGS}",
]
],
)

# Update WiFi devboard firmware with release channel
distenv.PhonyTarget(
"devboard_flash",
Expand Down
5 changes: 3 additions & 2 deletions applications/debug/speaker_debug/speaker_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <music_worker/music_worker.h>
#include <cli/cli.h>
#include <toolbox/args.h>
#include <toolbox/pipe.h>

#define TAG "SpeakerDebug"

Expand Down Expand Up @@ -37,8 +38,8 @@ static void speaker_app_free(SpeakerDebugApp* app) {
free(app);
}

static void speaker_app_cli(Cli* cli, FuriString* args, void* context) {
UNUSED(cli);
static void speaker_app_cli(PipeSide* pipe, FuriString* args, void* context) {
UNUSED(pipe);

SpeakerDebugApp* app = (SpeakerDebugApp*)context;
SpeakerDebugAppMessage message;
Expand Down
9 changes: 5 additions & 4 deletions applications/debug/unit_tests/test_runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <cli/cli.h>
#include <toolbox/path.h>
#include <toolbox/pipe.h>
#include <loader/loader.h>
#include <storage/storage.h>
#include <notification/notification_messages.h>
Expand All @@ -25,7 +26,7 @@ struct TestRunner {
NotificationApp* notification;

// Temporary used things
Cli* cli;
PipeSide* pipe;
FuriString* args;

// ELF related stuff
Expand All @@ -38,14 +39,14 @@ struct TestRunner {
int minunit_status;
};

TestRunner* test_runner_alloc(Cli* cli, FuriString* args) {
TestRunner* test_runner_alloc(PipeSide* pipe, FuriString* args) {
TestRunner* instance = malloc(sizeof(TestRunner));

instance->storage = furi_record_open(RECORD_STORAGE);
instance->loader = furi_record_open(RECORD_LOADER);
instance->notification = furi_record_open(RECORD_NOTIFICATION);

instance->cli = cli;
instance->pipe = pipe;
instance->args = args;

instance->composite_resolver = composite_api_resolver_alloc();
Expand Down Expand Up @@ -147,7 +148,7 @@ static void test_runner_run_internal(TestRunner* instance) {
}

while(true) {
if(cli_cmd_interrupt_received(instance->cli)) {
if(cli_is_pipe_broken_or_is_etx_next_char(instance->pipe)) {
break;
}

Expand Down
8 changes: 4 additions & 4 deletions applications/debug/unit_tests/test_runner.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#pragma once

#include <furi.h>
#include <toolbox/pipe.h>

typedef struct TestRunner TestRunner;
typedef struct Cli Cli;

TestRunner* test_runner_alloc(Cli* cli, FuriString* args);
TestRunner* test_runner_alloc(PipeSide* pipe, FuriString* args);

void test_runner_free(TestRunner* isntance);
void test_runner_free(TestRunner* instance);

void test_runner_run(TestRunner* isntance);
void test_runner_run(TestRunner* instance);
5 changes: 0 additions & 5 deletions applications/debug/unit_tests/tests/storage/storage_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,6 @@ MU_TEST(test_storage_data_path) {
// check that appsdata folder exists
mu_check(storage_dir_exists(storage, APPS_DATA_PATH));

// check that cli folder exists
mu_check(storage_dir_exists(storage, APPSDATA_APP_PATH("cli")));

storage_simply_remove(storage, APPSDATA_APP_PATH("cli"));

furi_record_close(RECORD_STORAGE);
}

Expand Down
6 changes: 3 additions & 3 deletions applications/debug/unit_tests/unit_tests.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#include <furi.h>
#include <cli/cli.h>
#include <toolbox/pipe.h>

#include "test_runner.h"

void unit_tests_cli(Cli* cli, FuriString* args, void* context) {
UNUSED(cli);
void unit_tests_cli(PipeSide* pipe, FuriString* args, void* context) {
UNUSED(context);

TestRunner* test_runner = test_runner_alloc(cli, args);
TestRunner* test_runner = test_runner_alloc(pipe, args);
test_runner_run(test_runner);
test_runner_free(test_runner);
}
Expand Down
1 change: 1 addition & 0 deletions applications/main/application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ App(
name="On start hooks",
apptype=FlipperAppType.METAPACKAGE,
provides=[
"cli",
"ibutton_start",
"onewire_start",
"subghz_start",
Expand Down
24 changes: 12 additions & 12 deletions applications/main/gpio/usb_uart_bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,15 @@ static void usb_uart_on_irq_rx_dma_cb(
static void usb_uart_vcp_init(UsbUartBridge* usb_uart, uint8_t vcp_ch) {
furi_hal_usb_unlock();
if(vcp_ch == 0) {
Cli* cli = furi_record_open(RECORD_CLI);
cli_session_close(cli);
furi_record_close(RECORD_CLI);
CliVcp* cli_vcp = furi_record_open(RECORD_CLI_VCP);
cli_vcp_disable(cli_vcp);
furi_record_close(RECORD_CLI_VCP);
furi_check(furi_hal_usb_set_config(&usb_cdc_single, NULL) == true);
} else {
furi_check(furi_hal_usb_set_config(&usb_cdc_dual, NULL) == true);
Cli* cli = furi_record_open(RECORD_CLI);
cli_session_open(cli, &cli_vcp);
furi_record_close(RECORD_CLI);
CliVcp* cli_vcp = furi_record_open(RECORD_CLI_VCP);
cli_vcp_enable(cli_vcp);
furi_record_close(RECORD_CLI_VCP);
}
furi_hal_cdc_set_callbacks(vcp_ch, (CdcCallbacks*)&cdc_cb, usb_uart);
}
Expand All @@ -123,9 +123,9 @@ static void usb_uart_vcp_deinit(UsbUartBridge* usb_uart, uint8_t vcp_ch) {
UNUSED(usb_uart);
furi_hal_cdc_set_callbacks(vcp_ch, NULL, NULL);
if(vcp_ch != 0) {
Cli* cli = furi_record_open(RECORD_CLI);
cli_session_close(cli);
furi_record_close(RECORD_CLI);
CliVcp* cli_vcp = furi_record_open(RECORD_CLI_VCP);
cli_vcp_disable(cli_vcp);
furi_record_close(RECORD_CLI_VCP);
}
}

Expand Down Expand Up @@ -309,9 +309,9 @@ static int32_t usb_uart_worker(void* context) {

furi_hal_usb_unlock();
furi_check(furi_hal_usb_set_config(&usb_cdc_single, NULL) == true);
Cli* cli = furi_record_open(RECORD_CLI);
cli_session_open(cli, &cli_vcp);
furi_record_close(RECORD_CLI);
CliVcp* cli_vcp = furi_record_open(RECORD_CLI_VCP);
cli_vcp_enable(cli_vcp);
furi_record_close(RECORD_CLI_VCP);

return 0;
}
Expand Down
48 changes: 23 additions & 25 deletions applications/main/ibutton/ibutton_cli.c
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
#include <furi.h>
#include <furi_hal.h>

#include <cli/cli.h>
#include <cli/cli_commands.h>
#include <toolbox/args.h>
#include <toolbox/pipe.h>

#include <ibutton/ibutton_key.h>
#include <ibutton/ibutton_worker.h>
#include <ibutton/ibutton_protocols.h>

static void ibutton_cli(Cli* cli, FuriString* args, void* context);

// app cli function
void ibutton_on_system_start(void) {
#ifdef SRV_CLI
Cli* cli = furi_record_open(RECORD_CLI);
cli_add_command(cli, "ikey", CliCommandFlagDefault, ibutton_cli, cli);
furi_record_close(RECORD_CLI);
#else
UNUSED(ibutton_cli);
#endif
}

static void ibutton_cli_print_usage(void) {
printf("Usage:\r\n");
printf("ikey read\r\n");
Expand Down Expand Up @@ -92,7 +80,7 @@ static void ibutton_cli_worker_read_cb(void* context) {
furi_event_flag_set(event, EVENT_FLAG_IBUTTON_COMPLETE);
}

static void ibutton_cli_read(Cli* cli) {
static void ibutton_cli_read(PipeSide* pipe) {
iButtonProtocols* protocols = ibutton_protocols_alloc();
iButtonWorker* worker = ibutton_worker_alloc(protocols);
iButtonKey* key = ibutton_key_alloc(ibutton_protocols_get_max_data_size(protocols));
Expand All @@ -113,7 +101,7 @@ static void ibutton_cli_read(Cli* cli) {
break;
}

if(cli_cmd_interrupt_received(cli)) break;
if(cli_is_pipe_broken_or_is_etx_next_char(pipe)) break;
}

ibutton_worker_stop(worker);
Expand All @@ -138,7 +126,7 @@ static void ibutton_cli_worker_write_cb(void* context, iButtonWorkerWriteResult
furi_event_flag_set(write_context->event, EVENT_FLAG_IBUTTON_COMPLETE);
}

void ibutton_cli_write(Cli* cli, FuriString* args) {
void ibutton_cli_write(PipeSide* pipe, FuriString* args) {
iButtonProtocols* protocols = ibutton_protocols_alloc();
iButtonWorker* worker = ibutton_worker_alloc(protocols);
iButtonKey* key = ibutton_key_alloc(ibutton_protocols_get_max_data_size(protocols));
Expand Down Expand Up @@ -181,7 +169,7 @@ void ibutton_cli_write(Cli* cli, FuriString* args) {
}
}

if(cli_cmd_interrupt_received(cli)) break;
if(cli_is_pipe_broken_or_is_etx_next_char(pipe)) break;
}
} while(false);

Expand All @@ -195,7 +183,7 @@ void ibutton_cli_write(Cli* cli, FuriString* args) {
furi_event_flag_free(write_context.event);
}

void ibutton_cli_emulate(Cli* cli, FuriString* args) {
void ibutton_cli_emulate(PipeSide* pipe, FuriString* args) {
iButtonProtocols* protocols = ibutton_protocols_alloc();
iButtonWorker* worker = ibutton_worker_alloc(protocols);
iButtonKey* key = ibutton_key_alloc(ibutton_protocols_get_max_data_size(protocols));
Expand All @@ -214,7 +202,7 @@ void ibutton_cli_emulate(Cli* cli, FuriString* args) {

ibutton_worker_emulate_start(worker, key);

while(!cli_cmd_interrupt_received(cli)) {
while(!cli_is_pipe_broken_or_is_etx_next_char(pipe)) {
furi_delay_ms(100);
};

Expand All @@ -228,8 +216,8 @@ void ibutton_cli_emulate(Cli* cli, FuriString* args) {
ibutton_protocols_free(protocols);
}

void ibutton_cli(Cli* cli, FuriString* args, void* context) {
UNUSED(cli);
void ibutton_cli(PipeSide* pipe, FuriString* args, void* context) {
UNUSED(pipe);
UNUSED(context);
FuriString* cmd;
cmd = furi_string_alloc();
Expand All @@ -241,14 +229,24 @@ void ibutton_cli(Cli* cli, FuriString* args, void* context) {
}

if(furi_string_cmp_str(cmd, "read") == 0) {
ibutton_cli_read(cli);
ibutton_cli_read(pipe);
} else if(furi_string_cmp_str(cmd, "write") == 0) {
ibutton_cli_write(cli, args);
ibutton_cli_write(pipe, args);
} else if(furi_string_cmp_str(cmd, "emulate") == 0) {
ibutton_cli_emulate(cli, args);
ibutton_cli_emulate(pipe, args);
} else {
ibutton_cli_print_usage();
}

furi_string_free(cmd);
}

void ibutton_on_system_start(void) {
#ifdef SRV_CLI
Cli* cli = furi_record_open(RECORD_CLI);
cli_add_command(cli, "ikey", CliCommandFlagDefault, ibutton_cli, cli);
furi_record_close(RECORD_CLI);
#else
UNUSED(ibutton_cli);
#endif
}
Loading
Loading